1 64 65 package org.jfree.chart.renderer.category; 66 67 import java.awt.Graphics2D ; 68 import java.awt.Polygon ; 69 import java.awt.Shape ; 70 import java.awt.geom.Rectangle2D ; 71 import java.io.Serializable ; 72 73 import org.jfree.chart.axis.CategoryAxis; 74 import org.jfree.chart.axis.ValueAxis; 75 import org.jfree.chart.entity.EntityCollection; 76 import org.jfree.chart.event.RendererChangeEvent; 77 import org.jfree.chart.plot.CategoryPlot; 78 import org.jfree.chart.plot.PlotOrientation; 79 import org.jfree.data.DataUtilities; 80 import org.jfree.data.Range; 81 import org.jfree.data.category.CategoryDataset; 82 import org.jfree.data.general.DatasetUtilities; 83 import org.jfree.ui.RectangleEdge; 84 import org.jfree.util.PublicCloneable; 85 86 90 public class StackedAreaRenderer extends AreaRenderer 91 implements Cloneable , PublicCloneable, 92 Serializable { 93 94 95 private static final long serialVersionUID = -3595635038460823663L; 96 97 98 private boolean renderAsPercentages; 99 100 103 public StackedAreaRenderer() { 104 this(false); 105 } 106 107 113 public StackedAreaRenderer(boolean renderAsPercentages) { 114 super(); 115 this.renderAsPercentages = renderAsPercentages; 116 } 117 118 127 public boolean getRenderAsPercentages() { 128 return this.renderAsPercentages; 129 } 130 131 140 public void setRenderAsPercentages(boolean asPercentages) { 141 this.renderAsPercentages = asPercentages; 142 notifyListeners(new RendererChangeEvent(this)); 143 } 144 145 152 public int getPassCount() { 153 return 2; 154 } 155 156 164 public Range findRangeBounds(CategoryDataset dataset) { 165 if (this.renderAsPercentages) { 166 return new Range(0.0, 1.0); 167 } 168 else { 169 return DatasetUtilities.findStackedRangeBounds(dataset); 170 } 171 } 172 173 187 public void drawItem(Graphics2D g2, 188 CategoryItemRendererState state, 189 Rectangle2D dataArea, 190 CategoryPlot plot, 191 CategoryAxis domainAxis, 192 ValueAxis rangeAxis, 193 CategoryDataset dataset, 194 int row, 195 int column, 196 int pass) { 197 198 Number dataValue = dataset.getValue(row, column); 200 if (dataValue == null) { 201 return; 202 } 203 204 double value = dataValue.doubleValue(); 205 double total = 0.0; if (this.renderAsPercentages) { 207 total = DataUtilities.calculateColumnTotal(dataset, column); 208 value = value / total; 209 } 210 211 double xx1 = domainAxis.getCategoryMiddle(column, getColumnCount(), 215 dataArea, plot.getDomainAxisEdge()); 216 217 double previousHeightx1 = getPreviousHeight(dataset, row, column); 218 double y1 = value + previousHeightx1; 219 RectangleEdge location = plot.getRangeAxisEdge(); 220 double yy1 = rangeAxis.valueToJava2D(y1, dataArea, location); 221 222 g2.setPaint(getItemPaint(row, column)); 223 g2.setStroke(getItemStroke(row, column)); 224 225 if (column == 0) { 228 if (pass == 1) { 229 if (isItemLabelVisible(row, column)) { 231 drawItemLabel(g2, plot.getOrientation(), dataset, row, column, 232 xx1, yy1, (y1 < 0.0)); 233 } 234 } 235 } 236 else { 237 Number previousValue = dataset.getValue(row, column - 1); 238 if (previousValue != null) { 239 240 double xx0 = domainAxis.getCategoryMiddle(column - 1, 241 getColumnCount(), dataArea, plot.getDomainAxisEdge()); 242 double y0 = previousValue.doubleValue(); 243 if (this.renderAsPercentages) { 244 total = DataUtilities.calculateColumnTotal(dataset, 245 column - 1); 246 y0 = y0 / total; 247 } 248 249 250 double previousHeightx0 = getPreviousHeight(dataset, row, 253 column - 1); 254 255 y0 += previousHeightx0; 257 258 double previousHeightxx0 = rangeAxis.valueToJava2D( 260 previousHeightx0, dataArea, location); 261 double previousHeightxx1 = rangeAxis.valueToJava2D( 262 previousHeightx1, dataArea, location); 263 264 double yy0 = rangeAxis.valueToJava2D(y0, dataArea, location); 266 267 if (pass == 0) { 268 Polygon p = null; 269 PlotOrientation orientation = plot.getOrientation(); 270 if (orientation == PlotOrientation.HORIZONTAL) { 271 p = new Polygon (); 272 p.addPoint((int) yy0, (int) xx0); 273 p.addPoint((int) yy1, (int) xx1); 274 p.addPoint((int) previousHeightxx1, (int) xx1); 275 p.addPoint((int) previousHeightxx0, (int) xx0); 276 } 277 else if (orientation == PlotOrientation.VERTICAL) { 278 p = new Polygon (); 279 p.addPoint((int) xx0, (int) yy0); 280 p.addPoint((int) xx1, (int) yy1); 281 p.addPoint((int) xx1, (int) previousHeightxx1); 282 p.addPoint((int) xx0, (int) previousHeightxx0); 283 } 284 g2.setPaint(getItemPaint(row, column)); 285 g2.setStroke(getItemStroke(row, column)); 286 g2.fill(p); 287 } 288 else { 289 if (isItemLabelVisible(row, column)) { 290 drawItemLabel(g2, plot.getOrientation(), dataset, row, 291 column, xx1, yy1, (y1 < 0.0)); 292 } 293 } 294 } 295 296 297 } 298 299 300 EntityCollection entities = state.getEntityCollection(); 302 if (entities != null) { 303 Shape shape = new Rectangle2D.Double (xx1 - 3.0, yy1 - 3.0, 6.0, 6.0); 304 addItemEntity(entities, dataset, row, column, shape); 305 } 306 307 } 308 309 322 protected double getPreviousHeight(CategoryDataset dataset, 323 int series, int category) { 324 325 double result = 0.0; 326 Number n; 327 double total = 0.0; 328 if (this.renderAsPercentages) { 329 total = DataUtilities.calculateColumnTotal(dataset, category); 330 } 331 for (int i = 0; i < series; i++) { 332 n = dataset.getValue(i, category); 333 if (n != null) { 334 double v = n.doubleValue(); 335 if (this.renderAsPercentages) { 336 v = v / total; 337 } 338 result += v; 339 } 340 } 341 return result; 342 343 } 344 345 352 public boolean equals(Object obj) { 353 if (obj == this) { 354 return true; 355 } 356 if (! (obj instanceof StackedAreaRenderer)) { 357 return false; 358 } 359 StackedAreaRenderer that = (StackedAreaRenderer) obj; 360 if (this.renderAsPercentages != that.renderAsPercentages) { 361 return false; 362 } 363 return super.equals(obj); 364 } 365 } 366 | Popular Tags |