1:
78:
79: package ;
80:
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:
94: import ;
95: import ;
96: import ;
97: import ;
98: import ;
99: import ;
100: import ;
101: import ;
102: import ;
103: import ;
104: import ;
105: import ;
106: import ;
107: import ;
108: import ;
109:
110:
115: public class XYAreaRenderer extends AbstractXYItemRenderer
116: implements XYItemRenderer,
117: Cloneable,
118: PublicCloneable,
119: Serializable {
120:
121:
122: private static final long serialVersionUID = -4481971353973876747L;
123:
124:
127: static class XYAreaRendererState extends XYItemRendererState {
128:
129:
130: public Polygon area;
131:
132:
133: public Line2D line;
134:
135:
140: public XYAreaRendererState(PlotRenderingInfo info) {
141: super(info);
142: this.area = new Polygon();
143: this.line = new Line2D.Double();
144: }
145:
146: }
147:
148:
149: public static final int SHAPES = 1;
150:
151:
152: public static final int LINES = 2;
153:
154:
157: public static final int SHAPES_AND_LINES = 3;
158:
159:
160: public static final int AREA = 4;
161:
162:
165: public static final int AREA_AND_SHAPES = 5;
166:
167:
168: private boolean plotShapes;
169:
170:
171: private boolean plotLines;
172:
173:
174: private boolean plotArea;
175:
176:
177: private boolean showOutline;
178:
179:
183: private transient Shape legendArea;
184:
185:
188: public XYAreaRenderer() {
189: this(AREA);
190: }
191:
192:
197: public XYAreaRenderer(int type) {
198: this(type, null, null);
199: }
200:
201:
212: public XYAreaRenderer(int type, XYToolTipGenerator toolTipGenerator,
213: XYURLGenerator urlGenerator) {
214:
215: super();
216: setBaseToolTipGenerator(toolTipGenerator);
217: setURLGenerator(urlGenerator);
218:
219: if (type == SHAPES) {
220: this.plotShapes = true;
221: }
222: if (type == LINES) {
223: this.plotLines = true;
224: }
225: if (type == SHAPES_AND_LINES) {
226: this.plotShapes = true;
227: this.plotLines = true;
228: }
229: if (type == AREA) {
230: this.plotArea = true;
231: }
232: if (type == AREA_AND_SHAPES) {
233: this.plotArea = true;
234: this.plotShapes = true;
235: }
236: this.showOutline = false;
237: GeneralPath area = new GeneralPath();
238: area.moveTo(0.0f, -4.0f);
239: area.lineTo(3.0f, -2.0f);
240: area.lineTo(4.0f, 4.0f);
241: area.lineTo(-4.0f, 4.0f);
242: area.lineTo(-3.0f, -2.0f);
243: area.closePath();
244: this.legendArea = area;
245:
246: }
247:
248:
253: public boolean getPlotShapes() {
254: return this.plotShapes;
255: }
256:
257:
262: public boolean getPlotLines() {
263: return this.plotLines;
264: }
265:
266:
271: public boolean getPlotArea() {
272: return this.plotArea;
273: }
274:
275:
283: public boolean isOutline() {
284: return this.showOutline;
285: }
286:
287:
295: public void setOutline(boolean show) {
296: this.showOutline = show;
297: fireChangeEvent();
298: }
299:
300:
305: public Shape getLegendArea() {
306: return this.legendArea;
307: }
308:
309:
315: public void setLegendArea(Shape area) {
316: if (area == null) {
317: throw new IllegalArgumentException("Null 'area' argument.");
318: }
319: this.legendArea = area;
320: fireChangeEvent();
321: }
322:
323:
336: public XYItemRendererState initialise(Graphics2D g2, Rectangle2D dataArea,
337: XYPlot plot, XYDataset data, PlotRenderingInfo info) {
338: XYAreaRendererState state = new XYAreaRendererState(info);
339:
340:
341:
342: state.setProcessVisibleItemsOnly(false);
343: return state;
344: }
345:
346:
355: public LegendItem getLegendItem(int datasetIndex, int series) {
356: LegendItem result = null;
357: XYPlot xyplot = getPlot();
358: if (xyplot != null) {
359: XYDataset dataset = xyplot.getDataset(datasetIndex);
360: if (dataset != null) {
361: XYSeriesLabelGenerator lg = getLegendItemLabelGenerator();
362: String label = lg.generateLabel(dataset, series);
363: String description = label;
364: String toolTipText = null;
365: if (getLegendItemToolTipGenerator() != null) {
366: toolTipText = getLegendItemToolTipGenerator().generateLabel(
367: dataset, series);
368: }
369: String urlText = null;
370: if (getLegendItemURLGenerator() != null) {
371: urlText = getLegendItemURLGenerator().generateLabel(
372: dataset, series);
373: }
374: Paint paint = lookupSeriesPaint(series);
375: result = new LegendItem(label, description, toolTipText,
376: urlText, this.legendArea, paint);
377: result.setDataset(dataset);
378: result.setDatasetIndex(datasetIndex);
379: result.setSeriesKey(dataset.getSeriesKey(series));
380: result.setSeriesIndex(series);
381: }
382: }
383: return result;
384: }
385:
386:
404: public void drawItem(Graphics2D g2, XYItemRendererState state,
405: Rectangle2D dataArea, PlotRenderingInfo info, XYPlot plot,
406: ValueAxis domainAxis, ValueAxis rangeAxis, XYDataset dataset,
407: int series, int item, CrosshairState crosshairState, int pass) {
408:
409: if (!getItemVisible(series, item)) {
410: return;
411: }
412: XYAreaRendererState areaState = (XYAreaRendererState) state;
413:
414:
415: double x1 = dataset.getXValue(series, item);
416: double y1 = dataset.getYValue(series, item);
417: if (Double.isNaN(y1)) {
418: y1 = 0.0;
419: }
420: double transX1 = domainAxis.valueToJava2D(x1, dataArea,
421: plot.getDomainAxisEdge());
422: double transY1 = rangeAxis.valueToJava2D(y1, dataArea,
423: plot.getRangeAxisEdge());
424:
425:
426:
427: int itemCount = dataset.getItemCount(series);
428: double x0 = dataset.getXValue(series, Math.max(item - 1, 0));
429: double y0 = dataset.getYValue(series, Math.max(item - 1, 0));
430: if (Double.isNaN(y0)) {
431: y0 = 0.0;
432: }
433: double transX0 = domainAxis.valueToJava2D(x0, dataArea,
434: plot.getDomainAxisEdge());
435: double transY0 = rangeAxis.valueToJava2D(y0, dataArea,
436: plot.getRangeAxisEdge());
437:
438: double x2 = dataset.getXValue(series, Math.min(item + 1,
439: itemCount - 1));
440: double y2 = dataset.getYValue(series, Math.min(item + 1,
441: itemCount - 1));
442: if (Double.isNaN(y2)) {
443: y2 = 0.0;
444: }
445: double transX2 = domainAxis.valueToJava2D(x2, dataArea,
446: plot.getDomainAxisEdge());
447: double transY2 = rangeAxis.valueToJava2D(y2, dataArea,
448: plot.getRangeAxisEdge());
449:
450: double transZero = rangeAxis.valueToJava2D(0.0, dataArea,
451: plot.getRangeAxisEdge());
452: Polygon hotspot = null;
453: if (plot.getOrientation() == PlotOrientation.HORIZONTAL) {
454: hotspot = new Polygon();
455: hotspot.addPoint((int) transZero,
456: (int) ((transX0 + transX1) / 2.0));
457: hotspot.addPoint((int) ((transY0 + transY1) / 2.0),
458: (int) ((transX0 + transX1) / 2.0));
459: hotspot.addPoint((int) transY1, (int) transX1);
460: hotspot.addPoint((int) ((transY1 + transY2) / 2.0),
461: (int) ((transX1 + transX2) / 2.0));
462: hotspot.addPoint((int) transZero,
463: (int) ((transX1 + transX2) / 2.0));
464: }
465: else {
466: hotspot = new Polygon();
467: hotspot.addPoint((int) ((transX0 + transX1) / 2.0),
468: (int) transZero);
469: hotspot.addPoint((int) ((transX0 + transX1) / 2.0),
470: (int) ((transY0 + transY1) / 2.0));
471: hotspot.addPoint((int) transX1, (int) transY1);
472: hotspot.addPoint((int) ((transX1 + transX2) / 2.0),
473: (int) ((transY1 + transY2) / 2.0));
474: hotspot.addPoint((int) ((transX1 + transX2) / 2.0),
475: (int) transZero);
476: }
477:
478: if (item == 0) {
479: areaState.area = new Polygon();
480:
481: double zero = rangeAxis.valueToJava2D(0.0, dataArea,
482: plot.getRangeAxisEdge());
483: if (plot.getOrientation() == PlotOrientation.VERTICAL) {
484: areaState.area.addPoint((int) transX1, (int) zero);
485: }
486: else if (plot.getOrientation() == PlotOrientation.HORIZONTAL) {
487: areaState.area.addPoint((int) zero, (int) transX1);
488: }
489: }
490:
491:
492: if (plot.getOrientation() == PlotOrientation.VERTICAL) {
493: areaState.area.addPoint((int) transX1, (int) transY1);
494: }
495: else if (plot.getOrientation() == PlotOrientation.HORIZONTAL) {
496: areaState.area.addPoint((int) transY1, (int) transX1);
497: }
498:
499: PlotOrientation orientation = plot.getOrientation();
500: Paint paint = getItemPaint(series, item);
501: Stroke stroke = getItemStroke(series, item);
502: g2.setPaint(paint);
503: g2.setStroke(stroke);
504:
505: Shape shape = null;
506: if (getPlotShapes()) {
507: shape = getItemShape(series, item);
508: if (orientation == PlotOrientation.VERTICAL) {
509: shape = ShapeUtilities.createTranslatedShape(shape, transX1,
510: transY1);
511: }
512: else if (orientation == PlotOrientation.HORIZONTAL) {
513: shape = ShapeUtilities.createTranslatedShape(shape, transY1,
514: transX1);
515: }
516: g2.draw(shape);
517: }
518:
519: if (getPlotLines()) {
520: if (item > 0) {
521: if (plot.getOrientation() == PlotOrientation.VERTICAL) {
522: areaState.line.setLine(transX0, transY0, transX1, transY1);
523: }
524: else if (plot.getOrientation() == PlotOrientation.HORIZONTAL) {
525: areaState.line.setLine(transY0, transX0, transY1, transX1);
526: }
527: g2.draw(areaState.line);
528: }
529: }
530:
531:
532:
533: if (getPlotArea() && item > 0 && item == (itemCount - 1)) {
534:
535: if (orientation == PlotOrientation.VERTICAL) {
536:
537: areaState.area.addPoint((int) transX1, (int) transZero);
538: }
539: else if (orientation == PlotOrientation.HORIZONTAL) {
540:
541: areaState.area.addPoint((int) transZero, (int) transX1);
542: }
543:
544: g2.fill(areaState.area);
545:
546:
547: if (isOutline()) {
548: g2.setStroke(getItemOutlineStroke(series, item));
549: g2.setPaint(getItemOutlinePaint(series, item));
550: g2.draw(areaState.area);
551: }
552: }
553:
554: int domainAxisIndex = plot.getDomainAxisIndex(domainAxis);
555: int rangeAxisIndex = plot.getRangeAxisIndex(rangeAxis);
556: updateCrosshairValues(crosshairState, x1, y1, domainAxisIndex,
557: rangeAxisIndex, transX1, transY1, orientation);
558:
559:
560: EntityCollection entities = state.getEntityCollection();
561: if (entities != null && hotspot != null) {
562: addEntity(entities, hotspot, dataset, series, item, 0.0, 0.0);
563: }
564:
565: }
566:
567:
574: public Object clone() throws CloneNotSupportedException {
575: XYAreaRenderer clone = (XYAreaRenderer) super.clone();
576: clone.legendArea = ShapeUtilities.clone(this.legendArea);
577: return clone;
578: }
579:
580:
587: public boolean equals(Object obj) {
588: if (obj == this) {
589: return true;
590: }
591: if (!(obj instanceof XYAreaRenderer)) {
592: return false;
593: }
594: XYAreaRenderer that = (XYAreaRenderer) obj;
595: if (this.plotArea != that.plotArea) {
596: return false;
597: }
598: if (this.plotLines != that.plotLines) {
599: return false;
600: }
601: if (this.plotShapes != that.plotShapes) {
602: return false;
603: }
604: if (this.showOutline != that.showOutline) {
605: return false;
606: }
607: if (!ShapeUtilities.equal(this.legendArea, that.legendArea)) {
608: return false;
609: }
610: return true;
611: }
612:
613:
621: private void readObject(ObjectInputStream stream)
622: throws IOException, ClassNotFoundException {
623: stream.defaultReadObject();
624: this.legendArea = SerialUtilities.readShape(stream);
625: }
626:
627:
634: private void writeObject(ObjectOutputStream stream) throws IOException {
635: stream.defaultWriteObject();
636: SerialUtilities.writeShape(this.legendArea, stream);
637: }
638: }