Package JFplot

Source Code of JFplot.jPlot

package JFplot;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Paint;
import java.awt.Shape;
import java.awt.Stroke;
import java.io.File;
import java.io.IOException;

import javax.swing.JFrame;
import javax.swing.JPanel;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartFrame;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.annotations.XYPointerAnnotation;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.NumberTickUnit;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.ValueMarker;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.chart.title.LegendTitle;
import org.jfree.data.xy.DefaultXYDataset;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.data.general.DefaultPieDataset;
import org.jfree.ui.RectangleEdge;

// TODO subplots, load/save
import scalaSci.Vec;

/**
* This class encapsulates JFreeChart's XY charts. JFreeChart is very powerful,
* which also means that it is sometimes to complex for trivial tasks. This class
* simplifies the usage of JFreeChart by providing interface similar to Matlab's
* plot command.<p>
*
* To create a chart, we need X and Y values stored in arrays of
* doubles. Then we:
* <ul>
* <li>create a chart object</li>
* <li>display the chart in window</li> 
* <li>plot the data.</li>
* </ul>
* This procedure is illustrated by the following example:
* <pre>
*      double x1[] = new double[] { 0.1, 1.2, 1.5, 1.6, 2.0 };
*      double y1[] = new double[] { 0.1, 0.5, 0.5, 0.6, 0 };

*      jplot chart = new jplot("example1"); // create a chart object
*      chart.showInNewFrame();                // display it in new window
*
*      chart.plot(x1, y1);                    // draw a line
* </pre>
*  
* <p>
* If we want to display a chart in existing window, we can get a {@link JPanel}
* object containing chart by calling method {@link #getPanel()}
* <p>
* We can configure chart properties (colors, axis ranges...), by setter methods.
* Most <code>set...()</code> methods may be called before or after <code>plot()</code>
* and <code>addPlot()</code> methods. The exception to this rule are 
* methods, which set color and style of lines. They all have
* <code>lineIndex</code> or <code>lineId</code> as first parameter. These
* methods may be called only after the line with the given index or id has been
* drawn. 
* <p>
*
* <b>Examples:</b><br>
* Let's draw a green, dashed line, with 'x' markers and legend 'temperature':
* <pre>
*        String lineId = chart.plot(x1, y1, "g--x", "temperature");
* </pre>
* Note that we used <code>lineId</code> to store id for use in the next statement,
* where we'll change the line style and color to red dotted line with diamond
* markers. Width will be 5 pixels:
* <pre>
*        chart.setLineSpec(lineId, "r:d", 5);
* </pre>
* The same can be done by specifying the last plotted line:
* <pre>
*        chart.setLineSpec(jPlot.LAST_IDX, "r:d", 5);
* </pre>
* or specifying index value:
* <pre>
*        chart.setLineSpec(0, "r:d", 5);
* </pre>
*
* We can have more than one line on the chart at the same time. This can be
* achieved in one of three ways:<ul>
* <li>by specifying all lines in a single plot command, for example
*   <code>plot(x1, y1, x2, y2, x3, x3)</code></li>
* <li>by calling <code>setHold(true)</code> before calling next plot commands</li>
* <li>by calling method <code>addPlot()</code> instead of <code>plot()</code></li>
* </ul>
* <p>
* <b>Line specification</b>
* <p>
* Methods <code>plot(), addPlot()</code>, and <code>setLineSpec()</code> have
* parameter <code>lineSpec</code>, which defines line color, style, and markers.
* Any combination of color, marker and style is allowed. The following
* properties can be specified:
*
* <ul>
* <li>Colors:</li>
* <ul>
*   <li>r - red</li>
*   <li>g - green</li>
*   <li>b - blue</li>
*   <li>c - cyan</li>
*   <li>y - yellow</li>
*   <li>m - magenta</li>
*   <li>k - black</li>
* </ul>

* <li>Markers:</li>
* <ul>
*   <li>+ - Plus sign</li>
*   <li>o - Circle</li>
*   <li>* - Asterisk</li>
*   <li>. - Point</li>
*   <li>x - Cross</li>
*   <li>^ - Upward-pointing triangle</li>
*   <li>v - Downward-pointing triangle</li>
*   <li>> - Right-pointing triangle</li>
*   <li>< - Left-pointing triangle</li>
*   <li>'square' or s - Square</li>
*   <li>'diamond' or d - Diamond</li>
*   <li>'pentagram' or p - Five-pointed star (pentagram)</li>
*   <li>'hexagram' or h - Six-pointed star (hexagram)</li>
* </ul>
* <li>Styles</li>
* <ul>
<li><b>-</b> solid line</li>
<li><b>--</b> dashed line</li>
<li><b>:</b> dotted line</li>
<li><b>-.</b> dash-dot line</li>
* </ul>
* </ul>
*
* <b>Examples:</b><p>
* "yx--" - yellow dashed line with crosses at points<br>
* ":c" - dotted cyan line without markers<br>
* "w" - white solid line (the same as "w-")<br>
* <p>
*
*/


/*
var x1 = inc(0, 0.1, 10);
var x2 = sin(x1)
var jp = new  jplot("example1"); // create a chart object
jp.plot(x1, x2);                    // draw a line
jp.showInNewFrame
*/
public class jPlot   {

    /**
     * Use this value as line index, to refer to the last line added to
     * the chart.
     */
    static public   final int LAST_IDX = -1;
   
    public JFreeChart m_chart;
    public ChartPanel m_chartPanel;
    private JFrame m_frame;
    private DefaultXYDataset m_dataset;
    private boolean m_isHoldOn = false;

