// SimplePlotPanel.java // // Rahul Simha // Spring 2008 import java.util.*; import java.text.*; import java.io.*; import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.awt.geom.*; public class SimplePlotPanel extends JPanel { public static int glueSpace = 3; // Generic spacing between lines, text. public static int axisLabelFontSize = 10; // Font size for axis labels. public static int tickFontSize = 8; // Same for tickmark labels. public static int legendFontSize = 16; // Legend. public static int tickSize = 6; // Length of each tick mark. public static int titleFontSize = 12; // Length of each tick mark. public static int pointBlobRadius = 4; // Size of circle to mark a point. // Fonts and associated FontMetrics references: Font legendFont, tickFont, axisLabelFont, titleFont; FontMetrics tickFontMetrics, axisLabelFontMetrics, legendFontMetrics, titleFontMetrics; // Various box boundaries: // The panel: int panelHeight, panelWidth; // If an external bounding box is given: int bboxLeft, bboxRight, bboxTop, bboxBottom, bboxHeight, bboxWidth; // The inner box in which the curves are plotted: int plotBoxTopInset, plotBoxBottomInset, plotBoxLeftInset, plotBoxRightInset; int plotBoxHeight, plotBoxWidth, plotBoxLeft, plotBoxRight, plotBoxTop, plotBoxBottom; // The outerbox that contains the plotbox and the labels: int graphBoxHeight, graphBoxWidth, graphBoxLeft, graphBoxRight, graphBoxTop, graphBoxBottom; // The box below the outerbox that contains the legend: int legendBoxHeight, legendBoxWidth; int maxNumCurves; // Max allowable curves: for storage. int numCurves; // Actual number of curves. int maxNumValues; SimplePlotCurve[] curves; // The curves themselves. double Xmax, Xmin, Xrange; // Lowest, highest, and range of X values. double Ymax, Ymin, Yrange; // Same for Y. int numXTicks, numYTicks; // Number of tick marks. double[] XTicks, YTicks; // The actual points for the ticks. String[] XTickLabels, YTickLabels; // Labels. int XTickWidth, XTickHeight; // Font heights and widths. int YTickWidth, YTickHeight; String XaxisLabelString = "", YaxisLabelString = ""; // Axis labels. DecimalFormat Xformat, Yformat; // Format labels/ticks. String titleString = ""; // Title to appear center-top. // A set of colors to use. static Color colors[] = {Color.red, Color.blue, Color.green, Color.magenta}; // Parameters to constructor: total number of curves. Over all curves, // the largest number of X values, the largest number of Y values. public SimplePlotPanel (int maxNumCurves, int maxNumValues) { this.setBackground (Color.white); // Curve data: this.maxNumCurves = maxNumCurves; this.maxNumValues = maxNumValues; numCurves = 0; curves = new SimplePlotCurve [maxNumCurves]; for (int i=0; i pointSets, ArrayList names, String xLabel, int frameWidth, int frameHeight) { Vector[] pointSetVector = new Vector [pointSets.size()]; String[] nameVector = new String [names.size()]; for (int i=0; i 1) ) return new DecimalFormat (formatStr); value = high; } // Make it positive: if (value < 0) value = value * (-1); while (value < 1) { value = value * 10; formatStr = formatStr + "#"; } // System.out.println ("low=" + low + " high=" + high + " value=" + value + " formatStr=" + formatStr); return new DecimalFormat (formatStr); } String makeDoubleFormatX (double x) { String str= Xformat.format (x); // System.out.println ("makeX: x=" + x + " str=" + str); return str; } String makeDoubleFormatY (double y) { String str = Yformat.format (y); // System.out.println ("makeY: y=" + y + " str=" + str); return str; } void drawXTick (Graphics g, double x, String tickLabel) { // System.out.println ("DrawXTick: numXTicks=" + numXTicks + " x=" + x + " label=" + tickLabel); // Draw a tick at data position x. int xTick = dataXToPixelValue (x); int y = plotBoxBottom; g.setColor (Color.darkGray); g.drawLine (xTick, y+tickSize/2, xTick, y-tickSize/2); if (tickLabel != null) { // Put a label centered at xTick. int xLabelPos = xTick - (tickFontMetrics.stringWidth(tickLabel) / 2); int yLabelPos = plotBoxBottom + glueSpace + tickSize/2 + tickFontMetrics.getHeight(); g.drawString (tickLabel, xLabelPos, yLabelPos); } } void drawYTick (Graphics g, double y, String tickLabel) { // System.out.println ("DrawYTick: numYTicks=" + numYTicks + " y=" + y + " label=" + tickLabel); // Draw a tick at data position y. int yTick = dataYToPixelValue (y); int x = plotBoxLeft; g.setColor (Color.darkGray); g.drawLine (x-tickSize/2, yTick, x+tickSize/2, yTick); if (tickLabel != null) { // Put a label. int xLabelPos = plotBoxLeft - tickSize/2 - 2*glueSpace - tickFontMetrics.stringWidth(tickLabel); int yLabelPos = yTick + tickFontMetrics.getHeight()/2; g.drawString (tickLabel, xLabelPos, yLabelPos); } } void writeLegends (Graphics g) { for (int i=0; i 0) { prev_x = x; prev_y = y; } x = dataXToPixelValue (curve.getX(i)); y = dataYToPixelValue (curve.getY(i)); g.fillOval (x-pointBlobRadius, y-pointBlobRadius, 2*pointBlobRadius, 2*pointBlobRadius); //** Joint the dots? Assumes data is sorted. if (i > 0) g.drawLine (prev_x, prev_y, x, y); } } } class SimplePlotCurve { private int maxNumValues; // Maximum number of points. private int numXValues; // Actual number of points. private int numCurrentYValues; // Number of Y values added so far. String legendString; // String to print in legend. Color color; // Preferred color. private double[] X, Y; // The points. public SimplePlotCurve (int maxNumValues) { X = new double [maxNumValues]; Y = new double [maxNumValues]; numXValues = 0; numCurrentYValues = 0; } public void setXValues (double[] X) { numXValues = 0; for (int i=0; i numCurrentYValues) return numCurrentYValues; else return numXValues; } public int getNumYValues () { return numCurrentYValues; } public double getX (int i) { return X[i]; } public double getY (int i) { return Y[i]; } }