1:
62:
63: package ;
64:
65: import ;
66: import ;
67: import ;
68: import ;
69: import ;
70: import ;
71: import ;
72: import ;
73: import ;
74: import ;
75: import ;
76: import ;
77: import ;
78:
79: import ;
80: import ;
81: import ;
82: import ;
83: import ;
84: import ;
85: import ;
86: import ;
87: import ;
88: import ;
89: import ;
90: import ;
91: import ;
92: import ;
93: import ;
94: import ;
95: import ;
96: import ;
97:
98:
105: public class StackedXYAreaRenderer extends XYAreaRenderer
106: implements Cloneable,
107: PublicCloneable,
108: Serializable {
109:
110:
111: private static final long serialVersionUID = 5217394318178570889L;
112:
113:
116: static class StackedXYAreaRendererState extends XYItemRendererState {
117:
118:
119: private Polygon seriesArea;
120:
121:
122: private Line2D line;
123:
124:
125: private Stack lastSeriesPoints;
126:
127:
128: private Stack currentSeriesPoints;
129:
130:
135: public StackedXYAreaRendererState(PlotRenderingInfo info) {
136: super(info);
137: this.seriesArea = null;
138: this.line = null;
139: this.lastSeriesPoints = new Stack();
140: this.currentSeriesPoints = new Stack();
141: }
142:
143:
148: public Polygon getSeriesArea() {
149: return this.seriesArea;
150: }
151:
152:
157: public void setSeriesArea(Polygon area) {
158: this.seriesArea = area;
159: }
160:
161:
166: public Line2D getLine() {
167: return this.line;
168: }
169:
170:
175: public Stack getCurrentSeriesPoints() {
176: return this.currentSeriesPoints;
177: }
178:
179:
184: public void setCurrentSeriesPoints(Stack points) {
185: this.currentSeriesPoints = points;
186: }
187:
188:
193: public Stack getLastSeriesPoints() {
194: return this.lastSeriesPoints;
195: }
196:
197:
202: public void setLastSeriesPoints(Stack points) {
203: this.lastSeriesPoints = points;
204: }
205:
206: }
207:
208:
211: private transient Paint shapePaint = null;
212:
213:
217: private transient Stroke shapeStroke = null;
218:
219:
222: public StackedXYAreaRenderer() {
223: this(AREA);
224: }
225:
230: public StackedXYAreaRenderer(int type) {
231: this(type, null, null);
232: }
233:
234:
245: public StackedXYAreaRenderer(int type,
246: XYToolTipGenerator labelGenerator,
247: XYURLGenerator urlGenerator) {
248:
249: super(type, labelGenerator, urlGenerator);
250: }
251:
252:
258: public Paint getShapePaint() {
259: return this.shapePaint;
260: }
261:
262:
268: public Stroke getShapeStroke() {
269: return this.shapeStroke;
270: }
271:
272:
277: public void setShapePaint(Paint shapePaint) {
278: this.shapePaint = shapePaint;
279: }
280:
281:
286: public void setShapeStroke(Stroke shapeStroke) {
287: this.shapeStroke = shapeStroke;
288: }
289:
290:
305: public XYItemRendererState initialise(Graphics2D g2,
306: Rectangle2D dataArea,
307: XYPlot plot,
308: XYDataset data,
309: PlotRenderingInfo info) {
310:
311: return new StackedXYAreaRendererState(info);
312:
313: }
314:
315:
320: public int getPassCount() {
321: return 2;
322: }
323:
324:
336: public Range findRangeBounds(XYDataset dataset) {
337: if (dataset != null) {
338: return DatasetUtilities.findStackedRangeBounds(
339: (TableXYDataset) dataset);
340: }
341: else {
342: return null;
343: }
344: }
345:
346:
367: public void drawItem(Graphics2D g2,
368: XYItemRendererState state,
369: Rectangle2D dataArea,
370: PlotRenderingInfo info,
371: XYPlot plot,
372: ValueAxis domainAxis,
373: ValueAxis rangeAxis,
374: XYDataset dataset,
375: int series,
376: int item,
377: CrosshairState crosshairState,
378: int pass) {
379:
380: PlotOrientation orientation = plot.getOrientation();
381: StackedXYAreaRendererState areaState
382: = (StackedXYAreaRendererState) state;
383:
384:
385: TableXYDataset tdataset = (TableXYDataset) dataset;
386: int itemCount = tdataset.getItemCount();
387:
388:
389: double x1 = dataset.getXValue(series, item);
390: double y1 = dataset.getYValue(series, item);
391: boolean nullPoint = false;
392: if (Double.isNaN(y1)) {
393: y1 = 0.0;
394: nullPoint = true;
395: }
396:
397:
398: double ph1 = getPreviousHeight(tdataset, series, item);
399: double transX1 = domainAxis.valueToJava2D(x1, dataArea,
400: plot.getDomainAxisEdge());
401: double transY1 = rangeAxis.valueToJava2D(y1 + ph1, dataArea,
402: plot.getRangeAxisEdge());
403:
404:
405: Paint seriesPaint = getItemPaint(series, item);
406: Stroke seriesStroke = getItemStroke(series, item);
407:
408: if (pass == 0) {
409:
410:
411: if (item == 0) {
412:
413: areaState.setSeriesArea(new Polygon());
414: areaState.setLastSeriesPoints(
415: areaState.getCurrentSeriesPoints());
416: areaState.setCurrentSeriesPoints(new Stack());
417:
418:
419: double transY2 = rangeAxis.valueToJava2D(ph1, dataArea,
420: plot.getRangeAxisEdge());
421:
422:
423: if (orientation == PlotOrientation.VERTICAL) {
424: areaState.getSeriesArea().addPoint((int) transX1,
425: (int) transY2);
426: }
427: else if (orientation == PlotOrientation.HORIZONTAL) {
428: areaState.getSeriesArea().addPoint((int) transY2,
429: (int) transX1);
430: }
431: }
432:
433:
434: if (orientation == PlotOrientation.VERTICAL) {
435: Point point = new Point((int) transX1, (int) transY1);
436: areaState.getSeriesArea().addPoint((int) point.getX(),
437: (int) point.getY());
438: areaState.getCurrentSeriesPoints().push(point);
439: }
440: else if (orientation == PlotOrientation.HORIZONTAL) {
441: areaState.getSeriesArea().addPoint((int) transY1,
442: (int) transX1);
443: }
444:
445: if (getPlotLines()) {
446: if (item > 0) {
447:
448: double x0 = dataset.getXValue(series, item - 1);
449: double y0 = dataset.getYValue(series, item - 1);
450: double ph0 = getPreviousHeight(tdataset, series, item - 1);
451: double transX0 = domainAxis.valueToJava2D(x0, dataArea,
452: plot.getDomainAxisEdge());
453: double transY0 = rangeAxis.valueToJava2D(y0 + ph0,
454: dataArea, plot.getRangeAxisEdge());
455:
456: if (orientation == PlotOrientation.VERTICAL) {
457: areaState.getLine().setLine(transX0, transY0, transX1,
458: transY1);
459: }
460: else if (orientation == PlotOrientation.HORIZONTAL) {
461: areaState.getLine().setLine(transY0, transX0, transY1,
462: transX1);
463: }
464: g2.draw(areaState.getLine());
465: }
466: }
467:
468:
469:
470: if (getPlotArea() && item > 0 && item == (itemCount - 1)) {
471:
472: double transY2 = rangeAxis.valueToJava2D(ph1, dataArea,
473: plot.getRangeAxisEdge());
474:
475: if (orientation == PlotOrientation.VERTICAL) {
476:
477: areaState.getSeriesArea().addPoint((int) transX1,
478: (int) transY2);
479: }
480: else if (orientation == PlotOrientation.HORIZONTAL) {
481:
482: areaState.getSeriesArea().addPoint((int) transY2,
483: (int) transX1);
484: }
485:
486:
487:
488: if (series != 0) {
489: Stack points = areaState.getLastSeriesPoints();
490: while (!points.empty()) {
491: Point point = (Point) points.pop();
492: areaState.getSeriesArea().addPoint((int) point.getX(),
493: (int) point.getY());
494: }
495: }
496:
497:
498: g2.setPaint(seriesPaint);
499: g2.setStroke(seriesStroke);
500: g2.fill(areaState.getSeriesArea());
501:
502:
503: if (isOutline()) {
504: g2.setStroke(getSeriesOutlineStroke(series));
505: g2.setPaint(getSeriesOutlinePaint(series));
506: g2.draw(areaState.getSeriesArea());
507: }
508: }
509:
510: updateCrosshairValues(crosshairState, x1, y1, transX1, transY1,
511: orientation);
512:
513: }
514: else if (pass == 1) {
515:
516:
517:
518: Shape shape = null;
519: if (getPlotShapes()) {
520: shape = getItemShape(series, item);
521: if (plot.getOrientation() == PlotOrientation.VERTICAL) {
522: shape = ShapeUtilities.createTranslatedShape(shape,
523: transX1, transY1);
524: }
525: else if (plot.getOrientation() == PlotOrientation.HORIZONTAL) {
526: shape = ShapeUtilities.createTranslatedShape(shape,
527: transY1, transX1);
528: }
529: if (!nullPoint) {
530: if (getShapePaint() != null) {
531: g2.setPaint(getShapePaint());
532: }
533: else {
534: g2.setPaint(seriesPaint);
535: }
536: if (getShapeStroke() != null) {
537: g2.setStroke(getShapeStroke());
538: }
539: else {
540: g2.setStroke(seriesStroke);
541: }
542: g2.draw(shape);
543: }
544: }
545: else {
546: if (plot.getOrientation() == PlotOrientation.VERTICAL) {
547: shape = new Rectangle2D.Double(transX1 - 3, transY1 - 3,
548: 6.0, 6.0);
549: }
550: else if (plot.getOrientation() == PlotOrientation.HORIZONTAL) {
551: shape = new Rectangle2D.Double(transY1 - 3, transX1 - 3,
552: 6.0, 6.0);
553: }
554: }
555:
556:
557: if (state.getInfo() != null) {
558: EntityCollection entities = state.getEntityCollection();
559: if (entities != null && shape != null && !nullPoint) {
560: String tip = null;
561: XYToolTipGenerator generator
562: = getToolTipGenerator(series, item);
563: if (generator != null) {
564: tip = generator.generateToolTip(dataset, series, item);
565: }
566: String url = null;
567: if (getURLGenerator() != null) {
568: url = getURLGenerator().generateURL(dataset, series,
569: item);
570: }
571: XYItemEntity entity = new XYItemEntity(shape, dataset,
572: series, item, tip, url);
573: entities.add(entity);
574: }
575: }
576:
577: }
578: }
579:
580:
592: protected double getPreviousHeight(TableXYDataset dataset,
593: int series, int index) {
594: double result = 0.0;
595: for (int i = 0; i < series; i++) {
596: double value = dataset.getYValue(i, index);
597: if (!Double.isNaN(value)) {
598: result += value;
599: }
600: }
601: return result;
602: }
603:
604:
611: public boolean equals(Object obj) {
612: if (obj == this) {
613: return true;
614: }
615: if (!(obj instanceof StackedXYAreaRenderer) || !super.equals(obj)) {
616: return false;
617: }
618: StackedXYAreaRenderer that = (StackedXYAreaRenderer) obj;
619: if (!PaintUtilities.equal(this.shapePaint, that.shapePaint)) {
620: return false;
621: }
622: if (!ObjectUtilities.equal(this.shapeStroke, that.shapeStroke)) {
623: return false;
624: }
625: return true;
626: }
627:
628:
635: public Object clone() throws CloneNotSupportedException {
636: return super.clone();
637: }
638:
639:
647: private void readObject(ObjectInputStream stream)
648: throws IOException, ClassNotFoundException {
649: stream.defaultReadObject();
650: this.shapePaint = SerialUtilities.readPaint(stream);
651: this.shapeStroke = SerialUtilities.readStroke(stream);
652: }
653:
654:
661: private void writeObject(ObjectOutputStream stream) throws IOException {
662: stream.defaultWriteObject();
663: SerialUtilities.writePaint(this.shapePaint, stream);
664: SerialUtilities.writeStroke(this.shapeStroke, stream);
665: }
666:
667: }