    private String m_title;
    private String m_xAxisLabel;
    private String m_yAxisLabel;
    private XYPointerAnnotation m_xyAnnotation;
    private ValueMarker m_xMarker;
    private ValueMarker m_yMarker;
    private double[] m_xAxisRange;
    private double[] m_yAxisRange;
    private Paint m_backgroundPaint;
    private Paint m_gridPaint;
    private double m_xTickDelta;
    private double m_yTickDelta;
   
    private int defaultXSize = 500;
    private int defaultYSize = 500;


   public JFreeChart getChart() {
       return m_chart;
   }
        /**
     * Enumeration of chart axes.
     */
    public enum AxisEnum {
        /** Identifies X axis. */
        X,
        /** Identifies Y axis. */
        Y
    };



    /**
     * Call this method to get the panel with chart, which can be displayed
     * inside custom window.
     *
     * @return panel containing this chart
     */
    public  JPanel getPanel() {
        if (m_chartPanel == null) {
            if (m_chart == null) {
                m_dataset = new DefaultXYDataset();
                m_chart = ChartFactory.createXYLineChart(m_title,  m_xAxisLabel,  m_yAxisLabel,
                                                         m_dataset,  PlotOrientation.VERTICAL,  true,  true,  false);
                initChart();
            }
             m_chartPanel = new ChartPanel(m_chart);
        }
        return m_chartPanel;
       
    }
   
     public  JPanel getPanel(jPlot jp) {
        if (jp.m_chartPanel == null) {
            if (jp.m_chart == null) {
                jp.m_dataset = new DefaultXYDataset();
                jp.m_chart = ChartFactory.createXYLineChart(m_title,  m_xAxisLabel,  m_yAxisLabel,
                                                         m_dataset,  PlotOrientation.VERTICAL,  true,  true,  false);
                initChart();
            }
            jp.m_chartPanel = new ChartPanel(jp.m_chart);
        }
        return jp.m_chartPanel;
       
    }


    /**
     * Call this method to open chart in a new window.
     *
     * @return the created frame with the chart
     */
    public JFrame showInNewFrame() {
        if (m_frame == null) {
            m_frame = new JFrame();
            m_frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            m_frame.setContentPane(getPanel());
            m_frame.pack();
            m_frame.setVisible(true);
        }
        return m_frame;
    }


public JFrame showInNewFrame(int figId) {
        if (m_frame == null) {
            m_frame = new JFrame();
            m_frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            m_frame.setContentPane(getPanel());
            String figStr = "Figure "+figId;
            m_frame.setTitle(figStr);
            m_frame.pack();
            m_frame.setVisible(true);
        }
        return m_frame;
    }

    /**
     * Call this method to open chart in a new window. The only difference
     * between this method and showInNewFrame() is in return value. This method
     * was implemented because MAtlab did not recognize method showInNewFrame()
     * possibly because of unknown class JFrame???
     *
     * @return the created frame with the chart
     */
    public void showInNewWindow() {
        if (m_frame == null) {
            m_frame = new JFrame();
            m_frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            m_frame.setContentPane(getPanel());
            m_frame.pack();
            m_frame.setVisible(true);
        }
    }

       
    /**
     * Another method for testing in Matlab - without variable argument list.
     * 
     * @param x
     * @param y
     * @param dummy
     * @return
     */
      public String jplot(double []x, double []y, double dummy) {
        return jplot(x, y)[0];
    }
   
  /**
     * This method plots lines. Colors are cycled in the following order:
     * "y", "c", "m", "k", "r", "g", "b".
     * 
     * @param x array of X values
     * @param y array of Y values
     * @param args optional arrays of doubles for additional lines. Even arguments
     * are used as X values, odd arguments are used as Y values.
     * @return ids of lines. These ids can be used instead of index when calling
     * methods, which take lineId as parameter, for example setLineColor(),
     * setLinestyle(), setLineSpec(), addAnnotation().
     */
       public String[] jplot(double []x, double []y, double[]... args) {
       
        if (args.length % 2 != 0) {
            throw new IllegalArgumentException("There should be even number of " +
                                           "input arrays! It is: " + args.length);
        }
        int noOfSeries = args.length / 2 + 1;
        String [] seriesKeys = new String[noOfSeries];
        seriesKeys[0] = jplot(x, y, "y", "")[0];
       
        int keyIndex = 1;
        String colors [] = {"y", "c", "m", "k", "r", "g", "b"};
        for (int i = 0; i < args.length; i += 2) {
            double xa[] = args[i];
            double ya[] = args[i + 1];
            seriesKeys[keyIndex++] = addPlot(xa, ya, colors[i % colors.length], "");
        }
       
        return seriesKeys;
    }

       /**
     * This method plots lines. Colors are cycled in the following order:
     * "y", "c", "m", "k", "r", "g", "b".
     * 
     * @param x Vec of X values
     * @param y Vec of Y values
     * @param args optional arrays of Vecs for additional lines. Even arguments
     * are used as X values, odd arguments are used as Y values.
     * @return ids of lines. These ids can be used instead of index when calling
     * methods, which take lineId as parameter, for example setLineColor(),
     * setLinestyle(), setLineSpec(), addAnnotation().
     */
       // dummy parameter is needed for disambiguation
       public String[] jplot(Vec  x, Vec  y, int dummy, Vec ... args) {
       
        if (args.length % 2 != 0) {
            throw new IllegalArgumentException("There should be even number of " +
                                           "input arrays! It is: " + args.length);
        }
        int noOfSeries = args.length / 2 + 1;
        String [] seriesKeys = new String[noOfSeries];
        seriesKeys[0] = jplot(x, y, "y", "")[0];
       
        int keyIndex = 1;
        String colors [] = {"y", "c", "m", "k", "r", "g", "b"};
        for (int i = 0; i < args.length; i += 2) {
            double xa[] = args[i].getv();
            double ya[] = args[i + 1].getv();;
            seriesKeys[keyIndex++] = addPlot(xa, ya, colors[i % colors.length], "");
        }
       
        return seriesKeys;
    }

  
       public String[] jplot(Vec x, Vec y, double[]... args) {
        return jplot(x.getv(), y.getv(), args);
    }

