001/* =========================================================== 002 * JFreeChart : a free chart library for the Java(tm) platform 003 * =========================================================== 004 * 005 * (C) Copyright 2000-present, by David Gilbert 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-present, by Jeremy Bowman and Contributors. 031 * 032 * Original Author: Jeremy Bowman; 033 * Contributor(s): David Gilbert; 034 * Christian W. Zuckschwerdt; 035 * Peter Kolb (patch 2497611, 2791407); 036 * 037 */ 038 039package org.jfree.chart.renderer.category; 040 041import java.awt.Graphics2D; 042import java.awt.geom.Rectangle2D; 043 044import org.jfree.chart.axis.CategoryAxis; 045import org.jfree.chart.axis.ValueAxis; 046import org.jfree.chart.entity.EntityCollection; 047import org.jfree.chart.labels.CategoryItemLabelGenerator; 048import org.jfree.chart.plot.CategoryPlot; 049import org.jfree.chart.plot.PlotOrientation; 050import org.jfree.chart.ui.RectangleEdge; 051import org.jfree.data.Range; 052import org.jfree.data.category.CategoryDataset; 053import org.jfree.data.category.IntervalCategoryDataset; 054 055/** 056 * A renderer that handles the drawing of bars for a bar plot where 057 * each bar has a high and low value. This renderer is for use with the 058 * {@link CategoryPlot} class. The example shown here is generated by the 059 * {@code IntervalBarChartDemo1.java} program included in the JFreeChart 060 * Demo Collection: 061 * <br><br> 062 * <img src="doc-files/IntervalBarRendererSample.png" 063 * alt="IntervalBarRendererSample.png"> 064 */ 065public class IntervalBarRenderer extends BarRenderer { 066 067 /** For serialization. */ 068 private static final long serialVersionUID = -5068857361615528725L; 069 070 /** 071 * Constructs a new renderer. 072 */ 073 public IntervalBarRenderer() { 074 super(); 075 } 076 077 /** 078 * Returns the range of values from the specified dataset. For this 079 * renderer, this is equivalent to calling 080 * {@code findRangeBounds(dataset, true)}. 081 * 082 * @param dataset the dataset ({@code null} permitted). 083 * 084 * @return The range (or {@code null} if the dataset is 085 * {@code null} or empty). 086 */ 087 @Override 088 public Range findRangeBounds(CategoryDataset dataset) { 089 return findRangeBounds(dataset, true); 090 } 091 092 /** 093 * Draws the bar for a single (series, category) data item. 094 * 095 * @param g2 the graphics device. 096 * @param state the renderer state. 097 * @param dataArea the data area. 098 * @param plot the plot. 099 * @param domainAxis the domain axis. 100 * @param rangeAxis the range axis. 101 * @param dataset the dataset. 102 * @param row the row index (zero-based). 103 * @param column the column index (zero-based). 104 * @param pass the pass index. 105 */ 106 @Override 107 public void drawItem(Graphics2D g2, CategoryItemRendererState state, 108 Rectangle2D dataArea, CategoryPlot plot, CategoryAxis domainAxis, 109 ValueAxis rangeAxis, CategoryDataset dataset, int row, int column, 110 int pass) { 111 112 if (dataset instanceof IntervalCategoryDataset) { 113 IntervalCategoryDataset d = (IntervalCategoryDataset) dataset; 114 drawInterval(g2, state, dataArea, plot, domainAxis, rangeAxis, 115 d, row, column); 116 } else { 117 super.drawItem(g2, state, dataArea, plot, domainAxis, rangeAxis, 118 dataset, row, column, pass); 119 } 120 121 } 122 123 /** 124 * Draws a single interval. 125 * 126 * @param g2 the graphics device. 127 * @param state the renderer state. 128 * @param dataArea the data plot area. 129 * @param plot the plot. 130 * @param domainAxis the domain axis. 131 * @param rangeAxis the range axis. 132 * @param dataset the data. 133 * @param row the row index (zero-based). 134 * @param column the column index (zero-based). 135 */ 136 protected void drawInterval(Graphics2D g2, CategoryItemRendererState state, 137 Rectangle2D dataArea, CategoryPlot plot, CategoryAxis domainAxis, 138 ValueAxis rangeAxis, IntervalCategoryDataset dataset, int row, 139 int column) { 140 141 int visibleRow = state.getVisibleSeriesIndex(row); 142 if (visibleRow < 0) { 143 return; 144 } 145 146 PlotOrientation orientation = plot.getOrientation(); 147 double rectX = 0.0; 148 double rectY = 0.0; 149 150 RectangleEdge rangeAxisLocation = plot.getRangeAxisEdge(); 151 152 // Y0 153 Number value0 = dataset.getEndValue(row, column); 154 if (value0 == null) { 155 return; 156 } 157 double java2dValue0 = rangeAxis.valueToJava2D(value0.doubleValue(), 158 dataArea, rangeAxisLocation); 159 160 // Y1 161 Number value1 = dataset.getStartValue(row, column); 162 if (value1 == null) { 163 return; 164 } 165 double java2dValue1 = rangeAxis.valueToJava2D( 166 value1.doubleValue(), dataArea, rangeAxisLocation); 167 168 if (java2dValue1 < java2dValue0) { 169 double temp = java2dValue1; 170 java2dValue1 = java2dValue0; 171 java2dValue0 = temp; 172 } 173 174 // BAR WIDTH 175 double rectWidth = state.getBarWidth(); 176 177 // BAR HEIGHT 178 double rectHeight = Math.abs(java2dValue1 - java2dValue0); 179 180 RectangleEdge barBase = RectangleEdge.LEFT; 181 if (orientation == PlotOrientation.HORIZONTAL) { 182 // BAR Y 183 rectX = java2dValue0; 184 rectY = calculateBarW0(getPlot(), orientation, dataArea, 185 domainAxis, state, visibleRow, column); 186 rectHeight = state.getBarWidth(); 187 rectWidth = Math.abs(java2dValue1 - java2dValue0); 188 barBase = RectangleEdge.LEFT; 189 } else if (orientation.isVertical()) { 190 // BAR X 191 rectX = calculateBarW0(getPlot(), orientation, dataArea, 192 domainAxis, state, visibleRow, column); 193 rectY = java2dValue0; 194 barBase = RectangleEdge.BOTTOM; 195 } 196 Rectangle2D bar = new Rectangle2D.Double(rectX, rectY, rectWidth, 197 rectHeight); 198 BarPainter painter = getBarPainter(); 199 if (state.getElementHinting()) { 200 beginElementGroup(g2, dataset.getRowKey(row), 201 dataset.getColumnKey(column)); 202 } 203 if (getShadowsVisible()) { 204 painter.paintBarShadow(g2, this, row, column, bar, barBase, false); 205 } 206 getBarPainter().paintBar(g2, this, row, column, bar, barBase); 207 if (state.getElementHinting()) { 208 endElementGroup(g2); 209 } 210 211 CategoryItemLabelGenerator generator = getItemLabelGenerator(row, 212 column); 213 if (generator != null && isItemLabelVisible(row, column)) { 214 drawItemLabel(g2, dataset, row, column, plot, generator, bar, 215 false); 216 } 217 218 // add an item entity, if this information is being collected 219 EntityCollection entities = state.getEntityCollection(); 220 if (entities != null) { 221 addItemEntity(entities, dataset, row, column, bar); 222 } 223 224 } 225 226 /** 227 * Tests this renderer for equality with an arbitrary object. 228 * 229 * @param obj the object ({@code null} permitted). 230 * 231 * @return A boolean. 232 */ 233 @Override 234 public boolean equals(Object obj) { 235 if (obj == this) { 236 return true; 237 } 238 if (!(obj instanceof IntervalBarRenderer)) { 239 return false; 240 } 241 // there are no fields to check 242 return super.equals(obj); 243 } 244 245}