FileDocCategorySizeDatePackage
Grapher.javaAPI DocExample3697Thu May 27 22:01:30 BST 2004None

Grapher.java

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.geom.Point2D;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JPanel;

import com.darwinsys.util.Debug;

/** Simple Graphing program.
 * @author Ian F. Darwin, http://www.darwinsys.com/
 * @version $Id: Grapher.java,v 1.15 2004/05/28 02:01:30 ian Exp $
 */
public class Grapher extends JPanel {
	/** Multiplier for range to allow room for a border */
	public final static double BORDERFACTOR = 1.1f;

	/** The list of Point points. */
	protected List data;

	/** The minimum and maximum X values */
	protected double minx = Integer.MAX_VALUE, maxx = Integer.MIN_VALUE;
	/** The minimum and maximum Y values */
	protected double miny = Integer.MAX_VALUE, maxy = Integer.MIN_VALUE;
	/** The range of X and Y values */
	protected double xrange, yrange;

	public Grapher() {
		data = new ArrayList();
		figure();
	}

	/** Set the list data from a list of Strings, where the
	 * x coordinate is incremented automatically, and the y coordinate
	 * is made from the String in the list.
	 */
	public void setListDataFromYStrings(List newData) {
		data.clear();
		for (int i=0; i < newData.size(); i++) {
			Point2D p = new Point2D.Double();
			p.setLocation(i, java.lang.Double.parseDouble((String)newData.get(i)));
			data.add(p);
		}
		figure();
	}

	/** Set the list from an existing List, as from GraphReader.read() */
	public void setListData(List newData) {
		data = newData;
		figure();
	}

	/** Compute new data when list changes */
	private void figure() {
		// find min & max
        for (int i=0 ; i < data.size(); i++) {
			Point2D d = (Point2D)data.get(i);
			if (d.getX() < minx) minx = d.getX();
			if (d.getX() > maxx) maxx = d.getX();
			if (d.getY() < miny) miny = d.getY();
			if (d.getY() > maxy) maxy = d.getY();
        }

		// Compute ranges
		xrange = (maxx - minx) * BORDERFACTOR;
		yrange = (maxy - miny) * BORDERFACTOR;
		Debug.println("range", "minx,x,r = " + minx +' '+ maxx +' '+ xrange);
		Debug.println("range", "miny,y,r = " + miny +' '+ maxy +' '+ yrange);
	}

	/** Called when the window needs painting.
	 * Computes X and Y range, scales.
	 */
    public void paintComponent(Graphics g) {
		super.paintComponent(g);
		Dimension s = getSize();
		if (data.size() < 2) {
			g.drawString("Insufficient data: " + data.size(), 10, 40);
			return;
		}

		// Compute scale factors
		double xfact =  s.width  / xrange;
		double yfact =  s.height / yrange;

		// Scale and plot the data
        for (int i=0 ; i < data.size(); i++) {
			Point2D d = (Point2D)data.get(i);
			double x = (d.getX() - minx) * xfact;
			double y = (d.getY() - miny) * yfact;
			Debug.println("point", "AT " + i + " " + d + "; " +
				"x = " + x + "; y = " + y);
			// Draw a 5-pixel rectangle centered, so -2 both x and y.
			// AWT numbers Y from 0 down, so invert:
			g.drawRect(((int)x)-2, s.height-2-(int)y, 5, 5);
		}
    }

	public Dimension getPreferredSize() {
		return new Dimension(150, 150);
	}

	public static void main(String[] args) throws IOException {
		final JFrame f = new JFrame("Grapher");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		Grapher grapher = new Grapher();
		f.setContentPane(grapher);
		f.setLocation(100, 100);
		f.pack();
		List data = null;
		if (args.length == 0)
			data = GraphReader.read("Grapher.dat");
		else {
			String fileName = args[0];
			if ("-".equals(fileName)) {
				data = GraphReader.read(new InputStreamReader(System.in), "System.in");
			} else {
				data = GraphReader.read(fileName);
			}
		}
		grapher.setListData(data);
		f.setVisible(true);
	}
}