1 39 40 package org.jfree.chart.renderer; 41 42 import java.awt.Graphics2D ; 43 import java.awt.Paint ; 44 import java.awt.Stroke ; 45 import java.awt.geom.Rectangle2D ; 46 47 import org.jfree.chart.axis.CategoryAxis; 48 import org.jfree.chart.axis.ValueAxis; 49 import org.jfree.chart.entity.CategoryItemEntity; 50 import org.jfree.chart.entity.EntityCollection; 51 import org.jfree.chart.labels.CategoryItemLabelGenerator; 52 import org.jfree.chart.plot.CategoryPlot; 53 import org.jfree.chart.plot.PlotOrientation; 54 import org.jfree.data.CategoryDataset; 55 import org.jfree.ui.RectangleEdge; 56 import org.jfree.util.ObjectList; 57 58 63 public class LayeredBarRenderer extends BarRenderer { 64 65 66 protected ObjectList seriesBarWidthList; 67 68 71 public LayeredBarRenderer() { 72 super(); 73 this.seriesBarWidthList = new ObjectList(); 74 75 } 76 77 85 protected void calculateBarWidth(CategoryPlot plot, 86 Rectangle2D dataArea, 87 Integer rendererIndex, 88 CategoryItemRendererState state) { 89 90 CategoryAxis domainAxis = getDomainAxis(plot, rendererIndex); 92 CategoryDataset dataset = getDataset(plot, rendererIndex); 93 if (dataset != null) { 94 int columns = dataset.getColumnCount(); 95 int rows = dataset.getRowCount(); 96 double space = 0.0; 97 PlotOrientation orientation = plot.getOrientation(); 98 if (orientation == PlotOrientation.HORIZONTAL) { 99 space = dataArea.getHeight(); 100 } 101 else if (orientation == PlotOrientation.VERTICAL) { 102 space = dataArea.getWidth(); 103 } 104 double categoryMargin = 0.0; 105 double currentItemMargin = 0.0; 106 if (columns > 1) { 107 categoryMargin = domainAxis.getCategoryMargin(); 108 } 109 if (rows > 1) { 110 currentItemMargin = getItemMargin(); 111 } 112 double used = space * (1 - domainAxis.getLowerMargin() - domainAxis.getUpperMargin() 113 - categoryMargin - currentItemMargin); 114 if ((rows * columns) > 0) { 115 state.setBarWidth(used / (dataset.getColumnCount())); 116 } 117 else { 118 state.setBarWidth(used); 119 } 120 } 121 } 122 123 136 public void drawItem(Graphics2D g2, 137 CategoryItemRendererState state, 138 Rectangle2D dataArea, 139 CategoryPlot plot, 140 CategoryAxis domainAxis, 141 ValueAxis rangeAxis, 142 CategoryDataset data, 143 int row, 144 int column) { 145 146 PlotOrientation orientation = plot.getOrientation(); 147 if (orientation == PlotOrientation.HORIZONTAL) { 148 drawHorizontalItem(g2, state, dataArea, 149 plot, domainAxis, rangeAxis, data, row, column); 150 } 151 else if (orientation == PlotOrientation.VERTICAL) { 152 drawVerticalItem(g2, state, dataArea, 153 plot, domainAxis, rangeAxis, data, row, column); 154 } 155 156 } 157 158 171 protected void drawHorizontalItem(Graphics2D g2, 172 CategoryItemRendererState state, 173 Rectangle2D dataArea, 174 CategoryPlot plot, 175 CategoryAxis domainAxis, 176 ValueAxis rangeAxis, 177 CategoryDataset data, 178 int row, 179 int column) { 180 181 Number dataValue = data.getValue(row, column); 183 if (dataValue == null) { 184 return; 185 } 186 187 double value = dataValue.doubleValue(); 189 double base = 0.0; 190 double lclip = getLowerClip(); 191 double uclip = getUpperClip(); 192 if (uclip <= 0.0) { if (value >= uclip) { 194 return; } 196 base = uclip; 197 if (value <= lclip) { 198 value = lclip; 199 } 200 } 201 else if (lclip <= 0.0) { if (value >= uclip) { 203 value = uclip; 204 } 205 else { 206 if (value <= lclip) { 207 value = lclip; 208 } 209 } 210 } 211 else { if (value <= lclip) { 213 return; } 215 base = lclip; 216 if (value >= uclip) { 217 value = uclip; 218 } 219 } 220 221 RectangleEdge edge = plot.getRangeAxisEdge(); 222 double transX1 = rangeAxis.translateValueToJava2D(base, dataArea, edge); 223 double transX2 = rangeAxis.translateValueToJava2D(value, dataArea, edge); 224 double rectX = Math.min(transX1, transX2); 225 double rectWidth = Math.abs(transX2 - transX1); 226 227 double rectY = domainAxis.getCategoryStart(column, getColumnCount(), dataArea, 229 plot.getDomainAxisEdge()); 230 231 int seriesCount = getRowCount(); 232 233 double shift = 0.0; 235 double rectHeight = 0.0; 236 if (getSeriesBarWidth(row, state) != state.getBarWidth()) { 237 rectHeight = getSeriesBarWidth(row, state) * state.getBarWidth(); 238 rectY = rectY + (1 - getSeriesBarWidth(row, state)) * state.getBarWidth() / 2; 239 } 240 else { 241 rectHeight = state.getBarWidth(); 242 if (seriesCount > 1) { 243 shift = rectHeight * 0.20 / (seriesCount - 1); 244 } 245 } 246 247 Rectangle2D bar = new Rectangle2D.Double (rectX, 248 (rectY + ((seriesCount - 1 - row) * shift)), 249 rectWidth, 250 (rectHeight - (seriesCount - 1 - row) * shift * 2)); 251 252 g2.setPaint(getItemPaint(row, column)); 253 g2.fill(bar); 254 255 if (isDrawBarOutline() && state.getBarWidth() > BAR_OUTLINE_WIDTH_THRESHOLD) { 257 Stroke stroke = getItemOutlineStroke(row, column); 258 Paint paint = getItemOutlinePaint(row, column); 259 if (stroke != null && paint != null) { 260 g2.setStroke(stroke); 261 g2.setPaint(paint); 262 g2.draw(bar); 263 } 264 } 265 266 CategoryItemLabelGenerator generator = getItemLabelGenerator(row, column); 267 if (generator != null && isItemLabelVisible(row, column)) { 268 drawItemLabel(g2, data, row, column, plot, generator, bar, (transX1 > transX2)); 269 } 270 271 if (state.getInfo() != null) { 273 EntityCollection entities = state.getInfo().getOwner().getEntityCollection(); 274 if (entities != null) { 275 String tip = null; 276 if (generator != null) { 277 tip = generator.generateToolTip(data, row, column); 278 } 279 String url = null; 280 if (getItemURLGenerator(row, column) != null) { 281 url = getItemURLGenerator(row, column).generateURL(data, row, column); 282 } 283 CategoryItemEntity entity = new CategoryItemEntity(bar, tip, url, data, row, 284 data.getColumnKey(column), column); 285 entities.addEntity(entity); 286 } 287 } 288 } 289 290 303 protected void drawVerticalItem(Graphics2D g2, 304 CategoryItemRendererState state, 305 Rectangle2D dataArea, 306 CategoryPlot plot, 307 CategoryAxis domainAxis, 308 ValueAxis rangeAxis, 309 CategoryDataset data, 310 int row, 311 int column) { 312 313 Number dataValue = data.getValue(row, column); 315 if (dataValue == null) { 316 return; 317 } 318 319 double rectX = domainAxis.getCategoryStart(column, getColumnCount(), dataArea, 321 plot.getDomainAxisEdge()); 322 323 int seriesCount = getRowCount(); 324 325 double value = dataValue.doubleValue(); 327 double base = 0.0; 328 double lclip = getLowerClip(); 329 double uclip = getUpperClip(); 330 331 if (uclip <= 0.0) { if (value >= uclip) { 333 return; } 335 base = uclip; 336 if (value <= lclip) { 337 value = lclip; 338 } 339 } 340 else if (lclip <= 0.0) { if (value >= uclip) { 342 value = uclip; 343 } 344 else { 345 if (value <= lclip) { 346 value = lclip; 347 } 348 } 349 } 350 else { if (value <= lclip) { 352 return; } 354 base = getLowerClip(); 355 if (value >= uclip) { 356 value = uclip; 357 } 358 } 359 360 RectangleEdge edge = plot.getRangeAxisEdge(); 361 double transY1 = rangeAxis.translateValueToJava2D(base, dataArea, edge); 362 double transY2 = rangeAxis.translateValueToJava2D(value, dataArea, edge); 363 double rectY = Math.min(transY2, transY1); 364 365 double rectWidth = state.getBarWidth(); 366 double rectHeight = Math.abs(transY2 - transY1); 367 368 double shift = 0.0; 370 rectWidth = 0.0; 371 if (getSeriesBarWidth(row, state) != state.getBarWidth()) { 372 rectWidth = getSeriesBarWidth(row, state) * state.getBarWidth(); 373 rectX = rectX + (1 - getSeriesBarWidth(row, state)) * state.getBarWidth() / 2; 374 } else { 375 rectWidth = state.getBarWidth(); 376 if (seriesCount > 1) { 377 shift = rectWidth * 0.20 / (seriesCount - 1); 379 } 380 } 381 382 Rectangle2D bar = new Rectangle2D.Double ( 383 (rectX + ((seriesCount - 1 - row) * shift)), 384 rectY, 385 (rectWidth - (seriesCount - 1 - row) * shift * 2), 386 rectHeight); 387 g2.setPaint(getItemPaint(row, column)); 388 g2.fill(bar); 389 390 if (isDrawBarOutline() && state.getBarWidth() > BAR_OUTLINE_WIDTH_THRESHOLD) { 392 Stroke stroke = getItemOutlineStroke(row, column); 393 Paint paint = getItemOutlinePaint(row, column); 394 if (stroke != null && paint != null) { 395 g2.setStroke(stroke); 396 g2.setPaint(paint); 397 g2.draw(bar); 398 } 399 } 400 401 double transX1 = rangeAxis.translateValueToJava2D(base, dataArea, edge); 403 double transX2 = rangeAxis.translateValueToJava2D(value, dataArea, edge); 404 405 CategoryItemLabelGenerator generator = getItemLabelGenerator(row, column); 406 if (generator != null && isItemLabelVisible(row, column)) { 407 drawItemLabel(g2, data, row, column, plot, generator, bar, (transX1 > transX2)); 408 } 409 410 if (state.getInfo() != null) { 412 EntityCollection entities = state.getInfo().getOwner().getEntityCollection(); 413 if (entities != null) { 414 String tip = null; 415 if (generator != null) { 416 tip = generator.generateToolTip(data, row, column); 417 } 418 String url = null; 419 if (getItemURLGenerator(row, column) != null) { 420 url = getItemURLGenerator(row, column).generateURL(data, row, column); 421 } 422 CategoryItemEntity entity = new CategoryItemEntity(bar, tip, url, data, row, 423 data.getColumnKey(column), column); 424 entities.addEntity(entity); 425 } 426 } 427 } 428 429 437 public double getSeriesBarWidth(int series, CategoryItemRendererState state) { 438 439 if (this.seriesBarWidthList.get(series) != null) { 440 return ((Number ) this.seriesBarWidthList.get(series)).doubleValue(); 441 } 442 else { 443 return state.getBarWidth(); 444 } 445 } 446 447 453 public void setSeriesBarWidth(int series, double width) { 454 this.seriesBarWidthList.set(series, new Double (width)); 455 } 456 457 } 458 | Popular Tags |