1:
57:
58: package ;
59:
60: import ;
61: import ;
62: import ;
63: import ;
64: import ;
65: import ;
66: import ;
67: import ;
68: import ;
69: import ;
70: import ;
71: import ;
72:
73: import ;
74: import ;
75: import ;
76: import ;
77: import ;
78: import ;
79: import ;
80: import ;
81: import ;
82: import ;
83: import ;
84: import ;
85: import ;
86: import ;
87: import ;
88:
89:
93: public class StatisticalBarRenderer extends BarRenderer
94: implements CategoryItemRenderer, Cloneable, PublicCloneable,
95: Serializable {
96:
97:
98: private static final long serialVersionUID = -4986038395414039117L;
99:
100:
101: private transient Paint errorIndicatorPaint;
102:
103:
108: private transient Stroke errorIndicatorStroke;
109:
110:
113: public StatisticalBarRenderer() {
114: super();
115: this.errorIndicatorPaint = Color.gray;
116: this.errorIndicatorStroke = new BasicStroke(1.0f);
117: }
118:
119:
127: public Paint getErrorIndicatorPaint() {
128: return this.errorIndicatorPaint;
129: }
130:
131:
140: public void setErrorIndicatorPaint(Paint paint) {
141: this.errorIndicatorPaint = paint;
142: fireChangeEvent();
143: }
144:
145:
155: public Stroke getErrorIndicatorStroke() {
156: return this.errorIndicatorStroke;
157: }
158:
159:
171: public void setErrorIndicatorStroke(Stroke stroke) {
172: this.errorIndicatorStroke = stroke;
173: fireChangeEvent();
174: }
175:
176:
191: public void drawItem(Graphics2D g2,
192: CategoryItemRendererState state,
193: Rectangle2D dataArea,
194: CategoryPlot plot,
195: CategoryAxis domainAxis,
196: ValueAxis rangeAxis,
197: CategoryDataset data,
198: int row,
199: int column,
200: int pass) {
201:
202:
203: if (!(data instanceof StatisticalCategoryDataset)) {
204: throw new IllegalArgumentException(
205: "Requires StatisticalCategoryDataset.");
206: }
207: StatisticalCategoryDataset statData = (StatisticalCategoryDataset) data;
208:
209: PlotOrientation orientation = plot.getOrientation();
210: if (orientation == PlotOrientation.HORIZONTAL) {
211: drawHorizontalItem(g2, state, dataArea, plot, domainAxis,
212: rangeAxis, statData, row, column);
213: }
214: else if (orientation == PlotOrientation.VERTICAL) {
215: drawVerticalItem(g2, state, dataArea, plot, domainAxis, rangeAxis,
216: statData, row, column);
217: }
218: }
219:
220:
233: protected void drawHorizontalItem(Graphics2D g2,
234: CategoryItemRendererState state,
235: Rectangle2D dataArea,
236: CategoryPlot plot,
237: CategoryAxis domainAxis,
238: ValueAxis rangeAxis,
239: StatisticalCategoryDataset dataset,
240: int row,
241: int column) {
242:
243: RectangleEdge xAxisLocation = plot.getDomainAxisEdge();
244:
245:
246: double rectY = domainAxis.getCategoryStart(column, getColumnCount(),
247: dataArea, xAxisLocation);
248:
249: int seriesCount = getRowCount();
250: int categoryCount = getColumnCount();
251: if (seriesCount > 1) {
252: double seriesGap = dataArea.getHeight() * getItemMargin()
253: / (categoryCount * (seriesCount - 1));
254: rectY = rectY + row * (state.getBarWidth() + seriesGap);
255: }
256: else {
257: rectY = rectY + row * state.getBarWidth();
258: }
259:
260:
261: Number meanValue = dataset.getMeanValue(row, column);
262: if (meanValue == null) {
263: return;
264: }
265: double value = meanValue.doubleValue();
266: double base = 0.0;
267: double lclip = getLowerClip();
268: double uclip = getUpperClip();
269:
270: if (uclip <= 0.0) {
271: if (value >= uclip) {
272: return;
273: }
274: base = uclip;
275: if (value <= lclip) {
276: value = lclip;
277: }
278: }
279: else if (lclip <= 0.0) {
280: if (value >= uclip) {
281: value = uclip;
282: }
283: else {
284: if (value <= lclip) {
285: value = lclip;
286: }
287: }
288: }
289: else {
290: if (value <= lclip) {
291: return;
292: }
293: base = getLowerClip();
294: if (value >= uclip) {
295: value = uclip;
296: }
297: }
298:
299: RectangleEdge yAxisLocation = plot.getRangeAxisEdge();
300: double transY1 = rangeAxis.valueToJava2D(base, dataArea, yAxisLocation);
301: double transY2 = rangeAxis.valueToJava2D(value, dataArea,
302: yAxisLocation);
303: double rectX = Math.min(transY2, transY1);
304:
305: double rectHeight = state.getBarWidth();
306: double rectWidth = Math.abs(transY2 - transY1);
307:
308: Rectangle2D bar = new Rectangle2D.Double(rectX, rectY, rectWidth,
309: rectHeight);
310: Paint itemPaint = getItemPaint(row, column);
311: GradientPaintTransformer t = getGradientPaintTransformer();
312: if (t != null && itemPaint instanceof GradientPaint) {
313: itemPaint = t.transform((GradientPaint) itemPaint, bar);
314: }
315: g2.setPaint(itemPaint);
316: g2.fill(bar);
317:
318:
319: if (isDrawBarOutline()
320: && state.getBarWidth() > BAR_OUTLINE_WIDTH_THRESHOLD) {
321: Stroke stroke = getItemOutlineStroke(row, column);
322: Paint paint = getItemOutlinePaint(row, column);
323: if (stroke != null && paint != null) {
324: g2.setStroke(stroke);
325: g2.setPaint(paint);
326: g2.draw(bar);
327: }
328: }
329:
330:
331: Number n = dataset.getStdDevValue(row, column);
332: if (n != null) {
333: double valueDelta = n.doubleValue();
334: double highVal = rangeAxis.valueToJava2D(meanValue.doubleValue()
335: + valueDelta, dataArea, yAxisLocation);
336: double lowVal = rangeAxis.valueToJava2D(meanValue.doubleValue()
337: - valueDelta, dataArea, yAxisLocation);
338:
339: if (this.errorIndicatorPaint != null) {
340: g2.setPaint(this.errorIndicatorPaint);
341: }
342: else {
343: g2.setPaint(getItemOutlinePaint(row, column));
344: }
345: if (this.errorIndicatorStroke != null) {
346: g2.setStroke(this.errorIndicatorStroke);
347: }
348: else {
349: g2.setStroke(getItemOutlineStroke(row, column));
350: }
351: Line2D line = null;
352: line = new Line2D.Double(lowVal, rectY + rectHeight / 2.0d,
353: highVal, rectY + rectHeight / 2.0d);
354: g2.draw(line);
355: line = new Line2D.Double(highVal, rectY + rectHeight * 0.25,
356: highVal, rectY + rectHeight * 0.75);
357: g2.draw(line);
358: line = new Line2D.Double(lowVal, rectY + rectHeight * 0.25,
359: lowVal, rectY + rectHeight * 0.75);
360: g2.draw(line);
361: }
362:
363: CategoryItemLabelGenerator generator = getItemLabelGenerator(row,
364: column);
365: if (generator != null && isItemLabelVisible(row, column)) {
366: drawItemLabel(g2, dataset, row, column, plot, generator, bar,
367: (value < 0.0));
368: }
369:
370:
371: EntityCollection entities = state.getEntityCollection();
372: if (entities != null) {
373: addItemEntity(entities, dataset, row, column, bar);
374: }
375:
376: }
377:
378:
391: protected void drawVerticalItem(Graphics2D g2,
392: CategoryItemRendererState state,
393: Rectangle2D dataArea,
394: CategoryPlot plot,
395: CategoryAxis domainAxis,
396: ValueAxis rangeAxis,
397: StatisticalCategoryDataset dataset,
398: int row,
399: int column) {
400:
401: RectangleEdge xAxisLocation = plot.getDomainAxisEdge();
402:
403:
404: double rectX = domainAxis.getCategoryStart(column, getColumnCount(),
405: dataArea, xAxisLocation);
406:
407: int seriesCount = getRowCount();
408: int categoryCount = getColumnCount();
409: if (seriesCount > 1) {
410: double seriesGap = dataArea.getWidth() * getItemMargin()
411: / (categoryCount * (seriesCount - 1));
412: rectX = rectX + row * (state.getBarWidth() + seriesGap);
413: }
414: else {
415: rectX = rectX + row * state.getBarWidth();
416: }
417:
418:
419: Number meanValue = dataset.getMeanValue(row, column);
420: if (meanValue == null) {
421: return;
422: }
423:
424: double value = meanValue.doubleValue();
425: double base = 0.0;
426: double lclip = getLowerClip();
427: double uclip = getUpperClip();
428:
429: if (uclip <= 0.0) {
430: if (value >= uclip) {
431: return;
432: }
433: base = uclip;
434: if (value <= lclip) {
435: value = lclip;
436: }
437: }
438: else if (lclip <= 0.0) {
439: if (value >= uclip) {
440: value = uclip;
441: }
442: else {
443: if (value <= lclip) {
444: value = lclip;
445: }
446: }
447: }
448: else {
449: if (value <= lclip) {
450: return;
451: }
452: base = getLowerClip();
453: if (value >= uclip) {
454: value = uclip;
455: }
456: }
457:
458: RectangleEdge yAxisLocation = plot.getRangeAxisEdge();
459: double transY1 = rangeAxis.valueToJava2D(base, dataArea, yAxisLocation);
460: double transY2 = rangeAxis.valueToJava2D(value, dataArea,
461: yAxisLocation);
462: double rectY = Math.min(transY2, transY1);
463:
464: double rectWidth = state.getBarWidth();
465: double rectHeight = Math.abs(transY2 - transY1);
466:
467: Rectangle2D bar = new Rectangle2D.Double(rectX, rectY, rectWidth,
468: rectHeight);
469: Paint itemPaint = getItemPaint(row, column);
470: GradientPaintTransformer t = getGradientPaintTransformer();
471: if (t != null && itemPaint instanceof GradientPaint) {
472: itemPaint = t.transform((GradientPaint) itemPaint, bar);
473: }
474: g2.setPaint(itemPaint);
475: g2.fill(bar);
476:
477: if (isDrawBarOutline()
478: && state.getBarWidth() > BAR_OUTLINE_WIDTH_THRESHOLD) {
479: Stroke stroke = getItemOutlineStroke(row, column);
480: Paint paint = getItemOutlinePaint(row, column);
481: if (stroke != null && paint != null) {
482: g2.setStroke(stroke);
483: g2.setPaint(paint);
484: g2.draw(bar);
485: }
486: }
487:
488:
489: Number n = dataset.getStdDevValue(row, column);
490: if (n != null) {
491: double valueDelta = n.doubleValue();
492: double highVal = rangeAxis.valueToJava2D(meanValue.doubleValue()
493: + valueDelta, dataArea, yAxisLocation);
494: double lowVal = rangeAxis.valueToJava2D(meanValue.doubleValue()
495: - valueDelta, dataArea, yAxisLocation);
496:
497: if (this.errorIndicatorPaint != null) {
498: g2.setPaint(this.errorIndicatorPaint);
499: }
500: else {
501: g2.setPaint(getItemOutlinePaint(row, column));
502: }
503: if (this.errorIndicatorStroke != null) {
504: g2.setStroke(this.errorIndicatorStroke);
505: }
506: else {
507: g2.setStroke(getItemOutlineStroke(row, column));
508: }
509:
510: Line2D line = null;
511: line = new Line2D.Double(rectX + rectWidth / 2.0d, lowVal,
512: rectX + rectWidth / 2.0d, highVal);
513: g2.draw(line);
514: line = new Line2D.Double(rectX + rectWidth / 2.0d - 5.0d, highVal,
515: rectX + rectWidth / 2.0d + 5.0d, highVal);
516: g2.draw(line);
517: line = new Line2D.Double(rectX + rectWidth / 2.0d - 5.0d, lowVal,
518: rectX + rectWidth / 2.0d + 5.0d, lowVal);
519: g2.draw(line);
520: }
521:
522: CategoryItemLabelGenerator generator = getItemLabelGenerator(row,
523: column);
524: if (generator != null && isItemLabelVisible(row, column)) {
525: drawItemLabel(g2, dataset, row, column, plot, generator, bar,
526: (value < 0.0));
527: }
528:
529:
530: EntityCollection entities = state.getEntityCollection();
531: if (entities != null) {
532: addItemEntity(entities, dataset, row, column, bar);
533: }
534: }
535:
536:
543: public boolean equals(Object obj) {
544: if (obj == this) {
545: return true;
546: }
547: if (!(obj instanceof StatisticalBarRenderer)) {
548: return false;
549: }
550: StatisticalBarRenderer that = (StatisticalBarRenderer) obj;
551: if (!PaintUtilities.equal(this.errorIndicatorPaint,
552: that.errorIndicatorPaint)) {
553: return false;
554: }
555: if (!ObjectUtilities.equal(this.errorIndicatorStroke,
556: that.errorIndicatorStroke)) {
557: return false;
558: }
559: return super.equals(obj);
560: }
561:
562:
569: private void writeObject(ObjectOutputStream stream) throws IOException {
570: stream.defaultWriteObject();
571: SerialUtilities.writePaint(this.errorIndicatorPaint, stream);
572: SerialUtilities.writeStroke(this.errorIndicatorStroke, stream);
573: }
574:
575:
583: private void readObject(ObjectInputStream stream)
584: throws IOException, ClassNotFoundException {
585: stream.defaultReadObject();
586: this.errorIndicatorPaint = SerialUtilities.readPaint(stream);
587: this.errorIndicatorStroke = SerialUtilities.readStroke(stream);
588: }
589:
590: }