1 69 70 package org.jfree.chart.renderer; 71 72 import java.awt.Graphics2D ; 73 import java.awt.Paint ; 74 import java.awt.geom.Rectangle2D ; 75 import java.io.Serializable ; 76 77 import org.jfree.chart.axis.CategoryAxis; 78 import org.jfree.chart.axis.ValueAxis; 79 import org.jfree.chart.entity.CategoryItemEntity; 80 import org.jfree.chart.entity.EntityCollection; 81 import org.jfree.chart.labels.CategoryItemLabelGenerator; 82 import org.jfree.chart.plot.CategoryPlot; 83 import org.jfree.chart.plot.PlotOrientation; 84 import org.jfree.data.CategoryDataset; 85 import org.jfree.ui.RectangleEdge; 86 import org.jfree.ui.TextAnchor; 87 import org.jfree.util.PublicCloneable; 88 89 94 public class StackedBarRenderer extends BarRenderer 95 implements Cloneable , PublicCloneable, Serializable { 96 97 104 public StackedBarRenderer() { 105 super(); 106 107 ItemLabelPosition p = new ItemLabelPosition( 110 ItemLabelAnchor.CENTER, TextAnchor.CENTER, TextAnchor.CENTER, 0.0 111 ); 112 setBasePositiveItemLabelPosition(p); 113 setBaseNegativeItemLabelPosition(p); 114 setPositiveItemLabelPositionFallback(null); 115 setNegativeItemLabelPositionFallback(null); 116 } 117 118 123 public RangeType getRangeType() { 124 return RangeType.STACKED; 125 } 126 127 135 protected void calculateBarWidth(CategoryPlot plot, 136 Rectangle2D dataArea, 137 Integer rendererIndex, 138 CategoryItemRendererState state) { 139 140 CategoryAxis domainAxis = getDomainAxis(plot, rendererIndex); 142 CategoryDataset data = getDataset(plot, rendererIndex); 143 if (data != null) { 144 PlotOrientation orientation = plot.getOrientation(); 145 double space = 0.0; 146 if (orientation == PlotOrientation.HORIZONTAL) { 147 space = dataArea.getHeight(); 148 } 149 else if (orientation == PlotOrientation.VERTICAL) { 150 space = dataArea.getWidth(); 151 } 152 double maxWidth = space * getMaxBarWidth(); 153 int columns = data.getColumnCount(); 154 double categoryMargin = 0.0; 155 if (columns > 1) { 156 categoryMargin = domainAxis.getCategoryMargin(); 157 } 158 159 double used = space * (1 - domainAxis.getLowerMargin() - domainAxis.getUpperMargin() 160 - categoryMargin); 161 if (columns > 0) { 162 state.setBarWidth(Math.min(used / columns, maxWidth)); 163 } 164 else { 165 state.setBarWidth(Math.min(used, maxWidth)); 166 } 167 } 168 169 } 170 171 184 public void drawItem(Graphics2D g2, 185 CategoryItemRendererState state, 186 Rectangle2D dataArea, 187 CategoryPlot plot, 188 CategoryAxis domainAxis, 189 ValueAxis rangeAxis, 190 CategoryDataset dataset, 191 int row, 192 int column) { 193 194 Number dataValue = dataset.getValue(row, column); 196 if (dataValue == null) { 197 return; 198 } 199 200 double value = dataValue.doubleValue(); 201 202 PlotOrientation orientation = plot.getOrientation(); 203 double barW0 = domainAxis.getCategoryMiddle(column, getColumnCount(), dataArea, 204 plot.getDomainAxisEdge()) 205 - state.getBarWidth() / 2.0; 206 207 double positiveBase = 0.0; 208 double negativeBase = 0.0; 209 210 for (int i = 0; i < row; i++) { 211 Number v = dataset.getValue(i, column); 212 if (v != null) { 213 double d = v.doubleValue(); 214 if (d > 0) { 215 positiveBase = positiveBase + d; 216 } 217 else { 218 negativeBase = negativeBase + d; 219 } 220 } 221 } 222 223 double translatedBase; 224 double translatedValue; 225 RectangleEdge location = plot.getRangeAxisEdge(); 226 if (value > 0.0) { 227 translatedBase = rangeAxis.translateValueToJava2D(positiveBase, dataArea, location); 228 translatedValue = rangeAxis.translateValueToJava2D(positiveBase + value, dataArea, 229 location); 230 } 231 else { 232 translatedBase = rangeAxis.translateValueToJava2D(negativeBase, dataArea, location); 233 translatedValue = rangeAxis.translateValueToJava2D(negativeBase + value, dataArea, 234 location); 235 } 236 double barL0 = Math.min(translatedBase, translatedValue); 237 double barLength = Math.max(Math.abs(translatedValue - translatedBase), 238 getMinimumBarLength()); 239 240 Rectangle2D bar = null; 241 if (orientation == PlotOrientation.HORIZONTAL) { 242 bar = new Rectangle2D.Double (barL0, barW0, barLength, state.getBarWidth()); 243 } 244 else { 245 bar = new Rectangle2D.Double (barW0, barL0, state.getBarWidth(), barLength); 246 } 247 Paint seriesPaint = getItemPaint(row, column); 248 g2.setPaint(seriesPaint); 249 g2.fill(bar); 250 if (isDrawBarOutline() && state.getBarWidth() > BAR_OUTLINE_WIDTH_THRESHOLD) { 251 g2.setStroke(getItemStroke(row, column)); 252 g2.setPaint(getItemOutlinePaint(row, column)); 253 g2.draw(bar); 254 } 255 256 CategoryItemLabelGenerator generator = getItemLabelGenerator(row, column); 257 if (generator != null && isItemLabelVisible(row, column)) { 258 drawItemLabel(g2, dataset, row, column, plot, generator, bar, (value < 0.0)); 259 } 260 261 if (state.getInfo() != null) { 263 EntityCollection entities = state.getInfo().getOwner().getEntityCollection(); 264 if (entities != null) { 265 String tip = null; 266 if (generator != null) { 267 tip = generator.generateToolTip(dataset, row, column); 268 } 269 String url = null; 270 if (getItemURLGenerator(row, column) != null) { 271 url = getItemURLGenerator(row, column).generateURL(dataset, row, column); 272 } 273 CategoryItemEntity entity = new CategoryItemEntity( 274 bar, tip, url, dataset, row, dataset.getColumnKey(column), column 275 ); 276 entities.addEntity(entity); 277 } 278 } 279 280 } 281 282 } 283 | Popular Tags |