package fr.ensea.chart; import java.text.NumberFormat; import java.util.Locale; import java.awt.*; import java.awt.event.*; /** * Represents an Axis for the Plot2D viewer */ public class Axis { double min; // minimum double max; // maximum private boolean autoAxisBounds; // whether min and max should be computed automatically from curves bounds double inc; // space between ticks private int axisIndex; // either Curve2D.X_AXIS or Y_AXIS NumberFormat numberingsFormatter=NumberFormat.getNumberInstance(Locale.US); // formatter for axis numberings (aka ticks labels) int maxNumberingWidthPx; // maximum width (in pixels) of labels (updated by dataChanged()) /** * constructor with automatic axis bounds on * @param axisIndex either Curve2D.X_AXIS or Y_AXIS */ Axis(int axisIndex){ min=-0.5; max=0.5; autoAxisBounds=true; this.axisIndex=axisIndex; numberingsFormatter.setGroupingUsed(false); } /** * default constructor with automatic axis bounds off * @param axisIndex either Curve2D.X_AXIS or Y_AXIS */ Axis(int axisIndex, double mini, double maxi){ min=mini; max=maxi; autoAxisBounds=false; this.axisIndex=axisIndex; numberingsFormatter.setGroupingUsed(false); } /** * Toggles the automatic computing of axis bounds on and off ; default is on at time */ public void setAutoAxisBounds(boolean b){ this.autoAxisBounds=b; } /** * Manually sets bounds for the axis ; see resets the automatic bound mode */ public void setManualAxisBounds(double mini, double maxi){ this.min = mini; this.max = maxi; if (mini >= maxi) throw new IllegalArgumentException("Setting manual axis bounds : max MUST be greater than min !"); this.autoAxisBounds=false; } /* package access from Plot2D.dataChanged() */ void dataChanged(Plot2D plot2D){ if (autoAxisBounds) autoComputeAxisBounds(plot2D.curveArray); configureNumberingsFormater(plot2D.fontMetrics); } private void configureNumberingsFormater(FontMetrics fontMetrics){ // recompute nb of digits for the NumberFormat : (see java.text.NumberFormat) double d = Math.max(Math.abs(min), Math.abs(max)); numberingsFormatter.setMaximumFractionDigits((int)(2 - Math.log(d)/Math.log(10))); // i.e. 230., 15.2 and 1.00 => 4 significant digits maxNumberingWidthPx = fontMetrics.stringWidth(numberingsFormatter.format(-d)); // minus sign is important to get a precise estimate of the maximum label width } private void autoComputeAxisBounds(DecoratedCurve2D[] curveArray){ min=-0.5; max=0.5; if (curveArray.length==0) return; else { int i=0; while (i= min) return true; return false; } // clip x to the axis range double clip(double x){ if (x > max) x=max; else if (x