       public String[] jplot(double [] x, Vec y, double[]... args) {
        return jplot(x, y.getv(), args);
    }

      public String[] jplot(Vec  x, double [] y, double[]... args) {
        return jplot(x.getv(), y, args);
    }

       public String[] jplot(double [] x) {
         // construct implicitly the axis
           int sigLen = x.length;
           double [] taxis = new double[sigLen];
           for (int k=0; k<sigLen; k++)
               taxis[k] = k;
                  
        return jplot(taxis, x);
    }

       public String[] jplot(Vec  x) {
            // construct implicitly the axis
           int sigLen = x.size();
           double [] taxis = new double[sigLen];
           for (int k=0; k<sigLen; k++)
               taxis[k] = k;
         return jplot(taxis, x.getv());
    }
      
       public String[] jplot(Vec  x, String specs) {
            // construct implicitly the axis
           int sigLen = x.size();
           double [] taxis = new double[sigLen];
           for (int k=0; k<sigLen; k++)
               taxis[k] = k;
         return jplot(taxis, x.getv(), specs);
    }
        public String[] jplot(double x[], String lineSpec, Object... args) {
    // construct implicitly the axis
           int sigLen = x.length;
           double [] taxis = new double[sigLen];
           for (int k=0; k<sigLen; k++)
               taxis[k] = k;
         return jplot(taxis, x, lineSpec, args);
        }
       
        public String[] jplot(Vec x, String lineSpec, Object... args) {
    // construct implicitly the axis
           int sigLen = x.size();
           double [] taxis = new double[sigLen];
           for (int k=0; k<sigLen; k++)
               taxis[k] = k;
         return jplot(taxis, x.getv(), lineSpec, args);
        }
       
       
    /**
     * This method plots lines with the specified line style and color.
     * 
     * @param x array of X values
     * @param y array of Y values
     * @param lineSpec line specification, see class description for details
     * @param args triples of (double x[], double y[], String lineSpec) for next
     * lines
     * @return ids of lines. These ids can be used instead of index when calling
     * methods, which take lineId as parameter, for example setLineColor(),
     * setLinestyle(), setLineSpec(), addAnnotation().
     */
       public String[] jplot(double x[], double y[], String lineSpec, Object... args) {
       
        if (args.length % 3 != 0) {
            throw new IllegalArgumentException("The number of input args should " +
                                           "be multiple of 3! It is: " + args.length);
        }
       
        int noOfSeries = args.length / 3 + 1;
        String [] seriesKeys = new String[noOfSeries];
        seriesKeys[0] = jplot(x, y, lineSpec, "")[0];
       
        int keyIndex = 1;
        for (int i = 0; i < args.length; i += 3) {
            double xa[] = (double[])args[i];
            double ya[] = (double[])args[i + 1];
            String lineSpecA = (String)args[i + 2];
            seriesKeys[keyIndex++] = addPlot(xa, ya, lineSpecA, "");
        }
       
        return seriesKeys;
    }

    /*
     var opl = new plot
     var  t = Inc(0, 0.01, 10)
     var  x = sin(0.234*t)+0.45*cos(0.3*t)
  //  we draw a red dashed line, with 'x' markers and legend sin-cos
     opl.jplot(t,x, "r--x", "sin-cos")
     opl.showInNewFrame
*/   
    
     /**
     * This method plots lines with the specified line style and color.
     * 
     * @param x array of X values
     * @param y array of Y values
     * @param lineSpec line specification, see class description for details
     * @param legend text for legend
     * @param args tuples of (double x[], double y[], String lineSpec, String legend) for next
     * lines
     * @return ids of lines. Usually the 'legend' parameter is used as id, unless
     * the line with the same legend already exists in the chart. In such case
     * the legend string is modified. These ids can be used instead of indices when calling
     * methods, which take <code>lineId </code> as parameter, for example <code>setLineColor(),
     * setLinestyle(), setLineSpec(), addAnnotation()</code>.
     */
/*
var t=inc(0,0.01, 2); var x = sin(2.3*t);
jplot(t, x)
*/
      public String[] jplot(double []x, Vec  y, String lineSpec, String legend, Object... args) {
          return   jplot(x, y.getv(), lineSpec, legend, args);
    }
   
       public String[] jplot(Vec x, Vec  y, String lineSpec, String legend, Object... args) {
           return   jplot(x.getv(), y.getv(), lineSpec, legend, args);
    }
   
       public String[] jplot(Vec x, double []  y, String lineSpec, String legend, Object... args) {
           return  jplot(x.getv(), y, lineSpec, legend, args);
    }
   
      
        public String[] jplot(double x[], String lineSpec, String legend, Object... args) {
    // construct implicitly the axis
           int sigLen = x.length;
           double [] taxis = new double[sigLen];
           for (int k=0; k<sigLen; k++)
               taxis[k] = k;
         return jplot(taxis, x, lineSpec, legend, args);
        }
       
