net.sourceforge.jabm.view.TimeSeriesChart.java Source code

Java tutorial

Introduction

Here is the source code for net.sourceforge.jabm.view.TimeSeriesChart.java

Source

/*
 * JABM - Java Agent-Based Modeling Toolkit
 * Copyright (C) 2013 Steve Phelps
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 3 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 */
package net.sourceforge.jabm.view;

import java.awt.Dimension;
import java.awt.HeadlessException;
import java.io.Serializable;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.Map;

import javax.swing.JComponent;
import javax.swing.SwingUtilities;

import net.sourceforge.jabm.event.ReportVariablesChangedEvent;
import net.sourceforge.jabm.event.SimEvent;
import net.sourceforge.jabm.report.ReportWithGUI;
import net.sourceforge.jabm.report.Timeseries;

import org.apache.log4j.Logger;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.data.DomainOrder;
import org.jfree.data.general.Dataset;
import org.jfree.data.general.DatasetChangeEvent;
import org.jfree.data.general.DatasetChangeListener;
import org.jfree.data.general.DatasetGroup;
import org.jfree.data.xy.XYDataset;
import org.springframework.beans.factory.InitializingBean;

/**
 * A graphical report that renders an underlying time series ({@link Timeseries}
 * ) as a JFreeChart time series chart.  This report listens for events from
 * the underlying Timeseries object and notifies its chart whenever the series
 * is updated.
 * 
 * @author Steve Phelps
 */
public class TimeSeriesChart implements XYDataset, ReportWithGUI, Serializable, InitializingBean {

    /**
     * The underlying time series which is the model for our chart.
     */
    protected Timeseries series;

    protected Map<Object, Number> variableBindings = new LinkedHashMap<Object, Number>();

    protected LinkedList<Object> variableNames = new LinkedList<Object>();

    protected LinkedList<DatasetChangeListener> listeners = new LinkedList<DatasetChangeListener>();

    protected String chartTitle;

    protected String rangeAxisLabel = "";

    /**
     * The JFreeChart ChartPanel which contains the actual swing component
     * for the chart.
     */
    protected ChartPanel chartPanel;

    static Logger logger = Logger.getLogger(TimeSeriesChart.class);

    public TimeSeriesChart() throws HeadlessException {
        super();
    }

    @Override
    public void afterPropertiesSet() {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                initialiseGUI();
            }
        });
    }

    public void initialiseGUI() {
        String name = chartTitle;
        if (name == null) {
            name = series.getName();
        }
        computeVariableNames();
        // series.initialise(null);
        JFreeChart chart = ChartFactory.createTimeSeriesChart(name, // chart
                // title
                "t", // domain axis label
                rangeAxisLabel, // range axis label
                this, // data
                true, // include legend
                true, // tooltips?
                false // URLs?
        );
        chartPanel = new ChartPanel(chart, true);
        chartPanel.setPreferredSize(new Dimension(500, 270));
        computeVariableNames();
        series.addListener(this);
    }

    public Map<Object, Number> getVariableBindings() {
        return series.getVariableBindings();
    }

    public void computeVariableNames() {
        this.variableNames = new LinkedList<Object>(series.getyVariableNames());
    }

    /**
     * When this report is computed it notifies its listeners (typically
     * the JFreeChart swing component) that its data set has changed.
     */
    public void compute(ReportVariablesChangedEvent event) {
        final Dataset eventOriginator = this;
        for (DatasetChangeListener listener : listeners) {
            listener.datasetChanged(new DatasetChangeEvent(eventOriginator, eventOriginator));
        }
    }

    public void dispose(SimEvent event) {
        series.dispose(event);
    }

    public void initialise(SimEvent event) {
        series.initialise(event);
    }

    public int getSeriesCount() {
        int n = series.getNumberOfSeries();
        return n;
    }

    @SuppressWarnings("rawtypes")
    public Comparable getSeriesKey(int seriesIndex) {
        // if (variableNames.size() == 0) {
        // //TODO
        // return "";
        // }
        String result = this.variableNames.get(seriesIndex).toString();
        return result;
    }

    @SuppressWarnings("rawtypes")
    public int indexOf(Comparable seriesKey) {
        int result = variableNames.indexOf(seriesKey);
        return result;
    }

    public DatasetGroup getGroup() {
        // TODO Auto-generated method stub
        return null;
    }

    public void addChangeListener(DatasetChangeListener arg0) {
        listeners.add(arg0);
    }

    public void removeChangeListener(DatasetChangeListener arg0) {
        listeners.remove(arg0);
    }

    public void setGroup(DatasetGroup arg0) {
    }

    public DomainOrder getDomainOrder() {
        return null;
    }

    public int getItemCount(int seriesIndex) {
        int result = series.size(seriesIndex);
        return result;
    }

    public Number getX(int seriesIndex, int itemIndex) {
        return series.getX(seriesIndex, itemIndex);
    }

    public double getXValue(int seriesIndex, int itemIndex) {
        double result = getX(seriesIndex, itemIndex).doubleValue();
        return result;
    }

    public Number getY(int seriesIndex, int itemIndex) {
        return series.getY(seriesIndex, itemIndex);
    }

    public double getYValue(int seriesIndex, int itemIndex) {
        return getY(seriesIndex, itemIndex).doubleValue();
    }

    public void eventOccurred(SimEvent event) {
        // series.eventOccurred(event);
        if (event instanceof ReportVariablesChangedEvent) {
            compute((ReportVariablesChangedEvent) event);
        }
    }

    public Timeseries getSeries() {
        return series;
    }

    public void setSeries(Timeseries series) {
        this.series = series;
    }

    public String getChartTitle() {
        return chartTitle;
    }

    public void setChartTitle(String chartTitle) {
        this.chartTitle = chartTitle;
    }

    public String getRangeAxisLabel() {
        return rangeAxisLabel;
    }

    public void setRangeAxisLabel(String rangeAxisLabel) {
        this.rangeAxisLabel = rangeAxisLabel;
    }

    @Override
    public String getName() {
        return chartTitle;
    }

    @Override
    public JComponent getComponent() {
        return chartPanel;
    }

}