edu.gmu.cs.sim.util.media.chart.TimeSeriesChartGenerator.java Source code

Java tutorial

Introduction

Here is the source code for edu.gmu.cs.sim.util.media.chart.TimeSeriesChartGenerator.java

Source

/*
  Copyright 2006 by Sean Luke and George Mason University
  Licensed under the Academic Free License version 3.0
  See the file "LICENSE" for more information
*/

package edu.gmu.cs.sim.util.media.chart;

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

import edu.gmu.cs.sim.util.gui.DisclosurePanel;
import edu.gmu.cs.sim.util.gui.LabelledList;
import edu.gmu.cs.sim.util.gui.NumberTextField;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.general.SeriesChangeListener;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;

// From JFreeChart
// from iText (www.lowagie.com/iText/)

/*  // looks like we'll have to move to these soon
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
*/

/**
 TimeSeriesChartGenerator is a ChartGenerator which displays a time-series chart using the JFreeChart library.
 The generator uses the XYSeriesCollection as its dataset, and thus holds some N XYSeriesDataset objects, each
 representing a time series displayed on the chart.  You add series to the generator with the <tt>addSeries</tt>
 method.
    
 <p>TimeSeriesChartGenerator creates attributes components in the form of TimeSeriesAttributes, which work with
 the generator to properly update the chart to reflect changes the user has made to its display.
 */

public class TimeSeriesChartGenerator extends XYChartGenerator {
    public void clearAllSeries() {
        SeriesAttributes[] c = getSeriesAttributes();
        for (int i = 0; i < c.length; i++) {
            ((TimeSeriesAttributes) (c[i])).clear();
        }
    }

    public void removeSeries(int index) {
        super.removeSeries(index);
        XYSeriesCollection xysc = (XYSeriesCollection) getSeriesDataset();
        xysc.removeSeries(index);
    }

    public void moveSeries(int index, boolean up) {
        super.moveSeries(index, up);

        if ((index > 0 && up) || (index < getSeriesCount() - 1 && !up)) // it's not the first or the last given the move
        {
            XYSeriesCollection xysc = (XYSeriesCollection) getSeriesDataset();
            // this requires removing everything from the dataset and resinserting, duh
            ArrayList items = new ArrayList(xysc.getSeries());
            xysc.removeAllSeries();

            int delta = up ? -1 : 1;
            // now rearrange
            items.add(index + delta, items.remove(index));

            // rebuild the dataset
            for (int i = 0; i < items.size(); i++) {
                xysc.addSeries(((XYSeries) (items.get(i))));
            }
        }
    }

    /** Adds a series, plus a (possibly null) SeriesChangeListener which will receive a <i>single</i>
     event if/when the series is deleted from the chart by the user.  The series should have a key
     in the form of a String.  Returns the series attributes. */
    public SeriesAttributes addSeries(final XYSeries series, final SeriesChangeListener stopper) {
        XYSeriesCollection xysc = (XYSeriesCollection) getSeriesDataset();

        int i = xysc.getSeriesCount();
        series.setKey(new ChartGenerator.UniqueString(series.getKey()));
        xysc.addSeries(series);
        TimeSeriesAttributes csa = new TimeSeriesAttributes(this, series, i, stopper);
        seriesAttributes.add(csa);
        revalidate();
        return csa;
    }

    protected void buildChart() {
        XYSeriesCollection collection = new XYSeriesCollection();

        chart = ChartFactory.createXYLineChart("Untitled Chart", "Untitled X Axis", "Untitled Y Axis", collection,
                PlotOrientation.VERTICAL, false, true, false);
        ((XYLineAndShapeRenderer) (((XYPlot) (chart.getPlot())).getRenderer())).setDrawSeriesLineAsPath(true);

        chart.setAntiAlias(true);
        //chartPanel = new ScrollableChartPanel(chart, true); 
        chartPanel = buildChartPanel(chart);
        setChartPanel(chartPanel);
        //        chartHolder.getViewport().setView(chartPanel);

        // this must come last because the chart must exist for us to set its dataset
        setSeriesDataset(collection);
    }

    JCheckBox useCullingCheckBox;
    NumberTextField maxPointsPerSeriesTextField;
    DataCuller dataCuller;

    public DataCuller getDataCuller() {
        return dataCuller;
    }

    public void setDataCuller(DataCuller dataCuller) {
        this.dataCuller = dataCuller;
    }

    public TimeSeriesChartGenerator() {
        super();
        LabelledList globalAttribList = (LabelledList) (((DisclosurePanel) getGlobalAttribute(-2))
                .getDisclosedComponent());
        useCullingCheckBox = new JCheckBox();

        globalAttribList.add(new JLabel("Cull Data"), useCullingCheckBox);
        maxPointsPerSeriesTextField = new NumberTextField(1000) {
            public double newValue(final double val) {
                int max = (int) val;
                if (val < 2) {
                    return (int) getValue();
                }
                dataCuller = new MinGapDataCuller(max);
                return max;
            }
        };
        useCullingCheckBox.setSelected(true);
        globalAttribList.add(new JLabel("... Over"), maxPointsPerSeriesTextField);
        maxPointsPerSeriesTextField.setToolTipText(
                "The maximum number of data points in a series before data culling gets triggered.");

        dataCuller = new MinGapDataCuller((int) maxPointsPerSeriesTextField.getValue());

        useCullingCheckBox.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                if (useCullingCheckBox.isSelected()) {
                    maxPointsPerSeriesTextField.setEnabled(true);
                    int maxPoints = (int) maxPointsPerSeriesTextField.getValue();
                    dataCuller = new MinGapDataCuller(maxPoints);
                } else {
                    maxPointsPerSeriesTextField.setEnabled(false);
                    dataCuller = null;
                }
            }
        });
    }
}