        public String[] jplot(Vec x, String lineSpec, String legend,  Object... args) {
    // construct implicitly the axis
           int sigLen = x.size();
           double [] taxis = new double[sigLen];
           for (int k=0; k<sigLen; k++)
               taxis[k] = k;
         return jplot(taxis, x.getv(), lineSpec, legend, args);
        }
       
      public String[] jplot(double x[], double y[], String lineSpec, String legend, Object... args) {

        if (args.length % 4 != 0) {
            throw new IllegalArgumentException("The number of input args should " +
                                           "be multiple of 4! It is: " + args.length);
        }
       
        LineAttrs lineAttrs = new LineAttrs(lineSpec);
        int noOfSeries = args.length / 4 + 1;
        String [] seriesKeys = new String[noOfSeries];
        seriesKeys[0] = jplot(x,
                             y,
                             lineAttrs.getColor(),
                             lineAttrs.getMarker(),
                             lineAttrs.getStyle(),
                             legend);

        int keyIndex = 1;
        for (int i = 0; i < args.length; i += 4) {
            double xa[] = (double[])args[i];
            double ya[] = (double[])args[i + 1];
            String lineSpecA = (String)args[i + 2];
            String legendA = (String)args[i + 3];
            seriesKeys[keyIndex++] = addPlot(xa, ya, lineSpecA, legendA);
        }
       
        return seriesKeys;
    }

public String jplot(double x[], Paint color, Shape marker,  float[] style,  String legend) {
// construct implicitly the axis
           int sigLen = x.length;
           double [] taxis = new double[sigLen];
           for (int k=0; k<sigLen; k++)
               taxis[k] = k;
   
           return jplot(taxis, x, color, marker, style, legend);
}



public String jplot(Vec  x, Paint color, Shape marker,  float[] style,  String legend) {
// construct implicitly the axis
           int sigLen = x.size();
           double [] taxis = new double[sigLen];
           for (int k=0; k<sigLen; k++)
               taxis[k] = k;
   
           return jplot(taxis, x.getv(), color, marker, style, legend);
}

/**
     * We use this method when we want to specify line properties, which can not
     * be specified with standard specification string.
     *
     * @param x array of X values
     * @param y array of Y values
     * @param color line color
     * @param marker shape used to mark points given by x[] and y[]
     * @param style definition for lengths of dashes and dots, for example:
     * new float[]{2, 5, 8, 5} specifies dot dash line.
     * @param legend text to appear in the legend
     * @return id of line. Usually the 'legend' parameter is used as id, unless
     * the line with the same legend already exists in the chart. In such case
     * the legend string is modified. This id can be used instead of index when calling
     * methods, which take lineId as parameter, for example <code>setLineColor(),
     * setLinestyle(), setLineSpec(), addAnnotation()</code>.
     */
       public String jplot(double x[], double y[], Paint color, Shape marker,  float[] style,  String legend) {

        if (x.length != y.length) {
            throw new IllegalArgumentException("Arrays x and y must have the same size!"
                    + " x.len = " + x.length + ",  y.len = " + y.length);
        }

        String seriesKey = null;
       
        if (m_chart == null) {
            m_dataset = new DefaultXYDataset();
           
            seriesKey = getUniqueSeriesKey(m_dataset, legend);
            m_dataset.addSeries(seriesKey,
                                new double[][] { x, y });

            m_chart = ChartFactory.createXYLineChart(m_title,
                                                     m_xAxisLabel,
                                                     m_yAxisLabel,
                                                     m_dataset,
                                                     PlotOrientation.VERTICAL,
                                                     true,
                                                     true,
                                                     false);
            initChart();
        } else { // chart already exists - we'll use it
            if (m_isHoldOn) {
                seriesKey = getUniqueSeriesKey(m_dataset, legend);
                m_dataset.addSeries(seriesKey, new double[][] { x, y });
            } else {   // hold not ON
                for (int i = 0; i < m_dataset.getSeriesCount(); i++) {
                    Comparable key = m_dataset.getSeriesKey(i);
                    m_dataset.removeSeries(key);
                }
                seriesKey = getUniqueSeriesKey(m_dataset, legend);
                m_dataset.addSeries(seriesKey, new double[][] { x, y });
            }
        }

        if (color == null) {
            color = Color.yellow;
        }
       
        setLineColor(LAST_IDX, color);
       
        if (marker != null  ||  style != null) {
            setLineStyle(LAST_IDX,
                         marker,
                         1,
                         style);
        }
       
        return seriesKey;
    }

