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