All Downloads are FREE. Search and download functionalities are using the official Maven repository.

JSci.swing.JGraph2D Maven / Gradle / Ivy

Go to download

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 JSci.swing;

import java.awt.*;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.ParseException;
import JSci.awt.*;import JSci.maths.ExtraMath;

/**
* The JGraph2D superclass provides an abstract encapsulation of 2D graphs.
* There is some support for the handling of NaN values.
* @version 1.8
* @author Mark Hale
*/
public abstract class JGraph2D extends JDoubleBufferedComponent implements GraphDataListener {
        public final static int LINEAR_SCALE = 0;
        public final static int LOG_SCALE = 1;
        /**
        * Data model.
        */
        protected Graph2DModel model;
        /**
        * Origin.
        */
        protected Point origin = new Point();
        protected Graph2D.DataMarker dataMarker = Graph2D.DataMarker.NONE;
        /**
        * Series colors.
        */
        protected Color seriesColor[]={Color.black,Color.blue,Color.green,Color.red,Color.yellow,Color.cyan,Color.lightGray,Color.magenta,Color.orange,Color.pink};
        /**
        * Axis numbering.
        */
        protected boolean xNumbering = true, yNumbering = true;
        protected NumberFormat xNumberFormat = new DecimalFormat("##0.0");
        protected NumberFormat yNumberFormat = new DecimalFormat("##0.0");
	protected boolean xAxisLine = true, yAxisLine = true;
        protected boolean gridLines = false;
        private final Color gridLineColor = Color.lightGray;
        /**
        * Axis scaling.
        */
        private float xScale,yScale;
        /**
        * Axis scaling type.
        */
        private int xScaleType, yScaleType;
        /**
        * Axis extrema.
        */
        private float minX, minY, maxX, maxY;
        private float scaledMinX, scaledMinY, scaledMaxX, scaledMaxY;
        private boolean autoXExtrema=true, autoYExtrema=true;
        private float xGrowth, yGrowth;
        /**
        * Axis numbering increment.
        */
        private final float xIncPixels = 40.0f;
        private final float yIncPixels = 40.0f;
        private float xInc,yInc;
        private boolean autoXInc=true,autoYInc=true;
        /**
        * Padding.
        */
        protected final int scalePad=5;
        protected final int axisPad=25;
        protected int leftAxisPad;
        /**
        * Constructs a 2D graph.
        */
        public JGraph2D(Graph2DModel gm) {
                model=gm;
                model.addGraphDataListener(this);
                dataChanged(new GraphDataEvent(model));
        }
        /**
        * Sets the data plotted by this graph to the specified data.
        */
        public final void setModel(Graph2DModel gm) {
                model.removeGraphDataListener(this);
                model=gm;
                model.addGraphDataListener(this);
                dataChanged(new GraphDataEvent(model));
        }
        /**
        * Returns the model used by this graph.
        */
        public final Graph2DModel getModel() {
                return model;
        }
        /**
        * Implementation of GraphDataListener.
	* Supports {@link JSci.awt.GraphDataEvent#isIncremental() incremental} updates.
        * Application code will not use this method explicitly, it is used internally.
        */
        public void dataChanged(GraphDataEvent e) {
                if(e.isIncremental()) {
                        Graphics g = getOffscreenGraphics();
                        if(g == null)
                                return;
                        final int series = e.getSeries();
                        if(series == GraphDataEvent.ALL_SERIES) {
                                model.firstSeries();
                                int n = 0;
                                do {
                                        final int i = model.seriesLength() - 1;
                                        incrementalRescale(model.getXCoord(i), model.getYCoord(i));
                                        g.setColor(seriesColor[n]);
                                        drawDataPoint(g, i);
                                        n++;
                                } while(model.nextSeries());
                        } else {
                                model.firstSeries();
                                int n=0;
                                for(; nseriesColor.length) {
                                Color tmp[]=seriesColor;
                                seriesColor=new Color[n];
                                System.arraycopy(tmp,0,seriesColor,0,tmp.length);
                                for(int i=tmp.length; i maxX)
                        max = autoXExtrema ? Math.max(x, maxX+xGrowth) : maxX+xGrowth;
                else
                        max = maxX;
                rescaleX(min, max);

                if(y < minY)
                        min = autoYExtrema ? Math.min(y, minY-yGrowth) : minY-yGrowth;
                else
                        min = minY;
                if(y > maxY)
                        max = autoYExtrema ? Math.max(y, maxY+yGrowth) : maxY+yGrowth;
                else
                        max = maxY;
                rescaleY(min, max);
        }
        /**
        * Turns axis numbering on/off.
        * Default is on.
        */
        public final void setNumbering(boolean flag) {
		setNumbering(flag, flag);
	}
        public final void setNumbering(boolean xFlag, boolean yFlag) {
                xNumbering = xFlag;
		yNumbering = yFlag;
                leftAxisPad = axisPad;
                if(yNumbering && 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(scaledMinX<0.0f) {
                                final int negXLen = (int)((Math.max(getSize().width,getMinimumSize().width)-2*(axisPad+scalePad))*scaledMinX/(scaledMinX-scaledMaxX));
                                yNumPad = Math.max(yNumPad-negXLen, 0);
                        }
                        leftAxisPad += yNumPad;
                }
                rescale();
        }
        public void addNotify() {
                super.addNotify();
                // getFont() is now not null
                // recalculate padding
                setNumbering(xNumbering, yNumbering);
        }
        /**
        * 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(xNumbering, yNumbering);
        }
        /**
        * Sets the display format used for x-axis numbering.
        */
        public final void setXNumberFormat(NumberFormat format) {
                xNumberFormat = format;
                setNumbering(xNumbering, yNumbering);
        }
        /**
        * Sets the display format used for y-axis numbering.
        */
        public final void setYNumberFormat(NumberFormat format) {
                yNumberFormat = format;
                setNumbering(xNumbering, yNumbering);
        }
	/**
	* Turns the axis lines on/off.
	*/
	public final void setAxisLines(boolean xFlag, boolean yFlag) {
		xAxisLine = xFlag;
		yAxisLine = yFlag;
		redraw();
	}
        /**
        * Turns grid lines on/off.
        * Default is off.
        */
        public final void setGridLines(boolean flag) {
                gridLines = flag;
                redraw();
        }
        /**
        * Sets the x-axis scale type.
        * @param t a _SCALE constant.
        */
        public final void setXScale(int t) {
                if(xScaleType != t) {
                        xScaleType = t;
                        dataChanged(new GraphDataEvent(model));
                }
        }
        /**
        * Sets the y-axis scale type.
        * @param t a _SCALE constant.
        */
        public final void setYScale(int t) {
                if(yScaleType != t) {
                        yScaleType = t;
                        dataChanged(new GraphDataEvent(model));
                }
        }
        /**
        * Sets the x-axis numbering increment.
        * @param dx use 0.0f for auto-adjusting (default).
        */
        public final void setXIncrement(float dx) {
                if(dx < 0.0f) {
                        throw new IllegalArgumentException("Increment should be positive.");
                } else if(dx == 0.0f) {
                        if(!autoXInc) {
                                autoXInc = true;
                                rescale();
                        }
                } else {
                        autoXInc = false;
                        if(dx != xInc) {
                                xInc = dx;
                                rescale();
                        }
                }
        }
        /**
        * Returns the x-axis numbering increment.
        */
        public final float getXIncrement() {
                return xInc;
        }
        /**
        * Sets the y-axis numbering increment.
        * @param dy use 0.0f for auto-adjusting (default).
        */
        public final void setYIncrement(float dy) {
                if(dy < 0.0f) {
                        throw new IllegalArgumentException("Increment should be positive.");
                } else if(dy == 0.0f) {
                        if(!autoYInc) {
                                autoYInc = true;
                                rescale();
                        }
                } else {
                        autoYInc = false;
                        if(dy != yInc) {
                                yInc = dy;
                                rescale();
                        }
                }
        }
        /**
        * Returns the y-axis numbering increment.
        */
        public final float getYIncrement() {
                return yInc;
        }
        /**
        * Sets the minimum/maximum values on the x-axis.
        * Set both min and max to 0.0f for auto-adjusting (default).
        */
        public final void setXExtrema(float min, float max) {
                if(min==0.0f && max==0.0f) {
                        autoXExtrema=true;
                        // determine min and max from model
                        min=Float.POSITIVE_INFINITY;
                        max=Float.NEGATIVE_INFINITY;
                        float tmp;
                        model.firstSeries();
                        do {
                                for(int i=0;i
            


© 2015 - 2024 Weber Informatics LLC | Privacy Policy