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