Hi all,
I have a problem and cannot figure this one out!
Does anyone have an example available using a dynamic plot similar to the
following code?
I am plotting 2 different object events occuring at different times but it
is not getting properly plotted, the second object start time is set to the
beginning time after a while.
Any idea why?
Has long as I draw only on plot I am fine, when the second plot gets drawn
things get crazy!
Thanks for your help.
Eric
//////////////////////////////////////////////////////////////////////////
/**
* This is a dynamic XY Chart used to display the Concentration of
* Detected Effluent for finder1 and finder2.
*
*/
package xyplotview;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
import sim.*;
import view.*;
import execcontrol.*;
import jclass.chart.JCChartComponent;
import jclass.chart.ChartDataView;
import jclass.chart.FileDataSource;
import jclass.chart.Chartable;
import jclass.chart.ChartDataModelUpdate;
import jclass.chart.JCLegend;
import jclass.chart.*;
import jclass.base.Border;
public class XYPlotView extends JPanel implements View
{
private final static int[] REGISTEREVNTS = {GraphicsStream.XY,
GraphicsStream.XYDATA}; //25, 54
public JCChartComponent chart; /** The chart
object */
private JCLegend xLabel,yLabel; /** Labels for
the chart */
private int chartId = 1; /** The
ViewEvent chart identifier for this class */
private ChartDataSource xytd = new ChartDataSource(); /** The
updating data source */
private Scenario scenario; /** Scenario
in which the view is running */
private Frame frame;
private view.GraphicModel gm;
private Vector state;
private ProbeBroker pb;
private Vector dataRequestVector;
private boolean first = true;
private int index = 0;
private int index2 = 0;
private double lastTime = 0.0;
/** Number of events occurring at the same time */
private int nSameTime = 0;
private ViewEvent lastEvent=null;
/** Time of last update actually drawn to chart */
private double lastDrawTime = 0;
private double lastEventTime = 0;
/** size of buffer in seconds. ViewEvents within tbuffer of the first
buffered event will be buffered. */
private double tbuffer = 500.0; // seconds
/** Public Constructor */
public XYPlotView()
{
super();
}
// Implement Interface View Methods
public void addViewListener(ViewListener vl){}
public void removeViewListener(ViewListener vl){}
public void fireViewEvent(ViewEvent e){}
public void setState(Vector state){}
public Vector saveState() { return state; }
public int[] evntRegister() {return REGISTEREVNTS;}
public synchronized void deleteView() {}
public void init(Frame f, GraphicModel gm, Scenario s, boolean editMode)
throws ViewInitFailException {}
public void init(Frame f, GraphicModel gm, Vector state, ProbeBroker pb)
throws ViewInitFailException
{
init(f, gm, state, false);
this.pb = pb;
// Get the dat file for this view
String dataRequestfilename =
(String)StateParser.getStateObject(state,"datarequestfile");
System.out.println("BettyChart: Retrieving DataRequests: " +
dataRequestfilename);
try
{
DataRequestReader drr = new DataRequestReader(gm.getScenario(),
Scenario.DATA_DIR + dataRequestfilename);
dataRequestVector = drr.getDataRequests();
for(int i = 0; i < dataRequestVector.size(); i++)
{
DataRequest dr = (DataRequest)dataRequestVector.elementAt(i);
dr.setRequestor(this);
pb.requestData(dr);
}
}
catch (java.io.IOException e) // No data requests (they will need to
be created with the gui)
{
System.out.println("XYPlotView: No DataRequests.");
}
}
public void init()
{
setLayout(new BorderLayout());
// Create the chart component
chart = new JCChartComponent();
chart.setDataView1ChartType(JCChartComponent.PLOT);
// Set Colors
Color lightGray = new Color(0xC0,0xC0,0xC0);
Color steelBlue = new Color(0x3D,0x71,0x9C);
Color darkSteelBlue = new Color(0x33,0x5e,0x82);
// Set Background and header colors
setBackground(lightGray);
chart.setBackground(lightGray);
chart.getHeader().setBackground(steelBlue);
chart.getHeader().setForeground(Color.white);
chart.getChartArea().setBackground(steelBlue);
chart.getChartArea().getPlotArea().setBackground(darkSteelBlue);
chart.getChartArea().setForeground(Color.white);
// Set Borders
chart.getChartArea().setBorderType(Border.OUT);
chart.getChartArea().setBorderWidth(2);
chart.getChartArea().setAxisBoundingBox(true);
chart.getHeader().setBorderType(Border.OUT);
chart.getHeader().setBorderWidth(2);
// Set the legend anchor and orientation
chart.getLegend().setIsShowing(true);
chart.setLegendAnchor( JCLegend.SOUTH);
chart.setLegendOrientation(JCLegend.HORIZONTAL);
// Set the axis titles
chart.setX1AxisTitleText("Time (sec)");
chart.setX1AxisTitleIsShowing(true);
chart.setY1AxisTitleText("Concentration (ppb)");
chart.setY1AxisTitleIsShowing(true);
chart.setY1AxisTitlePlacement( JCLegend.NORTHWEST );
chart.getDataView(0).setDataSource(xytd);
chart.setLineColorIndex( 0 );
chart.setSymbolColorIndex( 0 );
chart.setFastAction(true);
add("Center", chart);
}
public void update(Vector v)
{
for(int i = 0; i < v.size(); i++)
{
update((ViewEvent)v.elementAt(i));
}
}
public void update(ViewEvent evnt)
{
switch (evnt.type)
{
case ViewEvent.XYDATA:
// Set the min for the Xaxis when receiving the first event
if ( lastDrawTime == 0.0 && first ) {
first = false;
int min = (((int)Math.round(new
Double(evnt.time).doubleValue())));
String Min = Integer.toString(min);
chart.setX1AxisMin(Min);
chart.setX1AxisMinIsDefault(false);
}
if(lastEventTime != evnt.time) {
if (evnt.time < lastDrawTime + tbuffer) {
xytd.updateData(evnt);
}
else {
// draw the current plus all previously buffered events
xytd.updateData(evnt);
//xytd.redrawGraph();
lastDrawTime = evnt.time;
}
lastEventTime= evnt.time;
}
break;
} /* End of switch */
}
private final static Color[] COLORS = {Color.blue, Color.green,
Color.magenta, Color.yellow, Color.red};
public void reset() {
//xytd.reset();
}
public void init(Frame f, GraphicModel gm, Vector state, boolean
editMode) throws ViewInitFailException {
// Initialize the chart
init();
// Initializes the View.
this.state = state;
try {
// Set the scenario and model.
this.scenario = gm.getScenario();
this.frame = f;
// Get and set bounds for frame
int[] bounds = (int[])StateParser.getStateObject(state,
"geometry");
frame.setBounds(bounds[0],bounds[1],bounds[2],bounds[3]);
frame.setResizable(true);
// Get and set frame title
String title = (String)StateParser.getStateObject(state, "title");
if (title != null) {
frame.setTitle(title);
}
}
catch (Exception e) {
throw new ViewInitFailException((View)this, null, e.getMessage());
}
}
public void showDataReqDialog()
{
String dataRequestfilename =
(String)StateParser.getStateObject(state,"datarequestfile");
(new DlgDataRequestList(frame, scenario, dataRequestVector, pb,
this, Scenario.DATA_DIR + dataRequestfilename)).show();
}
}
//////////////////////////////////////////////////////////////////////////
/**
* This is the dynamic data source
*/
class ChartDataSource extends Observable implements Chartable
{
/** Look-up table mapping eid/pid to Vector position */
private Hashtable hashIndexToVector = new Hashtable();
/** List of x-values. Use hashVals to determine position in the Vector
*/
private Vector xData = new Vector();
/** List of y-values for finder1. Use hashVals to determine position in
the Vector */
private Vector yData = new Vector();
/** List of x-values for finder2. Use hashVals to determine position in
the Vector */
private Vector xData2 = new Vector();
/** List of y-values for finder2. Use hashVals to determine position in
the Vector */
private Vector yData2 = new Vector();
/** Boolean used for finder type */
private boolean finder = true;
private boolean found1 = false;
private boolean found2 = false;
// number of points
//private int nPoints = 4;
// point labels
private String[] pointLabels = new String[4];
// constructor
public ChartDataSource()
{
setChanged();
notifyObservers(new
ChartDataModelUpdate(ChartDataModelUpdate.RESET,0,1));
xData.addElement( new Double(0.0) );
setChanged();
notifyObservers(new
ChartDataModelUpdate(ChartDataModelUpdate.RESET,0,1));
yData.addElement( new Double(0.0) );
setChanged();
notifyObservers(new
ChartDataModelUpdate(ChartDataModelUpdate.RESET,0,1));
xData2.addElement( new Double(0.0) );
setChanged();
notifyObservers(new
ChartDataModelUpdate(ChartDataModelUpdate.RESET,0,1));
yData2.addElement(new Double(0.0) );
}
/***************************************************************************
* The Element Identifier (eid) and Primitive Identifier (pid) uniquely
specify
* each point on the chart. The index for looking up an x,y pair is
returned by
* this method.
*/
public Long computeIndex( int eid, int pid ) {
return new Long( (eid*10000) + pid );
}
public void redrawGraph() {
// Notify the chart to redraw
System.out.println("redraw
graph.........................................");
//if(finder) {
setChanged();
notifyObservers( new
ChartDataModelUpdate(ChartDataModelUpdate.RESET,0,xData.size()));
setChanged();
notifyObservers( new
ChartDataModelUpdate(ChartDataModelUpdate.CHANGE_ROW,1,yData.size()) );
//} else {
/*setChanged();
notifyObservers( new
ChartDataModelUpdate(ChartDataModelUpdate.RESET,0,xData2.size()) );
setChanged();
notifyObservers( new
ChartDataModelUpdate(ChartDataModelUpdate.CHANGE_ROW,2,yData2.size()) );
//}*/
System.out.println("Exit redraw graph..........xData.size(): " +
xData.size() + " xData2.size() " + xData2.size());
}
/***************************************************************************
* This method determines whether a new point is to be added, or an
existing
* point is to be edited.
*
* @param evt The ViewEvent holding the affected data point
*/
public void updateData( ViewEvent evt ) {
// Hard-coded reject the origin data point
if ( ( evt.x == evt.y ) && ( evt.x == 0.0 ) ) {
return;
}
addNewPoint( evt );
}
/***************************************************************************
* This method adds a new data point by:
* - Computing the hash index from Element id and Primitive id
* - Adding the x,y values to the Vectors
* - Notifying the chart of the new point
*
* @param evt The ViewEvent holding the new point to be added
*/
public void addNewPoint( ViewEvent evt ) {
// Compute new index based on eid/pid
ElementGraphicModel egm = null;
try
{
egm = (ElementGraphicModel)evt.element;
}
catch(ClassCastException cce) { return; }
Element elem = egm.getElement();
//Long index = computeIndex( elem.id, evt.pid );
Integer pos = null;
Integer pos2 = null;
int x0 =0;
int x1 = 0;
int beginTime = 0;
int beginTime2 = 0;
int incr = 0;
double y0 = 0.0;
double y1 = 0.0;
//System.out.println("pos: " + pos + " pos2: " + pos2 + " Index: " +
index);
//hashIndexToVector.put( index, pos );
// Lets find out which finder it is first.
if(elem.name.equals("finder1")){
if(found1 == false) {
beginTime = (int)Math.round(new Double(evt.x).doubleValue()
);
found1 = true;
}
finder =true;
Long index = computeIndex( elem.id, evt.pid );
// Get the next open position in the Vector
pos = new Integer( xData.size() );
// Add to the hash table
hashIndexToVector.put( index, pos );
x0 = (int)Math.round(new Double(evt.x).doubleValue() );
y0 = new Float(evt.y).floatValue();
} else {
finder=false;
// Get the next open position in the Vector
pos2 = new Integer( xData2.size() );
Long index2 = computeIndex( elem.id, evt.pid);
// Add to the hash table
hashIndexToVector.put( index2, pos2 );
x1 = (int)Math.round(new Double(evt.x).doubleValue() );
y1 = new Float(evt.y).floatValue();
}
// Add the data element to the end of the vector list
//int x0 = (int)Math.round(new Double(evt.x).doubleValue() );
//float y0 = new Double(evt.y).floatValue();
System.out.println("Finder name: " + evt.name + " pos: " + pos + "
pos2 " + pos2 +" X0 " + x0 + " Y0 " + y0);
if(finder) {
xData.addElement( new Double(x0) );
yData.addElement( new Double(y0) );
setChanged();
notifyObservers( new
ChartDataModelUpdate(ChartDataModelUpdate.CHANGE_ROW,0,xData.size()) );
setChanged();
notifyObservers( new
ChartDataModelUpdate(ChartDataModelUpdate.ADD_VALUE,0,pos.intValue()));
setChanged();
notifyObservers( new
ChartDataModelUpdate(ChartDataModelUpdate.CHANGE_ROW,1,yData.size()) );
setChanged();
notifyObservers( new
ChartDataModelUpdate(ChartDataModelUpdate.ADD_VALUE,1,pos.intValue() ));
} else {
xData2.addElement( new Double(x1));
yData2.addElement( new Double(y1));
// Notify the chart to redraw the appropriate points
setChanged();
notifyObservers( new
ChartDataModelUpdate(ChartDataModelUpdate.CHANGE_ROW,0,xData2.size()) );
setChanged();
notifyObservers( new
ChartDataModelUpdate(ChartDataModelUpdate.ADD_VALUE,0,pos2.intValue()));
setChanged();
notifyObservers( new
ChartDataModelUpdate(ChartDataModelUpdate.CHANGE_ROW,2,yData2.size()) );
setChanged();
notifyObservers( new
ChartDataModelUpdate(ChartDataModelUpdate.ADD_VALUE,2,pos2.intValue() ));
}
//System.out.println("Adding a new point: xData.size(): " +
xData.size() + " xData2.size() " + xData2.size() + " yData.size(): " +
yData.size() + " yData2.size() " + yData2.size() );
}
/***************************************************************************
* This method empties all buffers and causes the chart to clear all
points
*/
public void reset() {
hashIndexToVector.clear();
xData.removeAllElements();
yData.removeAllElements();
xData2.removeAllElements();
yData2.removeAllElements();
setChanged();
notifyObservers(new
ChartDataModelUpdate(ChartDataModelUpdate.RESET,0,1));
}
// methods needed for the Chartable interface
public int getDataInterpretation()
{
return ARRAY;
}
/***************************************************************************
* Method to retrieve the data element at the specified row (x-value)
and column (y-value)
*
* @param row Specifies the position at which the x-value occurs
* @param column Specifies the position at which the y-value occurs
* @return Object Returns the java.lang.Object at the specified
coordinates. Returns null
* if the row/column are invalid
*/
public java.lang.Object getDataItem(int row,int column)
{ System.out.println("get DataItem ROW: " + row + "Finder is: " +
finder + " col " + column);
switch(row)
{
case 0:
if(finder) {
return xData.elementAt(column);
} else {
return xData2.elementAt(column);
}
case 1:
return yData.elementAt(column);
case 2:
return yData2.elementAt(column);
case 3:
return xData2.elementAt(column);
default:
System.out.println("Bad data request in getDataItem!");
}
return null;
}
public java.util.Vector getRow(int row)
{
switch(row)
{
case 0:
if(finder) {
return xData;
} else {
return xData2;
}
case 1:
return yData;
case 2:
return yData2;
case 3:
return xData;
default:
System.out.println("Bad data request in getRow!");
}
return null;
}
/** Hard-coded to return only 3 rows */
public int getNumRows()
{
return 3;
}
public java.lang.String[] getPointLabels()
{
System.gc();
return pointLabels;
}
public java.lang.String getSeriesName(int row) {
return null;
}
// For the legend.
public java.lang.String getSeriesLabel(int row) {
System.out.println(" row: " + row);
return ("Finder " + (row+1));
}
public java.lang.String getName() {
return "Legend: ";
}
}
============================================================================
==============
===========================================================================
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message "signoff JAVA3D-INTEREST". For general help, send email to
[EMAIL PROTECTED] and include in the body of the message "help".