⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 plotter.java

📁 著名的开源仿真软件yale
💻 JAVA
字号:
/* *  YALE - Yet Another Learning Environment *  Copyright (C) 2002, 2003 *      Simon Fischer, Ralf Klinkenberg, Ingo Mierswa,  *          Katharina Morik, Oliver Ritthoff *      Artificial Intelligence Unit *      Computer Science Department *      University of Dortmund *      44221 Dortmund,  Germany *  email: yale@ls8.cs.uni-dortmund.de *  web:   http://yale.cs.uni-dortmund.de/ * *  This program is free software; you can redistribute it and/or *  modify it under the terms of the GNU General Public License as  *  published by the Free Software Foundation; either version 2 of the *  License, or (at your option) any later version.  * *  This program is distributed in the hope that it will be useful, but *  WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *  General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *  USA. */package edu.udo.cs.yale.gui;import edu.udo.cs.yale.Statistics;import edu.udo.cs.yale.StatisticsListener;import javax.swing.JPanel;import java.awt.geom.Point2D;import java.awt.geom.Line2D;import java.awt.geom.GeneralPath;import java.awt.geom.Rectangle2D;import java.awt.BasicStroke;import java.awt.Graphics;import java.awt.Graphics2D;import java.awt.Color;import java.awt.Font;import java.awt.Stroke;import java.awt.BasicStroke;import java.awt.Point;import java.awt.event.*;import java.awt.geom.AffineTransform;import java.awt.font.FontRenderContext;import java.util.SortedSet;import java.util.TreeSet;import java.util.List;import java.util.LinkedList;import java.util.Iterator;import java.util.Comparator;import java.text.DecimalFormat;public class Plotter extends JPanel implements StatisticsListener {    private static final Color[] LINE_COLORS =     { Color.black, Color.red, Color.blue, Color.orange, new Color(0,200,0) };    private static final Stroke[] LINE_STROKES =    { new BasicStroke(),      new BasicStroke(1f, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER, 10f, new float[] {6f,4f}, 0f ),      new BasicStroke(1f, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER, 10f, new float[] {6f,4f,2f,4f}, 0f ),      new BasicStroke(1f, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER, 10f, new float[] {3f,3f}, 0f ),    };    public static final LineStyle[] LINE_STYLES = new LineStyle[LINE_COLORS.length*LINE_STROKES.length];    static {	for (int i = 0; i < LINE_STROKES.length; i++) {	    for (int j = 0; j < LINE_COLORS.length; j++) {		LINE_STYLES[i*LINE_COLORS.length + j] = new LineStyle(LINE_COLORS[j],								      LINE_STROKES[i]);	    }	}    }    public static class LineStyle {	private Color color;	private Stroke stroke;	private LineStyle(Color color, Stroke stroke) {	    this.color = color;	    this.stroke = stroke;	}	public void set(Graphics2D g) {	    g.setColor(color);	    g.setStroke(stroke);	}    }    private class Plot extends TreeSet {	private int styleIndex;	private Plot(int styleIndex) {	    super(new Comparator() {		    public int compare(Object o1, Object o2) {			Point2D p1 = (Point2D)o1;			Point2D p2 = (Point2D)o2;			double dif = p1.getX() - p2.getX();			if (dif == 0.0) return 0;			else return (dif < 0) ? -1 : 1;		    }		});	    this.styleIndex = styleIndex;	}	private LineStyle getLineStyle() {	    return LINE_STYLES[styleIndex%LINE_STYLES.length];	}    }    private class RotationListener extends MouseAdapter implements MouseMotionListener {	private Point dragStart;	private int rotXStart;	private int rotZStart;	public void mousePressed(MouseEvent e) {	    dragStart = e.getPoint();	    rotXStart = rotX;	    rotZStart = rotZ;	}	public void mouseMoved(MouseEvent e) { }	public void mouseDragged(MouseEvent e) {	    rotX = (rotXStart + (int)(dragStart.getY() - e.getY())) % 180;	    if (rotX < 0) rotX += 180;	    rotZ = (rotZStart + (int)(dragStart.getX()- e.getX())) % 360;	    if (rotZ < 0) rotZ += 360;	    statisticsUpdated(null);	}    }    private int rotX = 60, rotZ = 30;    private static final int[] TICS = {1,2,5};    private static final Font LABEL_FONT = new Font("Lucida Sans", Font.PLAIN, 11).deriveFont(AffineTransform.getScaleInstance(1, -1));    private static final Color GRID_COLOR = Color.lightGray;    private static final int MARGIN = 20;    private static final int LABEL_MARGIN_X = 15;    private static final int LABEL_MARGIN_Y = 50;    private Statistics statistics;    private List plots = new LinkedList();    private double minX, maxX, minY, maxY, xTicSize, yTicSize;    private int xAxis = 0;    private int yAxis = -1;    private boolean[] columns;    private boolean hasChanged = false;    private java.awt.Image cachedImage = null;    private AffineTransform transform;    private GNUPlotDialog gnuPlotDialog = new GNUPlotDialog(this);    public Plotter(Statistics statistics) {	this.statistics = statistics;	statistics.addStatisticsListener(this);	columns = new boolean[statistics.getNumberOfColumns()];	prepareData();	setBackground(Color.white);		RotationListener listener = new RotationListener();	addMouseMotionListener(listener);	addMouseListener(listener);    }    public Statistics getStatistics() {	return statistics;    }    public void showGNUPlotDialog() {	gnuPlotDialog.show();    }    private void prepareData() {	plots.clear();	maxX = maxY = Double.NEGATIVE_INFINITY;	minX = minY = Double.POSITIVE_INFINITY;		for (int column = 0; column < columns.length; column++) {	    	    if (columns[column]) {				SortedSet points = new Plot(column);		Iterator i = statistics.iterator();		while (i.hasNext()) {		    Object[] row = (Object[])i.next();		    double x = Double.NaN;		    double y = Double.NaN;		    try {			if ((row[column] != null) && (row[xAxis] != null)) {			    x = Double.parseDouble(row[xAxis].toString());			    y = Double.parseDouble(row[column].toString());			    points.add(new Point2D.Double(x, y));			    minX = Math.min(x, minX);			    maxX = Math.max(x, maxX);			    minY = Math.min(y, minY);			    maxY = Math.max(y, maxY);			}		    } catch (NumberFormatException e) {			throw new IllegalArgumentException("Not a numerical data column: "+column);		    }		}				plots.add(points);	    }	}		if (statistics.getNumberOfRows() == 0) {	    minX = minY = 0;	    maxX = maxY = 1;	}		if (minX == maxX) {	    minX -= 0.5;	    maxX += 0.5;	}	if (minY == maxY) {	    minY -= 0.5;	    maxY += 0.5;	}		xTicSize = getTicSize(minX, maxX);	yTicSize = getTicSize(minY, maxY);	minX = Math.floor(minX / xTicSize) * xTicSize;	maxX = Math.ceil(maxX / xTicSize) * xTicSize;	minY = Math.floor(minY / yTicSize) * yTicSize;	maxY = Math.ceil(maxY / yTicSize) * yTicSize;    }	    private double getTicSize(double min, double max) {	double delta = (max - min) / 5;	double e = Math.floor(Math.log(delta) / Math.log(10));	double factor = Math.pow(10, e);	for (int i = TICS.length-1; i >= 0 ; i--) {	    if (TICS[i]*factor <= delta) return TICS[i] * factor;	}	return factor;    }    private void drawPoints(Graphics2D g, double dx, double dy, double sx, double sy) {	if (plots.size() == 0) return;			int c = 0;	Iterator p = plots.iterator();	while (p.hasNext()) {	    Plot plot = (Plot)p.next();	    if (plot.size() > 0) {		plot.getLineStyle().set(g);		GeneralPath path = new GeneralPath();		Iterator i = plot.iterator();		boolean first = true;		while (i.hasNext()) {		    Point2D point = (Point2D)i.next();		    float gSpaceX = (float)((point.getX()+dx)*sx);		    float gSpaceY = (float)((point.getY()+dy)*sy);		    if (first) path.moveTo(gSpaceX, gSpaceY);		    else path.lineTo(gSpaceX, gSpaceY);		    java.awt.geom.RectangularShape circle = new java.awt.geom.Ellipse2D.Double(gSpaceX - 2, gSpaceY - 2, 5, 5);		    g.fill(circle);		    first = false;		}		g.draw(path);		c = (c+1)%LINE_STYLES.length;	    }	}    }    private void drawGrid(Graphics2D g, double dx, double dy, double sx, double sy) {	DecimalFormat format = new DecimalFormat("0.00E0");	g.setFont(LABEL_FONT);  	g.setStroke(new BasicStroke(1));  	for (int i = 0; i < 12; i++) {  	    double x = i*xTicSize + minX;  	    double y = i*yTicSize + minY;	    g.setColor(GRID_COLOR);  	    g.draw(new Line2D.Double((x+dx)   *sx, (minY+dy)*sy, (x+dx)   *sx, (maxY+dy)*sy));  	    g.draw(new Line2D.Double((minX+dx)*sx, (y+dy)   *sy, (maxX+dx)*sx, (y+dy)   *sy));	    g.setColor(Color.black);	    String label = format.format(y)+" ";	    Rectangle2D stringBounds = LABEL_FONT.getStringBounds(label, g.getFontRenderContext());	    g.drawString(label, 			 (float)((minX+dx)*sx - stringBounds.getWidth()), 			 (float)((y+dy)*sy    - stringBounds.getHeight()/2 - stringBounds.getY()));	    label = format.format(x);	    stringBounds = LABEL_FONT.getStringBounds(label, g.getFontRenderContext());	    g.drawString(label, 			 (float)((x+dx)*sx    - stringBounds.getWidth()/2), 			 (float)((minY+dy)*sy + stringBounds.getHeight()));  	}    }    private void draw(Graphics2D g, int pixWidth, int pixHeight) {	Graphics2D coordinateSpace = (Graphics2D)g.create();	coordinateSpace.translate(LABEL_MARGIN_Y, LABEL_MARGIN_X);	transform.translate(LABEL_MARGIN_Y, LABEL_MARGIN_X);  	double sx = ((double)pixWidth-LABEL_MARGIN_Y)  / (maxX-minX);  	double sy = ((double)pixHeight-LABEL_MARGIN_X) / (maxY-minY);	transform.scale(sx, sy);	transform.translate(-minX, -minY);	drawGrid(coordinateSpace, -minX, -minY, sx, sy);	drawPoints(coordinateSpace, -minX, -minY, sx, sy);	coordinateSpace.dispose();    }    public void paintComponent(Graphics graphics) {	super.paintComponent(graphics);	if (yAxis == -1) {	    paint2DPlots(graphics);	} else {	    createGNUPlot(graphics);	    if (cachedImage != null)		graphics.drawImage(cachedImage, 0, 0, null);	}    }    private void createGNUPlot(Graphics graphics) {	if (hasChanged) {	    int count = 0;	    for (int i = 0; i < columns.length; i++)		if (columns[i]) count++;	    	    if (count > 0) {		int[] z = new int[count];		int j = 0;		for (int i = 0; i < columns.length; i++) {		    if (columns[i]) z[j++] = i;		}		try {		    cachedImage = statistics.createGNUPlot(xAxis, yAxis, z, 							   gnuPlotDialog.getGNUPlotCommands()+"\n"+							   "set view "+rotX+","+rotZ+"");		    hasChanged = false;		} catch (Exception e) {		    SwingTools.showSimpleErrorMessage("Error executing gnuplot", e);		}	    }	}    }    private void paint2DPlots(Graphics graphics) {	prepareData();	if (plots.size() == 0) return;	Graphics2D g = (Graphics2D)graphics;	g.setColor(Color.black);	int pixWidth  = getWidth()  - 2*MARGIN;	int pixHeight = getHeight() - 2*MARGIN;	transform = new AffineTransform();	Graphics2D scaled = (Graphics2D)g.create();	scaled.translate(MARGIN, MARGIN);	transform.translate(MARGIN, MARGIN);  	scaled.translate(0, pixHeight+1);  	transform.translate(0, pixHeight+1);  	scaled.scale(1,-1);  	transform.scale(1,-1);	draw(scaled, pixWidth, pixHeight);	scaled.dispose();  	String xAxisLabel = statistics.getColumnName(xAxis);  	Rectangle2D stringBounds = LABEL_FONT.getStringBounds(xAxisLabel, g.getFontRenderContext());  	g.drawString(xAxisLabel,   		     MARGIN + (int)(pixWidth/2-stringBounds.getWidth()/2),  		     MARGIN + (int)(pixHeight + stringBounds.getY())+3);    }        public AffineTransform getTransform() {	return transform;    }    public void statisticsUpdated(Statistics source) {	hasChanged = true;	repaint();    }    public void setXAxis(int xAxis) {	if (this.xAxis != xAxis) {	    this.hasChanged = true;	    this.xAxis = xAxis;	}    }    public void setYAxis(int yAxis) {	if (this.yAxis != yAxis) {	    this.hasChanged = true;	    this.yAxis = yAxis;	}    }    public void plotColumn(int index, boolean plot) {	if (this.columns[index] != plot) {	    this.hasChanged = true;	    columns[index] = plot;	}    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -