/* * Copyright 2003-2004, Franz-Josef Elmer, All rights reserved * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details * (http://www.gnu.org/copyleft/lesser.html). * * You should have received a copy of the GNU Lesser General Public License * along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package jcckit.plot; import java.util.Vector; import jcckit.data.DataCurve; import jcckit.data.DataEvent; import jcckit.data.DataListener; import jcckit.data.DataPlot; import jcckit.data.DataPoint; import jcckit.graphic.ClippingShape; import jcckit.graphic.GraphPoint; import jcckit.graphic.GraphicalComposite; import jcckit.graphic.GraphicalElement; import jcckit.transformation.Transformation; import jcckit.util.ConfigParameters; import jcckit.util.Factory; /** * A plot is determined by a {@link CoordinateSystem}, {@link Curve Curves}, * an optional annotation layer and an optional {@link Legend}. When rendered * these components are draw in this order. *
* Registrated {@link PlotListener PlotListeners} will be informed * when the plot changes. *
* A {@link DataPlot} can be connected with a Plot instance. * This is done with the method {@link #connect connect()} which registrates * this Plot instance as * a {@link DataListener} at the connected DataPlot. * After an received {@link DataEvent DataEvents} has been handled * the registrated PlotListeners will receive a * {@link PlotEvent} of the type {@link PlotEventType#DATA_PLOT_CHANGED}. * * @author Franz-Josef Elmer */ public class Plot implements DataListener { /** Configuration parameter key. */ public static final String COORDINATE_SYSTEM_KEY = "coordinateSystem", CURVE_FACTORY_KEY = "curveFactory", LEGEND_VISIBLE_KEY = "legendVisible", LEGEND_KEY = "legend", INITIAL_HINT_FOR_NEXT_CURVE_KEY = "initialHintForNextCurve"; private final Vector _plotListeners = new Vector(); private DataPlot _dataPlot; private final CurveFactory _curveFactory; private final Vector _curves = new Vector(); private final Vector _nextCurveHints = new Vector(); private final Hint _initialHintForNextCurve; private final Legend _legend; private final boolean _legendVisibility; private GraphicalElement _coordinateSystemView; private ClippingShape _clippingShape; private Transformation _transformation; private GraphicalElement _annotation; private GraphicalComposite _legendView = new GraphicalComposite(null); /** * Creates an instance from the specified configuration parameters. *
Key & Default Value | Type | Mandatory | *Description |
---|---|---|---|
coordinateSystem = {@link CartesianCoordinateSystem} | *ConfigParameters | no | *Definition of the {@link CoordinateSystem}. |
curveFactory = {@link SimpleCurveFactory} | *ConfigParameters | no | *Definition of the {@link CurveFactory}. |
initialHintForNextCurve = null | *ConfigParameters | no | *Definition of the initial {@link Hint} which is needed by some * {@link SymbolFactory SymbolFactories} like {@link BarFactory}. * |
legend = default values of {@link Legend} | *ConfigParameters | no | *Configuration parameters of a {@link Legend}. |
legendVisible = true | *boolean | no | *If true the {@link Legend} will be created. |
* If this Plot instance is already connected with a * DataPlot the connection will be released and a * {@link PlotEvent} of the type {@link PlotEventType#DATA_PLOT_DISCONNECTED} * will be sent to all registrated {@link PlotListener PlotListeners}. *
* It registers itself at dataPlot and * all its {@link DataCurve DataCurves}. *
* Finally all curves will be generated and a PlotEvent * of the type {@link PlotEventType#DATA_PLOT_CONNECTED} will be transmitted. * @param dataPlot Data to be connected with this plot instance. * Can be null in order to disconnect this instance from * any DataPlot. */ public void connect(DataPlot dataPlot) { if (_dataPlot != null) { _dataPlot.removeDataListener(this); notifyListeners(new PlotEvent(this, PlotEventType.DATA_PLOT_DISCONNECTED, _dataPlot)); } _dataPlot = dataPlot; if (_dataPlot != null) { _dataPlot.addDataListener(this); generateCurves(_dataPlot); notifyListeners(new PlotEvent(this, PlotEventType.DATA_PLOT_CONNECTED, _dataPlot)); } } /** * Transforms a point from device-independent coordinates into * data coordinates. * @param point Point in device-independent coordinates. * @return transform point. */ public DataPoint transform(GraphPoint point) { return _transformation.transformToData(point); } /** * Creates a graphical representation of the complete plot. * @return GraphicalComposite containing the views of the * coordinate system, the curves, and optionally the legend (in this order). */ public GraphicalComposite getCompletePlot() { GraphicalComposite result = new GraphicalComposite(null); result.addElement(_coordinateSystemView); GraphicalElement[] curves = getCurves(); for (int i = 0; i < curves.length; i++) { result.addElement(curves[i]); } if (_annotation != null) { result.addElement(_annotation); } if (_legendVisibility) { result.addElement(getLegend()); } return result; } /** Returns the view of the coordinate system. */ public GraphicalElement getCoordinateSystem() { return _coordinateSystemView; } /** Returns the graphical representations of all curves. */ public GraphicalElement[] getCurves() { synchronized (_curves) { GraphicalElement[] curves = new GraphicalElement[_curves.size()]; for (int i = 0; i < curves.length; i++) { curves[i] = ((Curve) _curves.elementAt(i)).getView(); } return curves; } } /** * Returns the annotation layer. * @return null if no annotation layer. */ public GraphicalElement getAnnotation() { return _annotation; } /** * Sets the annotation layer. * @param annotation Any kind of graphics which will be drawn on the * top of the curves but may be covered by the legend. * Can be null. */ public void setAnnotation(GraphicalElement annotation) { _annotation = annotation; } /** Returns true if the legend is visible. */ public boolean isLegendVisible() { return _legendVisibility; } /** Returns the graphical representations of the legend. */ public GraphicalElement getLegend() { return _legendView; } /** * Handles the received {@link DataEvent} and notifies * {@link PlotListener PlotListeners} by an event of the type * {@link PlotEventType#DATA_CURVE_CHANGED} or * {@link PlotEventType#DATA_PLOT_CHANGED}. The following table shows what * this method does: *
Source of event | *All hints for the next curve are null? | *Action | Type of sent {@link PlotEvent} | |
---|---|---|---|---|
{@link DataCurve} | Yes | Recreate changed curve. | * | DATA_CURVE_CHANGED |
{@link DataCurve} | No | Recreate changed curve * and all curves with large curve index. | * | DATA_PLOT_CHANGED |
{@link DataPlot} | - | Recreate all curves * and {@link Legend} view. | * | DATA_PLOT_CHANGED |