1 51 52 package org.jfree.chart.renderer.xy; 53 54 import java.awt.Graphics2D ; 55 import java.awt.geom.Rectangle2D ; 56 import java.io.Serializable ; 57 58 import org.jfree.chart.axis.ValueAxis; 59 import org.jfree.chart.entity.EntityCollection; 60 import org.jfree.chart.entity.XYItemEntity; 61 import org.jfree.chart.labels.XYToolTipGenerator; 62 import org.jfree.chart.plot.CrosshairState; 63 import org.jfree.chart.plot.PlotOrientation; 64 import org.jfree.chart.plot.PlotRenderingInfo; 65 import org.jfree.chart.plot.XYPlot; 66 import org.jfree.data.Range; 67 import org.jfree.data.general.DatasetUtilities; 68 import org.jfree.data.xy.IntervalXYDataset; 69 import org.jfree.data.xy.TableXYDataset; 70 import org.jfree.data.xy.XYDataset; 71 import org.jfree.ui.RectangleEdge; 72 73 83 public class StackedXYBarRenderer extends XYBarRenderer 84 implements Serializable { 85 86 87 private static final long serialVersionUID = -7049101055533436444L; 88 89 92 public StackedXYBarRenderer() { 93 super(); 94 } 95 96 101 public StackedXYBarRenderer(double margin) { 102 super(margin); 103 } 104 105 119 public XYItemRendererState initialise(Graphics2D g2, 120 Rectangle2D dataArea, 121 XYPlot plot, 122 XYDataset data, 123 PlotRenderingInfo info) { 124 return new XYBarRendererState(info); 125 } 126 127 136 public Range findRangeBounds(XYDataset dataset) { 137 if (dataset != null) { 138 return DatasetUtilities.findStackedRangeBounds( 139 (TableXYDataset) dataset); 140 } 141 else { 142 return null; 143 } 144 } 145 146 164 public void drawItem(Graphics2D g2, 165 XYItemRendererState state, 166 Rectangle2D dataArea, 167 PlotRenderingInfo info, 168 XYPlot plot, 169 ValueAxis domainAxis, 170 ValueAxis rangeAxis, 171 XYDataset dataset, 172 int series, 173 int item, 174 CrosshairState crosshairState, 175 int pass) { 176 177 if (!(dataset instanceof IntervalXYDataset 178 && dataset instanceof TableXYDataset)) { 179 String message = "dataset (type " + dataset.getClass().getName() 180 + ") has wrong type:"; 181 boolean and = false; 182 if (!IntervalXYDataset.class.isAssignableFrom(dataset.getClass())) { 183 message += " it is no IntervalXYDataset"; 184 and = true; 185 } 186 if (!TableXYDataset.class.isAssignableFrom(dataset.getClass())) { 187 if (and) { 188 message += " and"; 189 } 190 message += " it is no TableXYDataset"; 191 } 192 193 throw new IllegalArgumentException (message); 194 } 195 196 IntervalXYDataset intervalDataset = (IntervalXYDataset) dataset; 197 double value = intervalDataset.getYValue(series, item); 198 if (Double.isNaN(value)) { 199 return; 200 } 201 202 double positiveBase = 0.0; 203 double negativeBase = 0.0; 204 205 for (int i = 0; i < series; i++) { 206 double v = dataset.getYValue(i, item); 207 if (!Double.isNaN(v)) { 208 if (v > 0) { 209 positiveBase = positiveBase + v; 210 } 211 else { 212 negativeBase = negativeBase + v; 213 } 214 } 215 } 216 217 double translatedBase; 218 double translatedValue; 219 RectangleEdge edgeR = plot.getRangeAxisEdge(); 220 if (value > 0.0) { 221 translatedBase = rangeAxis.valueToJava2D(positiveBase, dataArea, 222 edgeR); 223 translatedValue = rangeAxis.valueToJava2D(positiveBase + value, 224 dataArea, edgeR); 225 } 226 else { 227 translatedBase = rangeAxis.valueToJava2D(negativeBase, dataArea, 228 edgeR); 229 translatedValue = rangeAxis.valueToJava2D(negativeBase + value, 230 dataArea, edgeR); 231 } 232 233 RectangleEdge edgeD = plot.getDomainAxisEdge(); 234 double startX = intervalDataset.getStartXValue(series, item); 235 if (Double.isNaN(startX)) { 236 return; 237 } 238 double translatedStartX = domainAxis.valueToJava2D(startX, dataArea, 239 edgeD); 240 241 double endX = intervalDataset.getEndXValue(series, item); 242 if (Double.isNaN(endX)) { 243 return; 244 } 245 double translatedEndX = domainAxis.valueToJava2D(endX, dataArea, edgeD); 246 247 double translatedWidth = Math.max(1, Math.abs(translatedEndX 248 - translatedStartX)); 249 double translatedHeight = Math.abs(translatedValue - translatedBase); 250 if (getMargin() > 0.0) { 251 double cut = translatedWidth * getMargin(); 252 translatedWidth = translatedWidth - cut; 253 translatedStartX = translatedStartX + cut / 2; 254 } 255 256 Rectangle2D bar = null; 257 PlotOrientation orientation = plot.getOrientation(); 258 if (orientation == PlotOrientation.HORIZONTAL) { 259 bar = new Rectangle2D.Double (Math.min(translatedBase, 260 translatedValue), translatedEndX, translatedHeight, 261 translatedWidth); 262 } 263 else if (orientation == PlotOrientation.VERTICAL) { 264 bar = new Rectangle2D.Double (translatedStartX, 265 Math.min(translatedBase, translatedValue), 266 translatedWidth, translatedHeight); 267 } 268 269 g2.setPaint(getItemPaint(series, item)); 270 g2.fill(bar); 271 if (isDrawBarOutline() 272 && Math.abs(translatedEndX - translatedStartX) > 3) { 273 g2.setStroke(getItemStroke(series, item)); 274 g2.setPaint(getItemOutlinePaint(series, item)); 275 g2.draw(bar); 276 } 277 278 if (info != null) { 280 EntityCollection entities = info.getOwner().getEntityCollection(); 281 if (entities != null) { 282 String tip = null; 283 XYToolTipGenerator generator 284 = getToolTipGenerator(series, item); 285 if (generator != null) { 286 tip = generator.generateToolTip(dataset, series, item); 287 } 288 String url = null; 289 if (getURLGenerator() != null) { 290 url = getURLGenerator().generateURL(dataset, series, item); 291 } 292 XYItemEntity entity = new XYItemEntity(bar, dataset, series, 293 item, tip, url); 294 entities.add(entity); 295 } 296 } 297 } 298 299 } 300 | Popular Tags |