sim.util.media.chart.TimeSeriesAttributes Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of mason Show documentation
Show all versions of mason Show documentation
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.util.media.chart;
import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;
import java.awt.event.*;
import java.util.*;
import sim.util.gui.*;
import sim.util.*;
// From JFreeChart
import org.jfree.data.xy.*;
import org.jfree.chart.*;
import org.jfree.chart.event.*;
import org.jfree.chart.plot.*;
import org.jfree.data.general.*;
import org.jfree.chart.renderer.xy.*;
import org.jfree.data.general.*;
/** A SeriesAttributes used for user control pf time series created with TimeSeriesCharGenerator.
This is done largely through the
manipulation of XYSeries objects and features of the XYPlot class. */
public class TimeSeriesAttributes extends SeriesAttributes
{
/** A dash */
static final float DASH = 6;
/** A dot */
static final float DOT = 1;
/** A short space */
static final float SPACE = 3;
/** A long space */
static final float SKIP = DASH;
public static final int PATTERN_SOLID = 0;
public static final int PATTERN_LONG_DASH = 1;
public static final int PATTERN_STRETCH_DASH = 2;
public static final int PATTERN_DASH = 3;
public static final int PATTERN_DASH_DASH_DOT = 4;
public static final int PATTERN_DASH_DOT = 5;
public static final int PATTERN_DASH_DOT_DOT = 6;
public static final int PATTERN_DOT = 7;
public static final int PATTERN_STRETCH_DOT = 8;
/** Nine dash combinations that the user might find helpful. */
static final float[][] dashPatterns =
{
{ DASH, 0.0f }, // --------
{ DASH * 2, SKIP }, // -- -- --
{ DASH, SKIP } , // - - -
{ DASH, SPACE } , // - - - -
{ DASH, SPACE, DASH, SPACE, DOT, SPACE }, // - - . - - .
{ DASH, SPACE, DOT, SPACE, }, // - . - .
{ DASH, SPACE, DOT, SPACE, DOT, SPACE }, // - . . - . .
{ DOT, SPACE }, // . . . .
{ DOT, SKIP } // . . . .
};
/** How much we should stretch the dashPatterns listed above. 1.0 is normal. */
float stretch;
NumberTextField stretchField;
/** Line thickness. */
float thickness;
NumberTextField thicknessField;
/** Line dash pattern (one of the dashPatterns above). */
int dashPattern;
JComboBox dashPatternList;
/** Line color. */
Color strokeColor;
ColorWell strokeColorWell;
public void setThickness(double value) { thicknessField.setValue(thicknessField.newValue(value)); }
public double getThickness() { return (double)(thicknessField.getValue()); }
public void setStretch(double value) { stretchField.setValue(stretchField.newValue(value)); }
public double getStretch() { return (double)(stretchField.getValue()); }
public void setDashPattern(int value)
{
if (value >= 0 && value < dashPatterns.length)
{
dashPatternList.setSelectedIndex(value);
dashPattern = value;
}
}
public int getDashPattern() { return dashPatternList.getSelectedIndex(); }
public void setStrokeColor(Color value) { strokeColorWell.setColor(strokeColor = value);}
public Color getStrokeColor() { return strokeColor; }
/** The time series in question. */
XYSeries series;
public XYSeries getSeries() { return series; }
/** Clears the existing internal XYSeries, then adds all the series elements in the provided XYSeries to the
internal XYSeries. Does not notify the chart to update.
*/
public void setSeries(XYSeries series)
{
this.series.clear();
int count = series.getItemCount();
for(int i = 0; i < count; i++)
this.series.add(series.getDataItem(i), true);
}
public void setSeriesName(String val) { series.setKey(new ChartGenerator.UniqueString(val)); } // bypasses super.setSeriesName
public String getSeriesName() { return "" + series.getKey(); } // bypasses super.getSeriesName
public void clear() { series.clear(); }
/** Builds a TimeSeriesAttributes with the given generator, series, and index for the series. */
public TimeSeriesAttributes(ChartGenerator generator, XYSeries series, int index, SeriesChangeListener stoppable)
{
super(generator, "" + series.getKey(), index, stoppable);
this.series = series;
}
public void rebuildGraphicsDefinitions()
{
float[] newDashPattern = new float[dashPatterns[dashPattern].length];
for(int x=0;x 0)
newDashPattern[x] = dashPatterns[dashPattern][x] * stretch * thickness; // include thickness so we dont' get overlaps -- will this confuse users?
XYItemRenderer renderer = (XYItemRenderer)(((XYPlot)getPlot()).getRenderer());
// we do two different BasicStroke options here because recent versions of Java (for example, 1.6.0_35_b10-428-11M3811 on Retina Displays)
// break when defining solid strokes as { X, 0.0 } even though that's perfecty cromulent. So instead we hack it so that the "solid" stroke
// is done using a different constructor.
renderer.setSeriesStroke(getSeriesIndex(),
((dashPattern == 0) ? // solid
new BasicStroke(thickness, BasicStroke.CAP_ROUND,
BasicStroke.JOIN_ROUND, 0) :
new BasicStroke(thickness, BasicStroke.CAP_ROUND,
BasicStroke.JOIN_ROUND,0,newDashPattern,0)));
renderer.setSeriesPaint(getSeriesIndex(),strokeColor);
repaint();
}
public void buildAttributes()
{
// The following three variables aren't defined until AFTER construction if
// you just define them above. So we define them below here instead.
dashPattern = 0; // dashPatterns[0];
stretch = 1.0f;
thickness = 2.0f;
// strokeColor = Color.black; // rebuildGraphicsDefinitions will get called by our caller afterwards
XYItemRenderer renderer = (((XYPlot)getPlot()).getRenderer());
// NOTE:
// Paint paint = renderer.getSeriesPaint(getSeriesIndex());
// In JFreeChart 1.0.6 getSeriesPaint returns null!!!
// You need lookupSeriesPaint(), but that's not backward compatible.
// The only thing consistent in all versions is getItemPaint
// (which looks like a gross miss-use, but gets the job done)
Paint paint = renderer.getItemPaint(getSeriesIndex(), -1);
strokeColor = (Color)paint;
strokeColorWell = new ColorWell(strokeColor)
{
public Color changeColor(Color c)
{
strokeColor = c;
rebuildGraphicsDefinitions();
return c;
}
};
addLabelled("Color",strokeColorWell);
thicknessField = new NumberTextField(2.0,true)
{
public double newValue(double newValue)
{
if (newValue < 0.0)
newValue = currentValue;
thickness = (float)newValue;
rebuildGraphicsDefinitions();
return newValue;
}
};
addLabelled("Width",thicknessField);
dashPatternList = new JComboBox();
dashPatternList.setEditable(false);
dashPatternList.setModel(new DefaultComboBoxModel(new java.util.Vector(Arrays.asList(
new String[] { "Solid", "__ __ __", "_ _ _ _", "_ _ _ _ _", "_ _ . _ _ .",
"_ . _ . _ .", "_ . . _ . .", ". . . . . . .", ". . . . ." }))));
dashPatternList.setSelectedIndex(0);
dashPatternList.addActionListener(new ActionListener()
{
public void actionPerformed ( ActionEvent e )
{
dashPattern = dashPatternList.getSelectedIndex(); // dashPatterns[dashPatternList.getSelectedIndex()];
rebuildGraphicsDefinitions();
}
});
addLabelled("Dash",dashPatternList);
stretchField = new NumberTextField(1.0,true)
{
public double newValue(double newValue)
{
if (newValue < 0.0)
newValue = currentValue;
stretch = (float)newValue;
rebuildGraphicsDefinitions();
return newValue;
}
};
addLabelled("Stretch",stretchField);
}
public boolean possiblyCull()
{
DataCuller dataCuller = ((TimeSeriesChartGenerator)generator).getDataCuller();
if(dataCuller!=null && dataCuller.tooManyPoints(series.getItemCount()))
{
deleteItems(dataCuller.cull(getXValues(), true));
return true;
}
else
return false;
}
void deleteItems(IntBag items)
{
Bag tmpBag = new Bag();
if(items.numObjs==0)
return;
int currentTabooIndex = 0;
int currentTaboo = items.objs[0];
Iterator iter = series.getItems().iterator();
int index=0;
while(iter.hasNext())
{
Object o = iter.next();
if(index==currentTaboo)
{
//skip the copy, let's move on to next taboo index
if(currentTabooIndex
© 2015 - 2025 Weber Informatics LLC | Privacy Policy