JSci.awt.LineTrace Maven / Gradle / Ivy
package JSci.awt;
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;
import JSci.maths.ExtraMath;
/**
* A line trace AWT component.
* @version 1.4
* @author Mark Hale
*/
public final class LineTrace extends DoubleBufferedCanvas {
/**
* Data points.
*/
private final List dataPoints = new ArrayList();
/**
* Sampling interval.
*/
private float samplingInterval;
/**
* Axis numbering.
*/
private boolean numbering=true;
private NumberFormat xNumberFormat = new DecimalFormat("##0.0");
private NumberFormat yNumberFormat = new DecimalFormat("##0.0");
/**
* 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 LineTrace(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(max-->