Frames | No Frames |
1: /* =========================================================== 2: * JFreeChart : a free chart library for the Java(tm) platform 3: * =========================================================== 4: * 5: * (C) Copyright 2000-2007, by Object Refinery Limited and Contributors. 6: * 7: * Project Info: http://www.jfree.org/jfreechart/index.html 8: * 9: * This library is free software; you can redistribute it and/or modify it 10: * under the terms of the GNU Lesser General Public License as published by 11: * the Free Software Foundation; either version 2.1 of the License, or 12: * (at your option) any later version. 13: * 14: * This library is distributed in the hope that it will be useful, but 15: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 16: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 17: * License for more details. 18: * 19: * You should have received a copy of the GNU Lesser General Public 20: * License along with this library; if not, write to the Free Software 21: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 22: * USA. 23: * 24: * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 25: * in the United States and other countries.] 26: * 27: * ------------------- 28: * XYStepRenderer.java 29: * ------------------- 30: * (C) Copyright 2002-2007, by Roger Studner and Contributors. 31: * 32: * Original Author: Roger Studner; 33: * Contributor(s): David Gilbert (for Object Refinery Limited); 34: * Matthias Rose; 35: * Gerald Struck (fix for bug 1569094); 36: * 37: * $Id: XYStepRenderer.java,v 1.7.2.6 2007/02/06 16:29:11 mungady Exp $ 38: * 39: * Changes 40: * ------- 41: * 13-May-2002 : Version 1, contributed by Roger Studner (DG); 42: * 25-Jun-2002 : Updated import statements (DG); 43: * 22-Jul-2002 : Added check for null data items (DG); 44: * 25-Mar-2003 : Implemented Serializable (DG); 45: * 01-May-2003 : Modified drawItem() method signature (DG); 46: * 20-Aug-2003 : Implemented Cloneable and PublicCloneable (DG); 47: * 16-Sep-2003 : Changed ChartRenderingInfo --> PlotRenderingInfo (DG); 48: * 28-Oct-2003 : Added tooltips, code contributed by Matthias Rose 49: * (RFE 824857) (DG); 50: * 10-Feb-2004 : Removed working line (use line from state object instead) (DG); 51: * 25-Feb-2004 : Replaced CrosshairInfo with CrosshairState. Renamed 52: * XYToolTipGenerator --> XYItemLabelGenerator (DG); 53: * 19-Jan-2005 : Now accesses only primitives from dataset (DG); 54: * 15-Mar-2005 : Fix silly bug in drawItem() method (DG); 55: * 19-Sep-2005 : Extend XYLineAndShapeRenderer (fixes legend shapes), added 56: * support for series visibility, and use getDefaultEntityRadius() 57: * for entity hotspot size (DG); 58: * ------------- JFREECHART 1.0.x --------------------------------------------- 59: * 15-Jun-2006 : Added basic support for item labels (DG); 60: * 11-Oct-2006 : Fixed rendering with horizontal orientation (see bug 1569094), 61: * thanks to Gerald Struck (DG); 62: * 06-Feb-2007 : Fixed bug 1086307, crosshairs with multiple axes (DG); 63: * 64: */ 65: 66: package org.jfree.chart.renderer.xy; 67: 68: import java.awt.Graphics2D; 69: import java.awt.Paint; 70: import java.awt.Shape; 71: import java.awt.Stroke; 72: import java.awt.geom.Line2D; 73: import java.awt.geom.Rectangle2D; 74: import java.io.Serializable; 75: 76: import org.jfree.chart.axis.ValueAxis; 77: import org.jfree.chart.entity.EntityCollection; 78: import org.jfree.chart.entity.XYItemEntity; 79: import org.jfree.chart.labels.XYToolTipGenerator; 80: import org.jfree.chart.plot.CrosshairState; 81: import org.jfree.chart.plot.PlotOrientation; 82: import org.jfree.chart.plot.PlotRenderingInfo; 83: import org.jfree.chart.plot.XYPlot; 84: import org.jfree.chart.urls.XYURLGenerator; 85: import org.jfree.data.xy.XYDataset; 86: import org.jfree.ui.RectangleEdge; 87: import org.jfree.util.PublicCloneable; 88: 89: /** 90: * Line/Step item renderer for an {@link XYPlot}. This class draws lines 91: * between data points, only allowing horizontal or vertical lines (steps). 92: */ 93: public class XYStepRenderer extends XYLineAndShapeRenderer 94: implements XYItemRenderer, 95: Cloneable, 96: PublicCloneable, 97: Serializable { 98: 99: /** For serialization. */ 100: private static final long serialVersionUID = -8918141928884796108L; 101: 102: /** 103: * Constructs a new renderer with no tooltip or URL generation. 104: */ 105: public XYStepRenderer() { 106: this(null, null); 107: } 108: 109: /** 110: * Constructs a new renderer with the specified tool tip and URL 111: * generators. 112: * 113: * @param toolTipGenerator the item label generator (<code>null</code> 114: * permitted). 115: * @param urlGenerator the URL generator (<code>null</code> permitted). 116: */ 117: public XYStepRenderer(XYToolTipGenerator toolTipGenerator, 118: XYURLGenerator urlGenerator) { 119: super(); 120: setBaseToolTipGenerator(toolTipGenerator); 121: setURLGenerator(urlGenerator); 122: setShapesVisible(false); 123: } 124: 125: /** 126: * Draws the visual representation of a single data item. 127: * 128: * @param g2 the graphics device. 129: * @param state the renderer state. 130: * @param dataArea the area within which the data is being drawn. 131: * @param info collects information about the drawing. 132: * @param plot the plot (can be used to obtain standard color 133: * information etc). 134: * @param domainAxis the domain axis. 135: * @param rangeAxis the vertical axis. 136: * @param dataset the dataset. 137: * @param series the series index (zero-based). 138: * @param item the item index (zero-based). 139: * @param crosshairState crosshair information for the plot 140: * (<code>null</code> permitted). 141: * @param pass the pass index (ignored here). 142: */ 143: public void drawItem(Graphics2D g2, 144: XYItemRendererState state, 145: Rectangle2D dataArea, 146: PlotRenderingInfo info, 147: XYPlot plot, 148: ValueAxis domainAxis, 149: ValueAxis rangeAxis, 150: XYDataset dataset, 151: int series, 152: int item, 153: CrosshairState crosshairState, 154: int pass) { 155: 156: // do nothing if item is not visible 157: if (!getItemVisible(series, item)) { 158: return; 159: } 160: 161: PlotOrientation orientation = plot.getOrientation(); 162: 163: Paint seriesPaint = getItemPaint(series, item); 164: Stroke seriesStroke = getItemStroke(series, item); 165: g2.setPaint(seriesPaint); 166: g2.setStroke(seriesStroke); 167: 168: // get the data point... 169: double x1 = dataset.getXValue(series, item); 170: double y1 = dataset.getYValue(series, item); 171: if (Double.isNaN(y1)) { 172: return; 173: } 174: 175: RectangleEdge xAxisLocation = plot.getDomainAxisEdge(); 176: RectangleEdge yAxisLocation = plot.getRangeAxisEdge(); 177: double transX1 = domainAxis.valueToJava2D(x1, dataArea, xAxisLocation); 178: double transY1 = rangeAxis.valueToJava2D(y1, dataArea, yAxisLocation); 179: 180: if (item > 0) { 181: // get the previous data point... 182: double x0 = dataset.getXValue(series, item - 1); 183: double y0 = dataset.getYValue(series, item - 1); 184: if (!Double.isNaN(y0)) { 185: double transX0 = domainAxis.valueToJava2D(x0, dataArea, 186: xAxisLocation); 187: double transY0 = rangeAxis.valueToJava2D(y0, dataArea, 188: yAxisLocation); 189: 190: Line2D line = state.workingLine; 191: if (orientation == PlotOrientation.HORIZONTAL) { 192: if (transY0 == transY1) { //this represents the situation 193: // for drawing a horizontal bar. 194: line.setLine(transY0, transX0, transY1, transX1); 195: g2.draw(line); 196: } 197: else { //this handles the need to perform a 'step'. 198: line.setLine(transY0, transX0, transY0, transX1); 199: g2.draw(line); 200: line.setLine(transY0, transX1, transY1, transX1); 201: g2.draw(line); 202: } 203: } 204: else if (orientation == PlotOrientation.VERTICAL) { 205: if (transY0 == transY1) { // this represents the situation 206: // for drawing a horizontal bar. 207: line.setLine(transX0, transY0, transX1, transY1); 208: g2.draw(line); 209: } 210: else { //this handles the need to perform a 'step'. 211: line.setLine(transX0, transY0, transX1, transY0); 212: g2.draw(line); 213: line.setLine(transX1, transY0, transX1, transY1); 214: g2.draw(line); 215: } 216: } 217: 218: } 219: } 220: 221: // draw the item label if there is one... 222: if (isItemLabelVisible(series, item)) { 223: double xx = transX1; 224: double yy = transY1; 225: if (orientation == PlotOrientation.HORIZONTAL) { 226: xx = transY1; 227: yy = transX1; 228: } 229: drawItemLabel(g2, orientation, dataset, series, item, xx, yy, 230: (y1 < 0.0)); 231: } 232: 233: int domainAxisIndex = plot.getDomainAxisIndex(domainAxis); 234: int rangeAxisIndex = plot.getRangeAxisIndex(rangeAxis); 235: updateCrosshairValues(crosshairState, x1, y1, domainAxisIndex, 236: rangeAxisIndex, transX1, transY1, orientation); 237: 238: // collect entity and tool tip information... 239: if (state.getInfo() != null) { 240: EntityCollection entities = state.getEntityCollection(); 241: if (entities != null) { 242: int r = getDefaultEntityRadius(); 243: Shape shape = orientation == PlotOrientation.VERTICAL 244: ? new Rectangle2D.Double(transX1 - r, transY1 - r, 2 * r, 245: 2 * r) 246: : new Rectangle2D.Double(transY1 - r, transX1 - r, 2 * r, 247: 2 * r); 248: if (shape != null) { 249: String tip = null; 250: XYToolTipGenerator generator 251: = getToolTipGenerator(series, item); 252: if (generator != null) { 253: tip = generator.generateToolTip(dataset, series, item); 254: } 255: String url = null; 256: if (getURLGenerator() != null) { 257: url = getURLGenerator().generateURL(dataset, series, 258: item); 259: } 260: XYItemEntity entity = new XYItemEntity(shape, dataset, 261: series, item, tip, url); 262: entities.add(entity); 263: } 264: } 265: } 266: } 267: 268: /** 269: * Returns a clone of the renderer. 270: * 271: * @return A clone. 272: * 273: * @throws CloneNotSupportedException if the renderer cannot be cloned. 274: */ 275: public Object clone() throws CloneNotSupportedException { 276: return super.clone(); 277: } 278: 279: }