       public ChartFrame  jPieChart(String [] categories, double [] values, String chartTitle) {
           DefaultPieDataset data = new DefaultPieDataset();
           for (int k=0; k<values.length; k++
              data.setValue(categories[k], values[k]);
            m_chart = ChartFactory.createPieChart(chartTitle, data, true, true, true);
          
           ChartFrame cf = new ChartFrame("Pie Chart", m_chart);
           cf.setSize(defaultXSize, defaultYSize);
           cf.setVisible(true);
           return cf;
      
       }
      
      
       /*
        var categories  = Array("category1", "category2", "category3")
        var values = Array(8.9, 5.6, 3.4)
        var jchart  = new jPlot()
        jchart.jPieChart(categories, values, "A demo pie chart")
        jchart.getChart().setBackgroundPaint(Color.blue)
        *
       
        */


    /**
     * If setters were called before chart has been created, set them now.
     */
     private void initChart() {
        XYPlot plot = m_chart.getXYPlot();

        if (m_xyAnnotation != null) {
            plot.addAnnotation(m_xyAnnotation);
        }
       
        if (m_xMarker != null) {
            plot.addDomainMarker(m_xMarker);
        }
       
        if (m_yMarker != null) {
            plot.addRangeMarker(m_yMarker);
        }
       
        if (m_xAxisRange != null) {
            NumberAxis rangeAxis = getAxis(AxisEnum.X);
            rangeAxis.setRange(m_xAxisRange[0], m_xAxisRange[1]);
        }
       
        if (m_yAxisRange != null) {
            NumberAxis rangeAxis = getAxis(AxisEnum.Y);
            rangeAxis.setRange(m_yAxisRange[0], m_yAxisRange[1]);
        }
       
        if (m_backgroundPaint != null) {
            m_chart.setBackgroundPaint(m_backgroundPaint);
            plot.setBackgroundPaint(m_backgroundPaint);
        }
       
        if (m_gridPaint != null) {
            plot.setDomainGridlinePaint(m_gridPaint);
            plot.setRangeGridlinePaint(m_gridPaint);
        }
       
        if (m_xTickDelta > 0) {
            NumberAxis rangeAxis = getAxis(AxisEnum.X);
            rangeAxis.setTickUnit(new NumberTickUnit(m_xTickDelta));
        }
       
        if (m_yTickDelta > 0) {
            NumberAxis rangeAxis = getAxis(AxisEnum.Y);
            rangeAxis.setTickUnit(new NumberTickUnit(m_yTickDelta));
        }
       
    }


    /**
     * Sets text for the given axis.
     * @param label axis text
     */
    public void setLabel(AxisEnum axis, String label) {
        if (m_chart != null) {
            ValueAxis vaxis = getAxis(axis)// plot.getRangeAxis();
            vaxis.setLabel(label);
        }
       
        switch (axis) {
        case X:
            m_xAxisLabel = label;
            break;
        case Y:
            m_yAxisLabel = label;
            break;
        }
    }


    /**
     * Sets text for X axis.
     * @param label x axis text */
    public void setXLabel(String label) {
        m_xAxisLabel = label;
        XYPlot plot = m_chart.getXYPlot();
        ValueAxis axis = plot.getDomainAxis();
        axis.setLabel(label);
    }
   
    /**
     * Sets text for Y axis.
     * @param label y axis text */
    public void setYLabel(String label) {
        m_yAxisLabel = label;
        XYPlot plot = m_chart.getXYPlot();
        ValueAxis axis = plot.getRangeAxis();
        axis.setLabel(label);
    }
    


    /**
     * Sets the chart title.
     * @param title title text.
     */
    public void setTitle(String title) {
        if (m_chart != null) {
            m_chart.setTitle(title);
        }
        m_title = title;
    }


    /**
     * Sets the chart background color.
     * 
     * @param color new background color. For example
     * <code>new java.awt.Color(12, 45, 145),</code> or <code>java.awt.Color.grey</code>.
     */
    public void setBackground(Paint color) {
        if (m_chart != null) {
            m_chart.setBackgroundPaint(color);
           
            XYPlot plot = m_chart.getXYPlot();
            plot.setBackgroundPaint(color);
        }
       
        m_backgroundPaint = color;
    }


    /**
     * Sets the grid color.
     *
     * @param color grid color.
     */
    public void setGridColor(Paint color) {
       
        if (m_chart != null) {
            XYPlot plot = m_chart.getXYPlot();
            plot.setDomainGridlinePaint(color);
            plot.setRangeGridlinePaint(color);
        }
       
        m_gridPaint = color;
    }


    /**
     * This method sets visibility of line parts.
     * Line is composed of line segments and markers. This method specifies,
     * which of these should be visible.
     *
     * @param lineIndex index specifying the line. Indices are assigned to
     * lines in the same order as they were added to chart. Use jPlo.LAST_IDX
     * to refer to the last line added.
     * @param isLineVisible if true, line segments are visible
     * @param isShapeVisible if true, markers are visible.
     */
    public void setLineVisibility(int lineIndex,
                                  boolean isLineVisible,
                                  boolean isShapeVisible) {
        XYPlot plot = m_chart.getXYPlot();
        XYLineAndShapeRenderer renderer = (XYLineAndShapeRenderer) plot.getRenderer();
       
        lineIndex = getLastIndex(lineIndex);
        renderer.setSeriesLinesVisible(lineIndex, isLineVisible);
        renderer.setSeriesShapesVisible(lineIndex, isShapeVisible);
    }


    /**
     * This method sets visibility of line parts.
     * Line is composed of line segments and markers. This method specifies,
     * which of these should be visible.
     *
     * @param lineId id specifying the line. Ids are returned from jplot() and
     * addPlot() methods. Usually the 'legend' parameter is used as id, unless
     * the line with the same legend already exists in the chart. In such case
     * the legend string is modified. 
     * @param isLineVisible if true, line segments are visible
     * @param isShapeVisible if true, markers are visible.
     */
    public void setLineVisibility(String lineId,
                                  boolean isLineVisible,
                                  boolean isShapeVisible) {
        setLineVisibility(getLineIndex(lineId), isLineVisible, isShapeVisible);
    }
   
   
    /**
     * Sets color of existing line.
     *
     * @param lineIndex index specifying the line. Indices are assigned to
     * lines in the same order as they were added to chart. Use jPlot.LAST_IDX
     * to refer to the last line added.
     * @param linePaint for example: Paint paint = Color.magenta;
     */
    public void setLineColor(int lineIndex, Paint linePaint) {
        XYPlot plot = m_chart.getXYPlot();
        XYLineAndShapeRenderer renderer = (XYLineAndShapeRenderer) plot.getRenderer();

        renderer.setSeriesPaint(getLastIndex(lineIndex), linePaint);
    }


    /**
     * Sets color of existing line.
     *
     * @param lineId id specifying the line. Ids are returned from jplot() and
     * addPlot() methods. 
     * @param linePaint for example: Paint paint = Color.magenta;
     */
    public void setLineColor(String lineId, Paint linePaint) {
        setLineColor(getLineIndex(lineId), linePaint);
    }
   
   
    /**
     * This method specifies shape of markers and line width.
     * 
     * @param lineIndex index specifying the line. Indices are assigned to
     * lines in the same order as they were added to chart. Use jPlot.LAST_IDX
     * to refer to the last line added.
     *
     * @param marker
     *            shape drawn at point positions, for example new
     *            Rectangle2D.Double(-4, -4, 8, 8). May also be null, to keep
     *            the existing shape.
     * @param lineWidth line width
     *
     * @see #LAST_IDX
     */
    public void setLineStyle(int lineIndex, Shape marker, int lineWidth) {
        setLineStyle(lineIndex, marker, lineWidth, new float[] { 1 });
    }


    /**
     * This method specifies shape of markers and line width.
     * 
     * @param lineId id specifying the line. Ids are returned from jplot() and
     * addPlot() methods. 
     *
     * @param marker
     *            shape drawn at point positions, for example new
     *            Rectangle2D.Double(-4, -4, 8, 8). May also be null, to keep
     *            the existing shape.
     * @param lineWidth line width
     *
     * @see #LAST_IDX
     */
    public void setLineStyle(String lineId, Shape marker, int lineWidth) {
        setLineStyle(getLineIndex(lineId), marker, lineWidth, new float[] { 1 });
    }


    /**
     * This method specifies shape of markers and line width.
     * It is intended for advanced users, who are familiar with Java2D API.
     *
     * @param lineIndex index specifying the line. Indices are assigned to
     * lines in the same order as they were added to chart. Use jPlot.LAST_IDX
     * to refer to the last line added.
     *
     * @param marker
     *            shape drawn at point positions, for example new
     *            Rectangle2D.Double(-4, -4, 8, 8). May also be null, to keep
     *            the existing shape.
     * @param lineWidth line width
     * @param style
     *            specifies lenghts of dashes and spaces, for example new
     *            float[]{1, 10, 5, 5}
     */
    public void setLineStyle(int lineIndex,
                             Shape marker,
                             int lineWidth,
                             float[] style) {

        XYPlot plot = m_chart.getXYPlot();
        XYLineAndShapeRenderer renderer = (XYLineAndShapeRenderer) plot.getRenderer();

        lineIndex = getLastIndex(lineIndex);
        if (marker != null) {
            renderer.setSeriesShape(lineIndex, marker);
            if (style == null) { // no line, draw only markers
                /* float dashPhase = 0;
                Stroke stroke = new BasicStroke(lineWidth,
                                                BasicStroke.CAP_ROUND,
                                                BasicStroke.JOIN_ROUND,
                                                2,
                                                null,
                                                dashPhase);
                renderer.setSeriesStroke(lineIndex, stroke);
                */
                setLineVisibility(lineIndex, false, true);
            } else {
                setLineVisibility(lineIndex, true, true); // show line and markers
            }
        }
       
        if (style != null) {
            float dashPhase = 0;
            Stroke stroke = new BasicStroke(lineWidth,
                                            BasicStroke.CAP_ROUND,
                                            BasicStroke.JOIN_ROUND,
                                            2,
                                            style,
                                            dashPhase);
            renderer.setSeriesStroke(lineIndex, stroke);
        }
    }


    /**
     * This method specifies shape of markers and line width.
     *
     * @param lineId id specifying the line. Ids are returned from jplot() and
     * addPlot() methods.
     *
     * @see #setLineStyle(int, Shape, int, float[])
     */
    public void setLineStyle(String lineId,
                             Shape marker,
                             int lineWidth,
                             float[] style) {
        setLineStyle(getLineIndex(lineId), marker, lineWidth, style);
    }
   

    /**
     * This method sets line specification - color, style, markers, and width.
     *
     * @param lineIndex index specifying the line. Indices are assigned to
     * lines in the same order as they were added to chart. Use jPlot.LAST_IDX
     * to refer to the last line added.

     * @param lineSpec line specification, see class description for details
     * @param lineWidth width of the line
     */
    public void setLineSpec(int lineIndex, String lineSpec, int lineWidth) {

        LineAttrs lineAttrs = new LineAttrs(lineSpec);
        setLineColor(lineIndex, lineAttrs.getColor());
        setLineStyle(lineIndex, lineAttrs.getMarker(), lineWidth, lineAttrs.getStyle());
    }


    /**
     * This method sets line specification - color, style, markers, and width.
     *
     * @param lineId id specifying the line. Ids are returned from jplot() and
     * addPlot() methods.

     * @param lineSpec line specification, see class description for details
     * @param lineWidth width of the line
     */
    public void setLineSpec(String lineId, String lineSpec, int lineWidth) {
        setLineSpec(getLineIndex(lineId), lineSpec, lineWidth);
    }

   
    /**
     * Defines delta between ticks on the specified axis.
     * @param delta the delta
     */
    public void setTickUnit(AxisEnum axis, double delta) {

        if (m_chart != null) {
            NumberAxis rangeAxis = getAxis(axis);
       
            //  change the auto tick unit selection to integer units only...
            //  rangeAxis.setStandardTickUnits(NumberAxis.createStandardTickUnits());
            rangeAxis.setTickUnit(new NumberTickUnit(delta));
        }
       
        switch (axis) {
        case X:
            m_xTickDelta = delta;
            break;
        case Y:
            m_yTickDelta = delta;
            break;
        }
    }


    private NumberAxis getAxis(AxisEnum axis) {
        XYPlot plot = m_chart.getXYPlot();
        switch (axis) {
        case X:
            return (NumberAxis)plot.getDomainAxis();
        case Y:
            return (NumberAxis)plot.getRangeAxis();
        }
        return null; // should never happen
    }
   

    /**
     * Draws annotation at default angle of 45 degrees.
     *
     * @param x pointer X position
     * @param y pointer Y position
     * @param annotation annotation text
     */
    public void addAnnotation(double x, double y, String annotation) {
        addAnnotation(x, y, annotation, -0.78f);
    }


    /**
     * Draws annotation on the chart.
     *
     * @param x pointer X position
     * @param y pointer Y position
     * @param annotation annotation text
     * @param angle annotation line angle in degrees
     */
    public void addAnnotation(double x, double y, String annotation, float angle) {
        m_xyAnnotation = new XYPointerAnnotation(annotation,
                                                                   x,
                                                                   y,
                                                                   -angle * Math.PI / 180);
        m_xyAnnotation.setLabelOffset(m_xyAnnotation.getLabelOffset() * 2 + 10);

        if (m_chart != null) {
            XYPlot plot = m_chart.getXYPlot();
            plot.addAnnotation(m_xyAnnotation);
        }
    }


    /**
     * Draws annotation at default angle of 45 degrees. Annotation coordinates
     * are given implicitly by specifying data index.
     *
     * @param lineIndex index specifying the line. Indices are assigned to
     * lines in the same order as they were added to chart. Use jPlot.LAST_IDX
     * to refer to the last line added.
     * @param pointIdx index of point on the specified line
     * @param annotation annotation text
     */
    public void addAnnotation(int lineIndex, int pointIdx, String annotation) {
        addAnnotation(lineIndex, pointIdx, annotation, -0.78f);
    }


    /**
     * Draws annotation on the chart.
     *
     * @param lineId id specifying the line. Ids are returned from jplot() and
     * addPlot() methods.
     *
     * @see #addAnnotation(int, int, String)
     */
    public void addAnnotation(String lineId, int pointIdx, String annotation) {
        addAnnotation(getLineIndex(lineId), pointIdx, annotation, -0.78f);
    }


    /**
     * Draws annotation on the chart. Annotation coordinates
     * are given implicitly by specifying data index.
     *
     * @param lineIndex index specifying the line. Indices are assigned to
     * lines in the same order as they were added to chart. Use jPlot.LAST_IDX
     * to refer to the last line added.
     * @param pointIdx index of point on the specified line
     * @param annotation annotation text
     * @param angle annotation line angle in degrees
     */
    public void addAnnotation(int lineIndex, int pointIdx, String annotation, float angle) {
        lineIndex = getLastIndex(lineIndex);
        double x = m_dataset.getXValue(lineIndex, pointIdx);
        double y = m_dataset.getYValue(lineIndex, pointIdx);
        addAnnotation(x, y, annotation, angle);
    }


    /**
     * Draws annotation on the chart.
     *
     * @param lineId id specifying the line. Ids are returned from jplot() and
     * addPlot() methods.
     *
     * @see #addAnnotation(int, int, String, float)
     */
    public void addAnnotation(String lineId,
                              int pointIdx,
                              String annotation,
                              float angle) {
        addAnnotation(getLineIndex(lineId), pointIdx, annotation, angle);
    }
   
   
    /**
     * Sets position of the legend. Legend can currently be placed only on one of
     * the chart edges. 
     * @param position legend position, for example RectangleEdge.BOTTOM
     */
    public void setLegendPosition(RectangleEdge position) {
        if (m_chart != null) {
            LegendTitle legend = m_chart.getLegend();
            legend.setPosition(position);
        } else {
            throw new IllegalStateException("Can not set legend position before " +
                "the chart is drawn. Call jplot() method first!");
        }
    }


    /**
     * Adds marker line to the chart. The default color is red.
     *
     * @param axis axis on which to add the marker.
     * @param position marker position
     */
    public void addMarker(AxisEnum axis, double position) {
        addMarker(axis, position, Color.red, 1, new float[] { 1 });
    }


    /**
     * Adds marker line to the chart.
     *
     * @param axis axis on which to add the marker.
     * @param position marker line position
     * @param paint marker line paint
     */
    public void addMarker(AxisEnum axis, double position, Paint paint) {
        addMarker(axis, position, paint, 1, new float[] { 1 });
    }


    /**
     * Adds marker line to the chart.
     *
     * @param axis axis on which to add the marker.
     * @param position marker position
     * @param paint marker paint
     * @param width marker width
     */
    public void addMarker(AxisEnum axis, double position, Paint paint, int width) {
        addMarker(axis, position, paint, width, new float[] { 1 });
    }


    /**
     * Adds marker line to the chart.
     *
     * @param axis axis on which to add the marker.
     * @param position marker position
     * @param paint marker paint, for example <code>Color.yellow</code>
     * @param width marker width
     * @param style marker style, for example:
     * <cocde>new float[]{2, 5, 8, 5}</code> specifies dot dash line.
     */
    public void addMarker(AxisEnum axis,  double position, Paint paint, int width, float[] style) {

        float dashPhase = 0;
        Stroke stroke = new BasicStroke(width,  BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND, 2, style, dashPhase);

        ValueMarker marker = new ValueMarker(position, paint, stroke);

        switch (axis) {
        case X:
            m_xMarker = marker;
            if (m_chart != null) {
                m_chart.getXYPlot().addDomainMarker(m_xMarker);
            }
            break;
        case Y:
            m_yMarker = marker;
            if (m_chart != null) {
                m_chart.getXYPlot().addRangeMarker(m_yMarker);
            }
            break;
        }
    }


    /**
     * Sets range on the given axis.
     *
     * @param min minimum value shown
     * @param max maximum value shown
     */
    public void setAxisRange(AxisEnum axis, double min, double max) {
        if (m_chart != null) {
            NumberAxis rangeAxis = getAxis(axis);
            rangeAxis.setRange(min, max);
        }
       
        switch (axis) {
        case X:
            m_xAxisRange = new double[]{min, max};
            break;
        case Y:
            m_yAxisRange = new double[]{min, max};
            break;
        }
    }


    /**
     * If hold is set to true, then calls to jplot() method add lines to the
     * chart and keep existing ones. If set to false, calling jplot() method
     * deletes existing lines and adds new ones.
     *  
     * @param isHoldOn new hold status
     */
    public void setHold(boolean isHoldOn) {
        m_isHoldOn = isHoldOn;
    }


    /**
     * Toggles hold status.
     *
     * @return hold status after it is toggled.
     * @see #setHold(boolean)
     */
    public boolean toggleHold() {
        m_isHoldOn = !m_isHoldOn;
        return m_isHoldOn;
    }


    /**
     * Returns current hold status.
     *
     * @see #setHold(boolean)
     */
    public boolean getHold() {
        return m_isHoldOn;
    }
  
   
    /**
     * Adds lines to the chart regardless of hold status.
     *
     * @param x array of X values
     * @param y array of Y values
     * @param lineSpec line specification, see class description for details
     *
     * @return id of line. This id can be used instead of index when calling
     * methods, which take lineId as parameter, for example setLineColor(),
     * setLinestyle(), setLineSpec(), addAnnotation().
     */
    public String addPlot(double []x, double []y, String lineSpec) {
        return addPlot(x, y, lineSpec, "");
    }

    public String addPlot(double []x, double []y, int dummy) {  // use a default line specification
        // dummy parameter is needed for disambiguation of overloaded definition
        // double [] x, double [] y, double []..
        return addPlot(x, y, "c", "") ;
    }
    
    public String addPlot(Vec x, Vec  y, String lineSpec) {
        // dummy parameter is needed for disambiguation of overloaded definition
        // Vec x, Vec y, Vec..
        return addPlot(x.getv(), y.getv(), lineSpec, "");
    }

    public String addPlot(Vec x, Vec  y, int dummy) {
        return addPlot(x.getv(), y.getv(), "");
    }
    /**
     * Adds lines to the chart regardless of hold status.
     *
     * @param x array of X values
     * @param y array of Y values
     * @param lineSpec line specification, see class description for details
     * @param legend text for legend
     *
     * @return id of line. Usually the 'legend' parameter is used as id, unless
     * the line with the same legend already exists in the chart. In such case
     * the legend string is modified. This id can be used instead of index when calling
     * methods, which take lineId as parameter, for example setLineColor(),
     * setLinestyle(), setLineSpec(), addAnnotation().
     */
      public  String addPlot(double x[], double y[], String lineSpec, String legend) {
        if (m_chart != null) {
            String seriesKey = getUniqueSeriesKey(m_dataset, legend);
            m_dataset.addSeries(seriesKey, new double[][] {x, y});
            int lastSeriesIndex = m_dataset.getSeriesCount() - 1;

            LineAttrs lineAtrs = new LineAttrs(lineSpec);
            setLineColor(lastSeriesIndex, lineAtrs.getColor());
            setLineStyle(lastSeriesIndex, lineAtrs.getMarker(), 1, lineAtrs.getStyle());
            return seriesKey;
        }

        return jplot(x, y, lineSpec, legend)[0];
    }

public  String addPlot(Vec x, Vec y, String lineSpec, String legend) {
    return   addPlot(x.getv(), y.getv(), lineSpec, legend);
}
/* public void load(String fileName) throws IOException {
    } */


    /**
     * Saves chart as image in PNG format.
     *
     * @param fileName name of file to save image to
     * @param width image width in pixels
     * @param height image height in pixels
     * @throws IOException if the output file can not be opened for writing
     */
    public void saveAsPNG(String fileName, int width, int height) throws IOException {
        ChartUtilities.saveChartAsPNG(new File(fileName), m_chart, width, height);
    }


    // Returns index of the last line added to the chart
    private int getLastIndex(int index) {
        int maxIdx = m_dataset.getSeriesCount() - 1;
       
        if (index == LAST_IDX  ||  index > maxIdx) {
            index = maxIdx;
        }
       
        return index;
    }
   
   
    private String getUniqueSeriesKey(DefaultXYDataset dataset, String suggestedKey) {
        if (dataset.indexOf(suggestedKey) == -1) {
            return suggestedKey;
        }
        
        suggestedKey += '.';
        return getUniqueSeriesKey(dataset, suggestedKey);
    }
   
   
    private int getLineIndex(String lineId) {
        int id = m_dataset.indexOf(lineId);
        if (id == -1) {
            throw new IllegalStateException("Line with the given id does not exist! " +
                "Id = " + lineId);
        }
        return id;
    }
}
TOP

Related Classes of JFplot.jPlot

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.