001: /* ===========================================================
002: * JFreeChart : a free chart library for the Java(tm) platform
003: * ===========================================================
004: *
005: * (C) Copyright 2000-2007, by Object Refinery Limited and Contributors.
006: *
007: * Project Info: http://www.jfree.org/jfreechart/index.html
008: *
009: * This library is free software; you can redistribute it and/or modify it
010: * under the terms of the GNU Lesser General Public License as published by
011: * the Free Software Foundation; either version 2.1 of the License, or
012: * (at your option) any later version.
013: *
014: * This library is distributed in the hope that it will be useful, but
015: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
016: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
017: * License for more details.
018: *
019: * You should have received a copy of the GNU Lesser General Public
020: * License along with this library; if not, write to the Free Software
021: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
022: * USA.
023: *
024: * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
025: * in the United States and other countries.]
026: *
027: * -------------------
028: * XYStepRenderer.java
029: * -------------------
030: * (C) Copyright 2002-2007, by Roger Studner and Contributors.
031: *
032: * Original Author: Roger Studner;
033: * Contributor(s): David Gilbert (for Object Refinery Limited);
034: * Matthias Rose;
035: * Gerald Struck (fix for bug 1569094);
036: *
037: * $Id: XYStepRenderer.java,v 1.7.2.6 2007/02/06 16:29:11 mungady Exp $
038: *
039: * Changes
040: * -------
041: * 13-May-2002 : Version 1, contributed by Roger Studner (DG);
042: * 25-Jun-2002 : Updated import statements (DG);
043: * 22-Jul-2002 : Added check for null data items (DG);
044: * 25-Mar-2003 : Implemented Serializable (DG);
045: * 01-May-2003 : Modified drawItem() method signature (DG);
046: * 20-Aug-2003 : Implemented Cloneable and PublicCloneable (DG);
047: * 16-Sep-2003 : Changed ChartRenderingInfo --> PlotRenderingInfo (DG);
048: * 28-Oct-2003 : Added tooltips, code contributed by Matthias Rose
049: * (RFE 824857) (DG);
050: * 10-Feb-2004 : Removed working line (use line from state object instead) (DG);
051: * 25-Feb-2004 : Replaced CrosshairInfo with CrosshairState. Renamed
052: * XYToolTipGenerator --> XYItemLabelGenerator (DG);
053: * 19-Jan-2005 : Now accesses only primitives from dataset (DG);
054: * 15-Mar-2005 : Fix silly bug in drawItem() method (DG);
055: * 19-Sep-2005 : Extend XYLineAndShapeRenderer (fixes legend shapes), added
056: * support for series visibility, and use getDefaultEntityRadius()
057: * for entity hotspot size (DG);
058: * ------------- JFREECHART 1.0.x ---------------------------------------------
059: * 15-Jun-2006 : Added basic support for item labels (DG);
060: * 11-Oct-2006 : Fixed rendering with horizontal orientation (see bug 1569094),
061: * thanks to Gerald Struck (DG);
062: * 06-Feb-2007 : Fixed bug 1086307, crosshairs with multiple axes (DG);
063: *
064: */
065:
066: package org.jfree.chart.renderer.xy;
067:
068: import java.awt.Graphics2D;
069: import java.awt.Paint;
070: import java.awt.Shape;
071: import java.awt.Stroke;
072: import java.awt.geom.Line2D;
073: import java.awt.geom.Rectangle2D;
074: import java.io.Serializable;
075:
076: import org.jfree.chart.axis.ValueAxis;
077: import org.jfree.chart.entity.EntityCollection;
078: import org.jfree.chart.entity.XYItemEntity;
079: import org.jfree.chart.labels.XYToolTipGenerator;
080: import org.jfree.chart.plot.CrosshairState;
081: import org.jfree.chart.plot.PlotOrientation;
082: import org.jfree.chart.plot.PlotRenderingInfo;
083: import org.jfree.chart.plot.XYPlot;
084: import org.jfree.chart.urls.XYURLGenerator;
085: import org.jfree.data.xy.XYDataset;
086: import org.jfree.ui.RectangleEdge;
087: import org.jfree.util.PublicCloneable;
088:
089: /**
090: * Line/Step item renderer for an {@link XYPlot}. This class draws lines
091: * between data points, only allowing horizontal or vertical lines (steps).
092: */
093: public class XYStepRenderer extends XYLineAndShapeRenderer implements
094: XYItemRenderer, Cloneable, PublicCloneable, Serializable {
095:
096: /** For serialization. */
097: private static final long serialVersionUID = -8918141928884796108L;
098:
099: /**
100: * Constructs a new renderer with no tooltip or URL generation.
101: */
102: public XYStepRenderer() {
103: this (null, null);
104: }
105:
106: /**
107: * Constructs a new renderer with the specified tool tip and URL
108: * generators.
109: *
110: * @param toolTipGenerator the item label generator (<code>null</code>
111: * permitted).
112: * @param urlGenerator the URL generator (<code>null</code> permitted).
113: */
114: public XYStepRenderer(XYToolTipGenerator toolTipGenerator,
115: XYURLGenerator urlGenerator) {
116: super ();
117: setBaseToolTipGenerator(toolTipGenerator);
118: setURLGenerator(urlGenerator);
119: setShapesVisible(false);
120: }
121:
122: /**
123: * Draws the visual representation of a single data item.
124: *
125: * @param g2 the graphics device.
126: * @param state the renderer state.
127: * @param dataArea the area within which the data is being drawn.
128: * @param info collects information about the drawing.
129: * @param plot the plot (can be used to obtain standard color
130: * information etc).
131: * @param domainAxis the domain axis.
132: * @param rangeAxis the vertical axis.
133: * @param dataset the dataset.
134: * @param series the series index (zero-based).
135: * @param item the item index (zero-based).
136: * @param crosshairState crosshair information for the plot
137: * (<code>null</code> permitted).
138: * @param pass the pass index (ignored here).
139: */
140: public void drawItem(Graphics2D g2, XYItemRendererState state,
141: Rectangle2D dataArea, PlotRenderingInfo info, XYPlot plot,
142: ValueAxis domainAxis, ValueAxis rangeAxis,
143: XYDataset dataset, int series, int item,
144: CrosshairState crosshairState, int pass) {
145:
146: // do nothing if item is not visible
147: if (!getItemVisible(series, item)) {
148: return;
149: }
150:
151: PlotOrientation orientation = plot.getOrientation();
152:
153: Paint seriesPaint = getItemPaint(series, item);
154: Stroke seriesStroke = getItemStroke(series, item);
155: g2.setPaint(seriesPaint);
156: g2.setStroke(seriesStroke);
157:
158: // get the data point...
159: double x1 = dataset.getXValue(series, item);
160: double y1 = dataset.getYValue(series, item);
161: if (Double.isNaN(y1)) {
162: return;
163: }
164:
165: RectangleEdge xAxisLocation = plot.getDomainAxisEdge();
166: RectangleEdge yAxisLocation = plot.getRangeAxisEdge();
167: double transX1 = domainAxis.valueToJava2D(x1, dataArea,
168: xAxisLocation);
169: double transY1 = rangeAxis.valueToJava2D(y1, dataArea,
170: yAxisLocation);
171:
172: if (item > 0) {
173: // get the previous data point...
174: double x0 = dataset.getXValue(series, item - 1);
175: double y0 = dataset.getYValue(series, item - 1);
176: if (!Double.isNaN(y0)) {
177: double transX0 = domainAxis.valueToJava2D(x0, dataArea,
178: xAxisLocation);
179: double transY0 = rangeAxis.valueToJava2D(y0, dataArea,
180: yAxisLocation);
181:
182: Line2D line = state.workingLine;
183: if (orientation == PlotOrientation.HORIZONTAL) {
184: if (transY0 == transY1) { //this represents the situation
185: // for drawing a horizontal bar.
186: line
187: .setLine(transY0, transX0, transY1,
188: transX1);
189: g2.draw(line);
190: } else { //this handles the need to perform a 'step'.
191: line
192: .setLine(transY0, transX0, transY0,
193: transX1);
194: g2.draw(line);
195: line
196: .setLine(transY0, transX1, transY1,
197: transX1);
198: g2.draw(line);
199: }
200: } else if (orientation == PlotOrientation.VERTICAL) {
201: if (transY0 == transY1) { // this represents the situation
202: // for drawing a horizontal bar.
203: line
204: .setLine(transX0, transY0, transX1,
205: transY1);
206: g2.draw(line);
207: } else { //this handles the need to perform a 'step'.
208: line
209: .setLine(transX0, transY0, transX1,
210: transY0);
211: g2.draw(line);
212: line
213: .setLine(transX1, transY0, transX1,
214: transY1);
215: g2.draw(line);
216: }
217: }
218:
219: }
220: }
221:
222: // draw the item label if there is one...
223: if (isItemLabelVisible(series, item)) {
224: double xx = transX1;
225: double yy = transY1;
226: if (orientation == PlotOrientation.HORIZONTAL) {
227: xx = transY1;
228: yy = transX1;
229: }
230: drawItemLabel(g2, orientation, dataset, series, item, xx,
231: yy, (y1 < 0.0));
232: }
233:
234: int domainAxisIndex = plot.getDomainAxisIndex(domainAxis);
235: int rangeAxisIndex = plot.getRangeAxisIndex(rangeAxis);
236: updateCrosshairValues(crosshairState, x1, y1, domainAxisIndex,
237: rangeAxisIndex, transX1, transY1, orientation);
238:
239: // collect entity and tool tip information...
240: if (state.getInfo() != null) {
241: EntityCollection entities = state.getEntityCollection();
242: if (entities != null) {
243: int r = getDefaultEntityRadius();
244: Shape shape = orientation == PlotOrientation.VERTICAL ? new Rectangle2D.Double(
245: transX1 - r, transY1 - r, 2 * r, 2 * r)
246: : new Rectangle2D.Double(transY1 - r, transX1
247: - r, 2 * r, 2 * r);
248: if (shape != null) {
249: String tip = null;
250: XYToolTipGenerator generator = getToolTipGenerator(
251: series, item);
252: if (generator != null) {
253: tip = generator.generateToolTip(dataset,
254: series, item);
255: }
256: String url = null;
257: if (getURLGenerator() != null) {
258: url = getURLGenerator().generateURL(dataset,
259: series, item);
260: }
261: XYItemEntity entity = new XYItemEntity(shape,
262: dataset, series, item, tip, url);
263: entities.add(entity);
264: }
265: }
266: }
267: }
268:
269: /**
270: * Returns a clone of the renderer.
271: *
272: * @return A clone.
273: *
274: * @throws CloneNotSupportedException if the renderer cannot be cloned.
275: */
276: public Object clone() throws CloneNotSupportedException {
277: return super.clone();
278: }
279:
280: }
|