All Downloads are FREE. Search and download functionalities are using the official Maven repository.

sim.portrayal.inspector.TimeSeriesChartingPropertyInspector Maven / Gradle / Ivy

Go to download

MASON is a fast discrete-event multiagent simulation library core in Java, designed to be the foundation for large custom-purpose Java simulations, and also to provide more than enough functionality for many lightweight simulation needs. MASON contains both a model library and an optional suite of visualization tools in 2D and 3D.

The newest version!
/*
  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.portrayal.inspector;
import java.awt.*;
import java.util.Iterator;
import sim.util.*;
import sim.display.*;
import sim.engine.*;
import sim.util.media.chart.*;
import org.jfree.data.xy.*;
import org.jfree.data.general.*;
import org.jfree.chart.plot.*;
import org.jfree.chart.*;

/** A property inspector which generates time series of data.  Time series are extended in real-time
    as requested by the user.  Data properties for which
    the TimeSeriesChartingPropertyInspector will operate include:
        
    
  • Any numerical value (byte, int, double, etc.)
  • Any sim.util.Valuable object
  • Any Number (Double, Integer, etc.)

TimeSeriesChartingPropertyInspector registers itself with the property menu option "Chart". */ public class TimeSeriesChartingPropertyInspector extends ChartingPropertyInspector { XYSeries chartSeries = null; XYSeries aggregateSeries = new XYSeries("ChartingPropertyInspector.temp", false); protected boolean validChartGenerator(ChartGenerator generator) { return generator instanceof TimeSeriesChartGenerator; } public static String name() { return "Chart"; } public static Class[] types() { return new Class[] { Number.class, Boolean.TYPE, Byte.TYPE, Short.TYPE, Integer.TYPE, Long.TYPE, Float.TYPE, Double.TYPE, Valuable.class }; } public TimeSeriesChartingPropertyInspector(Properties properties, int index, Frame parent, final GUIState simulation) { super(properties,index,parent,simulation); setupSeriesAttributes(properties, index); } public TimeSeriesChartingPropertyInspector(Properties properties, int index, final GUIState simulation, ChartGenerator generator) { super(properties, index, simulation, generator); setupSeriesAttributes(properties, index); } //I isolated this code from the constructor into this method because I have two constructors now. private void setupSeriesAttributes(Properties properties, int index) { if (isValidInspector()) { if (getGenerator().getNumSeriesAttributes() == 0) // recall that we've not been added yet { // take control getGenerator().setTitle("" + properties.getName(index) + " of " + properties.getObject()); ((XYChartGenerator)getGenerator()).setYAxisLabel("" + properties.getName(index)); ((XYChartGenerator)getGenerator()).setXAxisLabel("Time"); } chartSeries = new XYSeries( properties.getName(index), false ); // add our series seriesAttributes = ((TimeSeriesChartGenerator)generator).addSeries(chartSeries, new SeriesChangeListener() { public void seriesChanged(SeriesChangeEvent event) { getStopper().stop(); } }); } } protected ChartGenerator createNewGenerator() { return new TimeSeriesChartGenerator() { public void quit() { super.quit(); Stoppable stopper = getStopper(); if (stopper!=null) stopper.stop(); // remove the chart from the GUIState's charts getCharts(simulation).remove(this); } }; } protected double valueFor(Object o) { if (o instanceof java.lang.Number) // compiler complains unless I include the full classname!!! Huh? return ((Number)o).doubleValue(); else if (o instanceof Valuable) return ((Valuable)o).doubleValue(); else if (o instanceof Boolean) return ((Boolean)o).booleanValue() ? 1 : 0; else return Double.NaN; // unknown } void addToMainSeries(double x, double y, boolean notify) { chartSeries.add(x, y, false); TimeSeriesAttributes attributes = (TimeSeriesAttributes)(seriesAttributes); if (!attributes.possiblyCull()) { if (notify) // do a notification anyway chartSeries.fireSeriesChanged(); } } protected void updateSeries(double time, double lastTime) { double d = 0; GlobalAttributes globalAttributes = getGlobalAttributes(); // FIRST, load the aggregate series with the items aggregateSeries.add(time, d = valueFor(properties.getValue(index)), false); int len = aggregateSeries.getItemCount(); // SECOND, determine if it's time to dump stuff into the main series long interval = globalAttributes.interval; double intervalMark = time % interval; if (! // I think these are the three cases for when we may need to update because // we've exceeded the next interval (intervalMark == 0 || (time - lastTime >= interval) || lastTime % interval > intervalMark)) return; // not yet // THIRD determine how and when to dump stuff into the main series double y = 0; // make compiler happy double temp; switch(globalAttributes.aggregationMethod) { case AGGREGATIONMETHOD_CURRENT: // in this case the aggregateSeries is sort of worthless addToMainSeries(time, d, false); break; case AGGREGATIONMETHOD_MAX: double maxX = 0; for(int i=0;i temp || i==0) minX = temp; } addToMainSeries( minX, y, false ); break; case AGGREGATIONMETHOD_MEAN: double sumX = 0; int n = 0; for(int i=0;i





© 2015 - 2025 Weber Informatics LLC | Privacy Policy