sim.util.media.chart.TimeSeriesChartGenerator.java Source code

Java tutorial

Introduction

Here is the source code for 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 sim.util.media.chart;

import java.awt.*;
import java.util.*;
import java.awt.event.*;
import javax.swing.*;

import sim.util.gui.*;

// From JFreeChart
import org.jfree.data.xy.*;
import org.jfree.chart.*;
import org.jfree.chart.plot.*;
import org.jfree.chart.renderer.xy.*;
import org.jfree.data.general.*;

// from iText (www.lowagie.com/iText/)
import com.lowagie.text.*;
import com.lowagie.text.pdf.*;

/*  // 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;
                }
            }
        });
    }
}