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