Source for org.jfree.chart.renderer.category.IntervalBarRenderer

   1: /* ===========================================================
   2:  * JFreeChart : a free chart library for the Java(tm) platform
   3:  * ===========================================================
   4:  *
   5:  * (C) Copyright 2000-2007, 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:  * IntervalBarRenderer.java
  29:  * ------------------------
  30:  * (C) Copyright 2002-2007, by Jeremy Bowman.
  31:  *
  32:  * Original Author:  Jeremy Bowman;
  33:  * Contributor(s):   David Gilbert (for Object Refinery Limited);
  34:  *                   Christian W. Zuckschwerdt;
  35:  *
  36:  * $Id: IntervalBarRenderer.java,v 1.6.2.3 2007/02/02 15:52:07 mungady Exp $
  37:  *
  38:  * Changes
  39:  * -------
  40:  * 29-Apr-2002 : Version 1, contributed by Jeremy Bowman (DG);
  41:  * 11-May-2002 : Use CategoryPlot.getLabelsVisible() (JB);
  42:  * 29-May-2002 : Added constructors (DG);
  43:  * 26-Jun-2002 : Added axis to initialise method (DG);
  44:  * 20-Sep-2002 : Added basic support for chart entities (DG);
  45:  * 24-Oct-2002 : Amendments for changes in CategoryDataset interface and 
  46:  *               CategoryToolTipGenerator interface (DG);
  47:  * 05-Nov-2002 : Base dataset is now TableDataset not CategoryDataset (DG);
  48:  * 25-Mar-2003 : Implemented Serializable (DG);
  49:  * 30-Jul-2003 : Modified entity constructor (CZ);
  50:  * 19-Aug-2003 : Implemented Cloneable and PublicCloneable (DG);
  51:  * 08-Sep-2003 : Added checks for null values (DG);
  52:  * 07-Oct-2003 : Added renderer state (DG);
  53:  * 21-Oct-2003 : Bar width moved into renderer state (DG);
  54:  * 23-Dec-2003 : Removed the deprecated MultiIntervalCategoryDataset 
  55:  *               interface (DG);
  56:  * 05-Nov-2004 : Modified drawItem() signature (DG);
  57:  * 20-Apr-2005 : Renamed CategoryLabelGenerator 
  58:  *               --> CategoryItemLabelGenerator (DG);
  59:  * 02-Feb-2007 : Removed author tags all over JFreeChart sources (DG);
  60:  * 
  61:  */
  62: 
  63: package org.jfree.chart.renderer.category;
  64: 
  65: import java.awt.Graphics2D;
  66: import java.awt.Paint;
  67: import java.awt.Stroke;
  68: import java.awt.geom.Rectangle2D;
  69: import java.io.Serializable;
  70: 
  71: import org.jfree.chart.axis.CategoryAxis;
  72: import org.jfree.chart.axis.ValueAxis;
  73: import org.jfree.chart.entity.CategoryItemEntity;
  74: import org.jfree.chart.entity.EntityCollection;
  75: import org.jfree.chart.labels.CategoryItemLabelGenerator;
  76: import org.jfree.chart.labels.CategoryToolTipGenerator;
  77: import org.jfree.chart.plot.CategoryPlot;
  78: import org.jfree.chart.plot.PlotOrientation;
  79: import org.jfree.data.category.CategoryDataset;
  80: import org.jfree.data.category.IntervalCategoryDataset;
  81: import org.jfree.ui.RectangleEdge;
  82: import org.jfree.util.PublicCloneable;
  83: 
  84: /**
  85:  * A renderer that handles the drawing of bars for a bar plot where
  86:  * each bar has a high and low value.
  87:  * <p>
  88:  * For use with the {@link CategoryPlot} class.
  89:  */
  90: public class IntervalBarRenderer extends BarRenderer
  91:                                  implements CategoryItemRenderer, 
  92:                                             Cloneable, 
  93:                                             PublicCloneable, 
  94:                                             Serializable {
  95: 
  96:     /** For serialization. */
  97:     private static final long serialVersionUID = -5068857361615528725L;
  98:     
  99:     /**
 100:      * Constructs a new renderer.
 101:      */
 102:     public IntervalBarRenderer() {
 103:         super();
 104:     }
 105: 
 106:     /**
 107:      * Draws the bar for a single (series, category) data item.
 108:      *
 109:      * @param g2  the graphics device.
 110:      * @param state  the renderer state.
 111:      * @param dataArea  the data area.
 112:      * @param plot  the plot.
 113:      * @param domainAxis  the domain axis.
 114:      * @param rangeAxis  the range axis.
 115:      * @param dataset  the dataset.
 116:      * @param row  the row index (zero-based).
 117:      * @param column  the column index (zero-based).
 118:      * @param pass  the pass index.
 119:      */
 120:     public void drawItem(Graphics2D g2,
 121:                          CategoryItemRendererState state,
 122:                          Rectangle2D dataArea,
 123:                          CategoryPlot plot,
 124:                          CategoryAxis domainAxis,
 125:                          ValueAxis rangeAxis,
 126:                          CategoryDataset dataset,
 127:                          int row,
 128:                          int column,
 129:                          int pass) {
 130: 
 131:          if (dataset instanceof IntervalCategoryDataset) {
 132:              IntervalCategoryDataset d = (IntervalCategoryDataset) dataset;
 133:              drawInterval(g2, state, dataArea, plot, domainAxis, rangeAxis, 
 134:                      d, row, column);
 135:          }
 136:          else {
 137:              super.drawItem(g2, state, dataArea, plot, domainAxis, rangeAxis, 
 138:                      dataset, row, column, pass);
 139:          } 
 140:          
 141:      }
 142:                           
 143:      /**
 144:       * Draws a single interval.
 145:       *
 146:       * @param g2  the graphics device.
 147:       * @param state  the renderer state.
 148:       * @param dataArea  the data plot area.
 149:       * @param plot  the plot.
 150:       * @param domainAxis  the domain axis.
 151:       * @param rangeAxis  the range axis.
 152:       * @param dataset  the data.
 153:       * @param row  the row index (zero-based).
 154:       * @param column  the column index (zero-based).
 155:       */
 156:      protected void drawInterval(Graphics2D g2,
 157:                                  CategoryItemRendererState state,
 158:                                  Rectangle2D dataArea,
 159:                                  CategoryPlot plot,
 160:                                  CategoryAxis domainAxis,
 161:                                  ValueAxis rangeAxis,
 162:                                  IntervalCategoryDataset dataset,
 163:                                  int row,
 164:                                  int column) {
 165: 
 166:         int seriesCount = getRowCount();
 167:         int categoryCount = getColumnCount();
 168: 
 169:         PlotOrientation orientation = plot.getOrientation();
 170:         
 171:         double rectX = 0.0;
 172:         double rectY = 0.0;
 173: 
 174:         RectangleEdge domainAxisLocation = plot.getDomainAxisEdge();
 175:         RectangleEdge rangeAxisLocation = plot.getRangeAxisEdge();
 176:         
 177:         // Y0
 178:         Number value0 = dataset.getEndValue(row, column);
 179:         if (value0 == null) {
 180:             return;
 181:         }
 182:         double java2dValue0 = rangeAxis.valueToJava2D(
 183:             value0.doubleValue(), dataArea, rangeAxisLocation
 184:         );
 185: 
 186:         // Y1
 187:         Number value1 = dataset.getStartValue(row, column);
 188:         if (value1 == null) {
 189:             return;
 190:         }
 191:         double java2dValue1 = rangeAxis.valueToJava2D(
 192:                 value1.doubleValue(), dataArea, rangeAxisLocation);
 193: 
 194:         if (java2dValue1 < java2dValue0) {
 195:             double temp = java2dValue1;
 196:             java2dValue1 = java2dValue0;
 197:             java2dValue0 = temp;
 198:             Number tempNum = value1;
 199:             value1 = value0;
 200:             value0 = tempNum;
 201:         }
 202: 
 203:         // BAR WIDTH
 204:         double rectWidth = state.getBarWidth();
 205: 
 206:         // BAR HEIGHT
 207:         double rectHeight = Math.abs(java2dValue1 - java2dValue0);
 208: 
 209:         if (orientation == PlotOrientation.HORIZONTAL) {
 210:             // BAR Y
 211:             rectY = domainAxis.getCategoryStart(
 212:                 column, getColumnCount(), dataArea, domainAxisLocation
 213:             );
 214:             if (seriesCount > 1) {
 215:                 double seriesGap = dataArea.getHeight() * getItemMargin()
 216:                                    / (categoryCount * (seriesCount - 1));
 217:                 rectY = rectY + row * (state.getBarWidth() + seriesGap);
 218:             }
 219:             else {
 220:                 rectY = rectY + row * state.getBarWidth();
 221:             }
 222:             
 223:             rectX = java2dValue0;
 224: 
 225:             rectHeight = state.getBarWidth();
 226:             rectWidth = Math.abs(java2dValue1 - java2dValue0);
 227: 
 228:         }
 229:         else if (orientation == PlotOrientation.VERTICAL) {
 230:             // BAR X
 231:             rectX = domainAxis.getCategoryStart(
 232:                 column, getColumnCount(), dataArea, domainAxisLocation
 233:             );
 234: 
 235:             if (seriesCount > 1) {
 236:                 double seriesGap = dataArea.getWidth() * getItemMargin()
 237:                                    / (categoryCount * (seriesCount - 1));
 238:                 rectX = rectX + row * (state.getBarWidth() + seriesGap);
 239:             }
 240:             else {
 241:                 rectX = rectX + row * state.getBarWidth();
 242:             }
 243: 
 244:             rectY = java2dValue0;
 245: 
 246:         }
 247:         Rectangle2D bar = new Rectangle2D.Double(rectX, rectY, rectWidth, 
 248:                 rectHeight);
 249:         Paint seriesPaint = getItemPaint(row, column);
 250:         g2.setPaint(seriesPaint);
 251:         g2.fill(bar);
 252:         
 253:         // draw the outline...
 254:         if (state.getBarWidth() > BAR_OUTLINE_WIDTH_THRESHOLD) {
 255:             Stroke stroke = getItemOutlineStroke(row, column);
 256:             Paint paint = getItemOutlinePaint(row, column);
 257:             if (stroke != null && paint != null) {
 258:                 g2.setStroke(stroke);
 259:                 g2.setPaint(paint);
 260:                 g2.draw(bar);
 261:             }
 262:         }
 263:         
 264:         CategoryItemLabelGenerator generator 
 265:             = getItemLabelGenerator(row, column);
 266:         if (generator != null && isItemLabelVisible(row, column)) {
 267:             drawItemLabel(g2, dataset, row, column, plot, generator, bar, 
 268:                     false);
 269:         }        
 270: 
 271:         // collect entity and tool tip information...
 272:         if (state.getInfo() != null) {
 273:             EntityCollection entities = state.getEntityCollection();
 274:             if (entities != null) {
 275:                 String tip = null;
 276:                 CategoryToolTipGenerator tipster 
 277:                         = getToolTipGenerator(row, column);
 278:                 if (tipster != null) {
 279:                     tip = tipster.generateToolTip(dataset, row, column);
 280:                 }
 281:                 String url = null;
 282:                 if (getItemURLGenerator(row, column) != null) {
 283:                     url = getItemURLGenerator(row, column).generateURL(
 284:                             dataset, row, column);
 285:                 }
 286:                 CategoryItemEntity entity = new CategoryItemEntity(bar, tip, 
 287:                         url, dataset, row, dataset.getColumnKey(column), 
 288:                         column);
 289:                 entities.add(entity);
 290:             }
 291:         }
 292: 
 293:     }
 294: 
 295: }