JSci.awt.LineTrace.vm Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jsci Show documentation
Show all versions of jsci Show documentation
JSci is a set of open source Java packages. The aim is to encapsulate scientific methods/principles in the most natural way possible. As such they should greatly aid the development of scientific based software.
It offers: abstract math interfaces, linear algebra (support for various matrix and vector types), statistics (including probability distributions), wavelets, newtonian mechanics, chart/graph components (AWT and Swing), MathML DOM implementation, ...
Note: some packages, like javax.comm, for the astro and instruments package aren't listed as dependencies (not available).
The newest version!
package ${package};
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.Point2D;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.Iterator;
import java.util.List;
import java.util.ArrayList;
#if(!($api == "AWT"))import JSci.awt.*;#end
import JSci.maths.ExtraMath;
/**
* A line trace ${api} component.
* @version 1.4
* @author Mark Hale
*/
public final class ${className} extends ${extendsClassName} {
/**
* Data points.
*/
private final List dataPoints = new ArrayList();
/**
* Sampling interval.
*/
private float samplingInterval;
/**
* Axis numbering.
*/
private boolean numbering=true;
private NumberFormat xNumberFormat = new DecimalFormat("${numberFormat}");
private NumberFormat yNumberFormat = new DecimalFormat("${numberFormat}");
/**
* Origin.
*/
private Point origin=new Point();
/**
* Min and max data points.
*/
private float minX,minY,maxX,maxY;
/**
* Axis scaling.
*/
private float xScale,yScale;
private final float xIncPixels = 40.0f;
private final float yIncPixels = 40.0f;
/**
* Padding.
*/
private final int scalePad=5;
private final int axisPad=25;
private int leftAxisPad;
/**
* Constructs a line trace.
*/
public ${className}(float minx,float maxx,float miny,float maxy) {
addMouseMotionListener(new MouseLineAdapter());
setXExtrema(minx,maxx);
setYExtrema(miny,maxy);
setSamplingInterval(0.2f);
}
/**
* Gets the data sampled by this line trace.
*/
public Graph2DModel getModel() {
final Point2DListModel model=new Point2DListModel();
model.setData(dataPoints);
return model;
}
/**
* Turns axis numbering on/off.
*/
public final void setNumbering(boolean flag) {
numbering=flag;
leftAxisPad=axisPad;
if(numbering && getFont() != null) {
// adjust leftAxisPad to accomodate y-axis numbering
final FontMetrics metrics = getFontMetrics(getFont());
final int maxYNumLen = metrics.stringWidth(yNumberFormat.format(maxY));
final int minYNumLen = metrics.stringWidth(yNumberFormat.format(minY));
int yNumPad = Math.max(minYNumLen, maxYNumLen);
if(minX<0.0f) {
final int negXLen = (int)((Math.max(getSize().width,getMinimumSize().width)-2*(axisPad+scalePad))*minX/(minX-maxX));
yNumPad = Math.max(yNumPad-negXLen, 0);
}
leftAxisPad += yNumPad;
}
}
public void addNotify() {
super.addNotify();
// getFont() is now not null
// recalculate padding
setNumbering(numbering);
}
/**
* Sets the display format used for axis numbering.
* Convenience method.
* @see #setXNumberFormat(NumberFormat)
* @see #setYNumberFormat(NumberFormat)
*/
public final void setNumberFormat(NumberFormat format) {
xNumberFormat = format;
yNumberFormat = format;
setNumbering(numbering);
}
/**
* Sets the display format used for x-axis numbering.
*/
public final void setXNumberFormat(NumberFormat format) {
xNumberFormat = format;
setNumbering(numbering);
}
/**
* Sets the display format used for y-axis numbering.
*/
public final void setYNumberFormat(NumberFormat format) {
yNumberFormat = format;
setNumbering(numbering);
}
/**
* Sets the minimum/maximum values on the x-axis.
*/
public void setXExtrema(float min,float max) {
if(max0.0f)
g.drawLine(leftAxisPad-scalePad,getHeight()-axisPad,getWidth()-(axisPad-scalePad),getHeight()-axisPad);
else
g.drawLine(leftAxisPad-scalePad,origin.y,getWidth()-(axisPad-scalePad),origin.y);
if(minX>0.0f)
g.drawLine(leftAxisPad,axisPad-scalePad,leftAxisPad,getHeight()-(axisPad-scalePad));
else
g.drawLine(origin.x,axisPad-scalePad,origin.x,getHeight()-(axisPad-scalePad));
#else
// axis
g.setColor(getForeground());
if(minY>0.0f)
g.drawLine(leftAxisPad-scalePad,getSize().height-axisPad,getSize().width-(axisPad-scalePad),getSize().height-axisPad);
else
g.drawLine(leftAxisPad-scalePad,origin.y,getSize().width-(axisPad-scalePad),origin.y);
if(minX>0.0f)
g.drawLine(leftAxisPad,axisPad-scalePad,leftAxisPad,getSize().height-(axisPad-scalePad));
else
g.drawLine(origin.x,axisPad-scalePad,origin.x,getSize().height-(axisPad-scalePad));
#end
// numbering
if(numbering) {
final FontMetrics metrics=g.getFontMetrics();
final int strHeight=metrics.getHeight();
// x-axis numbering
float dx = (float) ExtraMath.round((double)xIncPixels/(double)xScale, 1);
if(dx == 0.0f)
dx = Float.MIN_VALUE;
for(double x=(minX>0.0f)?minX:dx; x<=maxX; x+=dx) {
String str = xNumberFormat.format((float)x);
// add a + prefix to compensate for - prefix in negative number strings when calculating length
int strWidth=metrics.stringWidth('+'+str);
Point p=dataToScreen((float)x, (minY>0.0f)?minY:0.0f);
g.drawLine(p.x,p.y,p.x,p.y+5);
g.drawString(str,p.x-strWidth/2,p.y+5+strHeight);
}
for(double x=-dx; x>=minX; x-=dx) {
String str = xNumberFormat.format((float)x);
int strWidth=metrics.stringWidth(str);
Point p=dataToScreen((float)x, (minY>0.0f)?minY:0.0f);
g.drawLine(p.x,p.y,p.x,p.y+5);
g.drawString(str,p.x-strWidth/2,p.y+5+strHeight);
}
// y-axis numbering
float dy = (float) ExtraMath.round((double)yIncPixels/(double)yScale, 1);
if(dy == 0.0f)
dy = Float.MIN_VALUE;
for(double y=(minY>0.0f)?minY:dy; y<=maxY; y+=dy) {
String str = yNumberFormat.format((float)y);
int strWidth=metrics.stringWidth(str);
Point p=dataToScreen((minX>0.0f)?minX:0.0f, (float)y);
g.drawLine(p.x,p.y,p.x-5,p.y);
g.drawString(str,p.x-8-strWidth,p.y+strHeight/4);
}
for(double y=-dy; y>=minY; y-=dy) {
String str = yNumberFormat.format((float)y);
int strWidth=metrics.stringWidth(str);
Point p=dataToScreen((minX>0.0f)?minX:0.0f, (float)y);
g.drawLine(p.x,p.y,p.x-5,p.y);
g.drawString(str,p.x-8-strWidth,p.y+strHeight/4);
}
}
}
class MouseLineAdapter extends MouseMotionAdapter {
public void mouseDragged(MouseEvent evt) {
Point2D.Float p=screenToData(evt.getPoint());
final int i = dataPoints.size()-1;
if(p.x >= i*samplingInterval+minX && p.x <= maxX) {
dataPoints.add(p);
}
redraw();
}
}
}