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 }