package mygraphs; import java.awt.*; import java.util.*; class XYGraphXYCanvas extends GraphPanel { Vector xDataVectors = new Vector(), yDataVectors = new Vector(); int numPos; Vector startPos = new Vector(), curPos = new Vector(); Vector itsXMaxs = new Vector(); float [] xSlopes = null; boolean negativeX = false; XYGraphXYCanvas(int num_storage_points) { super(); numPos = num_storage_points; } public int addItem(Color col) { colors.addElement(col); if(oneMax && itsYMaxs.size() > 0) itsYMaxs.addElement(itsYMaxs.elementAt(0)); else itsYMaxs.addElement(new Float(1.0)); if(oneMax && itsXMaxs.size() > 0) itsXMaxs.addElement(itsXMaxs.elementAt(0)); else itsXMaxs.addElement(new Float(1.0)); xDataVectors.addElement(new float[numPos]); yDataVectors.addElement(new float[numPos]); startPos.addElement(new Integer(0)); curPos.addElement(new Integer(0)); updateSlopes(); return xDataVectors.size() - 1; } public void addPoint(int index, float x_data, float y_data) { float [] xData, yData; boolean updateslopes = false; Dimension area = getSize(); Graphics og = offScrImage.getGraphics(); int cur_pos = ((Integer)curPos.elementAt(index)).intValue(); ((float [])xDataVectors.elementAt(index))[cur_pos] = x_data; ((float [])yDataVectors.elementAt(index))[cur_pos] = y_data; og.setColor((Color)colors.elementAt(index)); int plot_x = Math.round(x_data * xSlopes[index]); if(negativeX) plot_x += area.width / 2; int plot_y = Math.round(y_data * ySlopes[index]); if(negativeY) plot_y += area.height / 2; plot_y = area.height - plot_y - scaleInset; // If auto scaling the graph, check to see if we need to scale if(autoScale) { float val; if(plot_x < 0 || plot_x > area.width) { // Change the maximum to an integer multiple of 10, as long as its more than 10, // otherwise change it to an integer if its more than 1 val = (float)(Math.abs(x_data) * 1.5); if(val >= 10) val = (float)Math.ceil(val / 10.0) * 10; else if(val >= 1) val = (float)Math.ceil(val); // If all the maxs are the same, change all the other maxs as well if(oneMax) for(int i = 0; i < xDataVectors.size(); i++) itsXMaxs.setElementAt(new Float(val), i); else itsXMaxs.setElementAt(new Float(val), index); updateslopes = true; } if(!negativeX && (x_data < 0)) { negativeX = true; updateslopes = true; } if(plot_y < 0 || plot_y > area.height) { // Change the maximum to an integer multiple of 10, as long as its more than 10, // otherwise change it to an integer if its more than 1 val = (float)(Math.abs(y_data) * 1.5); if(val >= 10) val = (float)Math.ceil(val / 10.0) * 10; else if(val >= 1) val = (float)Math.ceil(val); // If all the maxs are the same, change all the other maxs as well if(oneMax) for(int i = 0; i < xDataVectors.size(); i++) itsYMaxs.setElementAt(new Float(val), i); else itsYMaxs.setElementAt(new Float(val), index); updateslopes = true; } if(!negativeY && (y_data < 0)) { negativeY = true; updateslopes = true; } } og.drawLine(plot_x, plot_y, plot_x+1, plot_y); og.drawLine(plot_x, plot_y+1, plot_x+1, plot_y+1); og.dispose(); // Advance the current storage position, and take care of wrapping around cur_pos++; if(cur_pos == numPos) { cur_pos = 0; startPos.setElementAt(new Integer(1), index); } else if(cur_pos == ((Integer)startPos.elementAt(index)).intValue()) { int new_start_pos = ((Integer)startPos.elementAt(index)).intValue() + 1; if(new_start_pos == numPos) new_start_pos = 0; startPos.setElementAt(new Integer(new_start_pos), index); } curPos.setElementAt(new Integer(cur_pos), index); if(updateslopes) updateSlopes(); Graphics g = getGraphics(); paint(g); g.dispose(); } public void updateSlopes() { int index; float max; if(xSlopes == null || xSlopes.length != xDataVectors.size()) xSlopes = new float[xDataVectors.size()]; Dimension area = getSize(); Enumeration elem = itsXMaxs.elements(); index = 0; while(elem.hasMoreElements()) { max = ((Float)elem.nextElement()).floatValue(); if(negativeX) xSlopes[index] = ((float)area.width / (max * 2)); else xSlopes[index] = ((float)area.width / max); index++; } super.updateSlopes(); } public void setXScale(float max) { if(max <= 0) return; // Maybe need to throw an exception ? for(int index = 0; index < itsXMaxs.size(); index++) { itsXMaxs.setElementAt(new Float(max), index); } updateSlopes(); } public void setXScale(float max, int index_num) { if(max <= 0) return; // Maybe need to throw an exception ? if(oneMax) { setXScale(max); return; } if(index_num >= itsXMaxs.size()) return; // Also an exception here ? itsXMaxs.setElementAt(new Float(max), index_num); updateSlopes(); } public void setXScale(float max, GraphableData obj) { int index = 0; while(index < itsXMaxs.size() && obj != xDataVectors.elementAt(index)) index++; if(index < itsXMaxs.size()) setXScale(max, index); } public void plotGraph(Graphics g) { float [] x_pts, y_pts; int pos = 0, index; float t; if(curPos == startPos) return; // Otherwise, probably some problems below /* Draw the data */ Dimension area = getSize(); Enumeration elem_x = xDataVectors.elements(); Enumeration elem_y = yDataVectors.elements(); Enumeration col_elem = colors.elements(); index = 0; while(elem_x.hasMoreElements()) { x_pts = (float [])elem_x.nextElement(); y_pts = (float [])elem_y.nextElement(); g.setColor((Color)col_elem.nextElement()); pos = ((Integer)startPos.elementAt(index)).intValue(); int cur_pos = ((Integer)curPos.elementAt(index)).intValue(); for(; pos != cur_pos; pos++) { if(pos == numPos) pos = 0; int plot_x = Math.round(x_pts[pos] * xSlopes[index]); if(negativeX) plot_x += area.width / 2; int plot_y = Math.round(y_pts[pos] * ySlopes[index]); if(negativeY) plot_y += area.height / 2; plot_y = area.height - plot_y - scaleInset; g.drawLine(plot_x, plot_y, plot_x+1, plot_y); g.drawLine(plot_x, plot_y+1, plot_x+1, plot_y+1); } index = index + 1; } offScrUpToDate = true; } }