001/* =========================================================== 002 * JFreeChart : a free chart library for the Java(tm) platform 003 * =========================================================== 004 * 005 * (C) Copyright 2000-2011, 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 * [Oracle and Java are registered trademarks of Oracle and/or its affiliates. 025 * Other names may be trademarks of their respective owners.] 026 * 027 * ------------------------ 028 * IntervalBarRenderer.java 029 * ------------------------ 030 * (C) Copyright 2002-2011, by Jeremy Bowman. 031 * 032 * Original Author: Jeremy Bowman; 033 * Contributor(s): David Gilbert (for Object Refinery Limited); 034 * Christian W. Zuckschwerdt; 035 * Peter Kolb (patch 2497611, 2791407); 036 * 037 * Changes 038 * ------- 039 * 29-Apr-2002 : Version 1, contributed by Jeremy Bowman (DG); 040 * 11-May-2002 : Use CategoryPlot.getLabelsVisible() (JB); 041 * 29-May-2002 : Added constructors (DG); 042 * 26-Jun-2002 : Added axis to initialise method (DG); 043 * 20-Sep-2002 : Added basic support for chart entities (DG); 044 * 24-Oct-2002 : Amendments for changes in CategoryDataset interface and 045 * CategoryToolTipGenerator interface (DG); 046 * 05-Nov-2002 : Base dataset is now TableDataset not CategoryDataset (DG); 047 * 25-Mar-2003 : Implemented Serializable (DG); 048 * 30-Jul-2003 : Modified entity constructor (CZ); 049 * 19-Aug-2003 : Implemented Cloneable and PublicCloneable (DG); 050 * 08-Sep-2003 : Added checks for null values (DG); 051 * 07-Oct-2003 : Added renderer state (DG); 052 * 21-Oct-2003 : Bar width moved into renderer state (DG); 053 * 23-Dec-2003 : Removed the deprecated MultiIntervalCategoryDataset 054 * interface (DG); 055 * 05-Nov-2004 : Modified drawItem() signature (DG); 056 * 20-Apr-2005 : Renamed CategoryLabelGenerator 057 * --> CategoryItemLabelGenerator (DG); 058 * 02-Feb-2007 : Removed author tags all over JFreeChart sources (DG); 059 * 24-Jun-2008 : Added new barPainter mechanism (DG); 060 * 07-Oct-2008 : Override equals() method to fix minor bug (DG); 061 * 14-Jan-2009 : Added support for seriesVisible flags (PK); 062 * 16-May-2009 : The findRangeBounds() method needs to include the dataset 063 * interval (DG); 064 * 19-May-2009 : Fixed FindBugs warnings, patch by Michal Wozniak (DG); 065 * 30-Oct-2011 : Fixed alignment when setMaximumBarWidth is applied (DG); 066 */ 067 068package org.jfree.chart.renderer.category; 069 070import java.awt.Graphics2D; 071import java.awt.geom.Rectangle2D; 072 073import org.jfree.chart.axis.CategoryAxis; 074import org.jfree.chart.axis.ValueAxis; 075import org.jfree.chart.entity.EntityCollection; 076import org.jfree.chart.labels.CategoryItemLabelGenerator; 077import org.jfree.chart.plot.CategoryPlot; 078import org.jfree.chart.plot.PlotOrientation; 079import org.jfree.data.Range; 080import org.jfree.data.category.CategoryDataset; 081import org.jfree.data.category.IntervalCategoryDataset; 082import org.jfree.ui.RectangleEdge; 083 084/** 085 * A renderer that handles the drawing of bars for a bar plot where 086 * each bar has a high and low value. This renderer is for use with the 087 * {@link CategoryPlot} class. The example shown here is generated by the 088 * <code>IntervalBarChartDemo1.java</code> program included in the JFreeChart 089 * Demo Collection: 090 * <br><br> 091 * <img src="../../../../../images/IntervalBarRendererSample.png" 092 * alt="IntervalBarRendererSample.png" /> 093 */ 094public class IntervalBarRenderer extends BarRenderer { 095 096 /** For serialization. */ 097 private static final long serialVersionUID = -5068857361615528725L; 098 099 /** 100 * Constructs a new renderer. 101 */ 102 public IntervalBarRenderer() { 103 super(); 104 } 105 106 /** 107 * Returns the range of values from the specified dataset. For this 108 * renderer, this is equivalent to calling 109 * <code>findRangeBounds(dataset, true)</code>. 110 * 111 * @param dataset the dataset (<code>null</code> permitted). 112 * 113 * @return The range (or <code>null</code> if the dataset is 114 * <code>null</code> or empty). 115 */ 116 public Range findRangeBounds(CategoryDataset dataset) { 117 return findRangeBounds(dataset, true); 118 } 119 120 /** 121 * Draws the bar for a single (series, category) data item. 122 * 123 * @param g2 the graphics device. 124 * @param state the renderer state. 125 * @param dataArea the data area. 126 * @param plot the plot. 127 * @param domainAxis the domain axis. 128 * @param rangeAxis the range axis. 129 * @param dataset the dataset. 130 * @param row the row index (zero-based). 131 * @param column the column index (zero-based). 132 * @param pass the pass index. 133 */ 134 public void drawItem(Graphics2D g2, 135 CategoryItemRendererState state, 136 Rectangle2D dataArea, 137 CategoryPlot plot, 138 CategoryAxis domainAxis, 139 ValueAxis rangeAxis, 140 CategoryDataset dataset, 141 int row, 142 int column, 143 int pass) { 144 145 if (dataset instanceof IntervalCategoryDataset) { 146 IntervalCategoryDataset d = (IntervalCategoryDataset) dataset; 147 drawInterval(g2, state, dataArea, plot, domainAxis, rangeAxis, 148 d, row, column); 149 } 150 else { 151 super.drawItem(g2, state, dataArea, plot, domainAxis, rangeAxis, 152 dataset, row, column, pass); 153 } 154 155 } 156 157 /** 158 * Draws a single interval. 159 * 160 * @param g2 the graphics device. 161 * @param state the renderer state. 162 * @param dataArea the data plot area. 163 * @param plot the plot. 164 * @param domainAxis the domain axis. 165 * @param rangeAxis the range axis. 166 * @param dataset the data. 167 * @param row the row index (zero-based). 168 * @param column the column index (zero-based). 169 */ 170 protected void drawInterval(Graphics2D g2, 171 CategoryItemRendererState state, 172 Rectangle2D dataArea, 173 CategoryPlot plot, 174 CategoryAxis domainAxis, 175 ValueAxis rangeAxis, 176 IntervalCategoryDataset dataset, 177 int row, 178 int column) { 179 180 int visibleRow = state.getVisibleSeriesIndex(row); 181 if (visibleRow < 0) { 182 return; 183 } 184 185 PlotOrientation orientation = plot.getOrientation(); 186 double rectX = 0.0; 187 double rectY = 0.0; 188 189 RectangleEdge rangeAxisLocation = plot.getRangeAxisEdge(); 190 191 // Y0 192 Number value0 = dataset.getEndValue(row, column); 193 if (value0 == null) { 194 return; 195 } 196 double java2dValue0 = rangeAxis.valueToJava2D(value0.doubleValue(), 197 dataArea, rangeAxisLocation); 198 199 // Y1 200 Number value1 = dataset.getStartValue(row, column); 201 if (value1 == null) { 202 return; 203 } 204 double java2dValue1 = rangeAxis.valueToJava2D( 205 value1.doubleValue(), dataArea, rangeAxisLocation); 206 207 if (java2dValue1 < java2dValue0) { 208 double temp = java2dValue1; 209 java2dValue1 = java2dValue0; 210 java2dValue0 = temp; 211 } 212 213 // BAR WIDTH 214 double rectWidth = state.getBarWidth(); 215 216 // BAR HEIGHT 217 double rectHeight = Math.abs(java2dValue1 - java2dValue0); 218 219 RectangleEdge barBase = RectangleEdge.LEFT; 220 if (orientation == PlotOrientation.HORIZONTAL) { 221 // BAR Y 222 rectX = java2dValue0; 223 rectY = calculateBarW0(getPlot(), orientation, dataArea, 224 domainAxis, state, visibleRow, column); 225 rectHeight = state.getBarWidth(); 226 rectWidth = Math.abs(java2dValue1 - java2dValue0); 227 barBase = RectangleEdge.LEFT; 228 } 229 else if (orientation == PlotOrientation.VERTICAL) { 230 // BAR X 231 rectX = calculateBarW0(getPlot(), orientation, dataArea, 232 domainAxis, state, visibleRow, column); 233 rectY = java2dValue0; 234 barBase = RectangleEdge.BOTTOM; 235 } 236 Rectangle2D bar = new Rectangle2D.Double(rectX, rectY, rectWidth, 237 rectHeight); 238 BarPainter painter = getBarPainter(); 239 if (getShadowsVisible()) { 240 painter.paintBarShadow(g2, this, row, column, bar, barBase, false); 241 } 242 getBarPainter().paintBar(g2, this, row, column, bar, barBase); 243 244 CategoryItemLabelGenerator generator = getItemLabelGenerator(row, 245 column); 246 if (generator != null && isItemLabelVisible(row, column)) { 247 drawItemLabel(g2, dataset, row, column, plot, generator, bar, 248 false); 249 } 250 251 // add an item entity, if this information is being collected 252 EntityCollection entities = state.getEntityCollection(); 253 if (entities != null) { 254 addItemEntity(entities, dataset, row, column, bar); 255 } 256 257 } 258 259 /** 260 * Tests this renderer for equality with an arbitrary object. 261 * 262 * @param obj the object (<code>null</code> permitted). 263 * 264 * @return A boolean. 265 */ 266 public boolean equals(Object obj) { 267 if (obj == this) { 268 return true; 269 } 270 if (!(obj instanceof IntervalBarRenderer)) { 271 return false; 272 } 273 // there are no fields to check 274 return super.equals(obj); 275 } 276 277}