1:
76:
77: package ;
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:
92: import ;
93: import ;
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:
109:
114: public class XYAreaRenderer extends AbstractXYItemRenderer
115: implements XYItemRenderer,
116: Cloneable,
117: PublicCloneable,
118: Serializable {
119:
120:
121: private static final long serialVersionUID = -4481971353973876747L;
122:
123:
126: static class XYAreaRendererState extends XYItemRendererState {
127:
128:
129: public Polygon area;
130:
131:
132: public Line2D line;
133:
134:
139: public XYAreaRendererState(PlotRenderingInfo info) {
140: super(info);
141: this.area = new Polygon();
142: this.line = new Line2D.Double();
143: }
144:
145: }
146:
147:
148: public static final int SHAPES = 1;
149:
150:
151: public static final int LINES = 2;
152:
153:
156: public static final int SHAPES_AND_LINES = 3;
157:
158:
159: public static final int AREA = 4;
160:
161:
164: public static final int AREA_AND_SHAPES = 5;
165:
166:
167: private boolean plotShapes;
168:
169:
170: private boolean plotLines;
171:
172:
173: private boolean plotArea;
174:
175:
176: private boolean showOutline;
177:
178:
182: private transient Shape legendArea;
183:
184:
187: public XYAreaRenderer() {
188: this(AREA);
189: }
190:
191:
196: public XYAreaRenderer(int type) {
197: this(type, null, null);
198: }
199:
200:
211: public XYAreaRenderer(int type, XYToolTipGenerator toolTipGenerator,
212: XYURLGenerator urlGenerator) {
213:
214: super();
215: setBaseToolTipGenerator(toolTipGenerator);
216: setURLGenerator(urlGenerator);
217:
218: if (type == SHAPES) {
219: this.plotShapes = true;
220: }
221: if (type == LINES) {
222: this.plotLines = true;
223: }
224: if (type == SHAPES_AND_LINES) {
225: this.plotShapes = true;
226: this.plotLines = true;
227: }
228: if (type == AREA) {
229: this.plotArea = true;
230: }
231: if (type == AREA_AND_SHAPES) {
232: this.plotArea = true;
233: this.plotShapes = true;
234: }
235: this.showOutline = false;
236: GeneralPath area = new GeneralPath();
237: area.moveTo(0.0f, -4.0f);
238: area.lineTo(3.0f, -2.0f);
239: area.lineTo(4.0f, 4.0f);
240: area.lineTo(-4.0f, 4.0f);
241: area.lineTo(-3.0f, -2.0f);
242: area.closePath();
243: this.legendArea = area;
244:
245: }
246:
247:
252: public boolean getPlotShapes() {
253: return this.plotShapes;
254: }
255:
256:
261: public boolean getPlotLines() {
262: return this.plotLines;
263: }
264:
265:
270: public boolean getPlotArea() {
271: return this.plotArea;
272: }
273:
274:
282: public boolean isOutline() {
283: return this.showOutline;
284: }
285:
286:
294: public void setOutline(boolean show) {
295: this.showOutline = show;
296: notifyListeners(new RendererChangeEvent(this));
297: }
298:
299:
304: public Shape getLegendArea() {
305: return this.legendArea;
306: }
307:
308:
314: public void setLegendArea(Shape area) {
315: if (area == null) {
316: throw new IllegalArgumentException("Null 'area' argument.");
317: }
318: this.legendArea = area;
319: notifyListeners(new RendererChangeEvent(this));
320: }
321:
322:
335: public XYItemRendererState initialise(Graphics2D g2, Rectangle2D dataArea,
336: XYPlot plot, XYDataset data, PlotRenderingInfo info) {
337: XYAreaRendererState state = new XYAreaRendererState(info);
338: return state;
339: }
340:
341:
350: public LegendItem getLegendItem(int datasetIndex, int series) {
351: LegendItem result = null;
352: XYPlot xyplot = getPlot();
353: if (xyplot != null) {
354: XYDataset dataset = xyplot.getDataset(datasetIndex);
355: if (dataset != null) {
356: XYSeriesLabelGenerator lg = getLegendItemLabelGenerator();
357: String label = lg.generateLabel(dataset, series);
358: String description = label;
359: String toolTipText = null;
360: if (getLegendItemToolTipGenerator() != null) {
361: toolTipText = getLegendItemToolTipGenerator().generateLabel(
362: dataset, series);
363: }
364: String urlText = null;
365: if (getLegendItemURLGenerator() != null) {
366: urlText = getLegendItemURLGenerator().generateLabel(
367: dataset, series);
368: }
369: Paint paint = getSeriesPaint(series);
370: result = new LegendItem(label, description, toolTipText,
371: urlText, this.legendArea, paint);
372: }
373: }
374: return result;
375: }
376:
377:
395: public void drawItem(Graphics2D g2, XYItemRendererState state,
396: Rectangle2D dataArea, PlotRenderingInfo info, XYPlot plot,
397: ValueAxis domainAxis, ValueAxis rangeAxis, XYDataset dataset,
398: int series, int item, CrosshairState crosshairState, int pass) {
399:
400: if (!getItemVisible(series, item)) {
401: return;
402: }
403: XYAreaRendererState areaState = (XYAreaRendererState) state;
404:
405:
406: double x1 = dataset.getXValue(series, item);
407: double y1 = dataset.getYValue(series, item);
408: if (Double.isNaN(y1)) {
409: y1 = 0.0;
410: }
411: double transX1 = domainAxis.valueToJava2D(x1, dataArea,
412: plot.getDomainAxisEdge());
413: double transY1 = rangeAxis.valueToJava2D(y1, dataArea,
414: plot.getRangeAxisEdge());
415:
416:
417:
418: int itemCount = dataset.getItemCount(series);
419: double x0 = dataset.getXValue(series, Math.max(item - 1, 0));
420: double y0 = dataset.getYValue(series, Math.max(item - 1, 0));
421: if (Double.isNaN(y0)) {
422: y0 = 0.0;
423: }
424: double transX0 = domainAxis.valueToJava2D(x0, dataArea,
425: plot.getDomainAxisEdge());
426: double transY0 = rangeAxis.valueToJava2D(y0, dataArea,
427: plot.getRangeAxisEdge());
428:
429: double x2 = dataset.getXValue(series, Math.min(item + 1,
430: itemCount - 1));
431: double y2 = dataset.getYValue(series, Math.min(item + 1,
432: itemCount - 1));
433: if (Double.isNaN(y2)) {
434: y2 = 0.0;
435: }
436: double transX2 = domainAxis.valueToJava2D(x2, dataArea,
437: plot.getDomainAxisEdge());
438: double transY2 = rangeAxis.valueToJava2D(y2, dataArea,
439: plot.getRangeAxisEdge());
440:
441: double transZero = rangeAxis.valueToJava2D(0.0, dataArea,
442: plot.getRangeAxisEdge());
443: Polygon hotspot = null;
444: if (plot.getOrientation() == PlotOrientation.HORIZONTAL) {
445: hotspot = new Polygon();
446: hotspot.addPoint((int) transZero,
447: (int) ((transX0 + transX1) / 2.0));
448: hotspot.addPoint((int) ((transY0 + transY1) / 2.0),
449: (int) ((transX0 + transX1) / 2.0));
450: hotspot.addPoint((int) transY1, (int) transX1);
451: hotspot.addPoint((int) ((transY1 + transY2) / 2.0),
452: (int) ((transX1 + transX2) / 2.0));
453: hotspot.addPoint((int) transZero,
454: (int) ((transX1 + transX2) / 2.0));
455: }
456: else {
457: hotspot = new Polygon();
458: hotspot.addPoint((int) ((transX0 + transX1) / 2.0),
459: (int) transZero);
460: hotspot.addPoint((int) ((transX0 + transX1) / 2.0),
461: (int) ((transY0 + transY1) / 2.0));
462: hotspot.addPoint((int) transX1, (int) transY1);
463: hotspot.addPoint((int) ((transX1 + transX2) / 2.0),
464: (int) ((transY1 + transY2) / 2.0));
465: hotspot.addPoint((int) ((transX1 + transX2) / 2.0),
466: (int) transZero);
467: }
468:
469: if (item == 0) {
470: areaState.area = new Polygon();
471:
472: double zero = rangeAxis.valueToJava2D(0.0, dataArea,
473: plot.getRangeAxisEdge());
474: if (plot.getOrientation() == PlotOrientation.VERTICAL) {
475: areaState.area.addPoint((int) transX1, (int) zero);
476: }
477: else if (plot.getOrientation() == PlotOrientation.HORIZONTAL) {
478: areaState.area.addPoint((int) zero, (int) transX1);
479: }
480: }
481:
482:
483: if (plot.getOrientation() == PlotOrientation.VERTICAL) {
484: areaState.area.addPoint((int) transX1, (int) transY1);
485: }
486: else if (plot.getOrientation() == PlotOrientation.HORIZONTAL) {
487: areaState.area.addPoint((int) transY1, (int) transX1);
488: }
489:
490: PlotOrientation orientation = plot.getOrientation();
491: Paint paint = getItemPaint(series, item);
492: Stroke stroke = getItemStroke(series, item);
493: g2.setPaint(paint);
494: g2.setStroke(stroke);
495:
496: Shape shape = null;
497: if (getPlotShapes()) {
498: shape = getItemShape(series, item);
499: if (orientation == PlotOrientation.VERTICAL) {
500: shape = ShapeUtilities.createTranslatedShape(shape, transX1,
501: transY1);
502: }
503: else if (orientation == PlotOrientation.HORIZONTAL) {
504: shape = ShapeUtilities.createTranslatedShape(shape, transY1,
505: transX1);
506: }
507: g2.draw(shape);
508: }
509:
510: if (getPlotLines()) {
511: if (item > 0) {
512: if (plot.getOrientation() == PlotOrientation.VERTICAL) {
513: areaState.line.setLine(transX0, transY0, transX1, transY1);
514: }
515: else if (plot.getOrientation() == PlotOrientation.HORIZONTAL) {
516: areaState.line.setLine(transY0, transX0, transY1, transX1);
517: }
518: g2.draw(areaState.line);
519: }
520: }
521:
522:
523:
524: if (getPlotArea() && item > 0 && item == (itemCount - 1)) {
525:
526: if (orientation == PlotOrientation.VERTICAL) {
527:
528: areaState.area.addPoint((int) transX1, (int) transZero);
529: }
530: else if (orientation == PlotOrientation.HORIZONTAL) {
531:
532: areaState.area.addPoint((int) transZero, (int) transX1);
533: }
534:
535: g2.fill(areaState.area);
536:
537:
538: if (isOutline()) {
539: g2.setStroke(getItemOutlineStroke(series, item));
540: g2.setPaint(getItemOutlinePaint(series, item));
541: g2.draw(areaState.area);
542: }
543: }
544:
545: int domainAxisIndex = plot.getDomainAxisIndex(domainAxis);
546: int rangeAxisIndex = plot.getRangeAxisIndex(rangeAxis);
547: updateCrosshairValues(crosshairState, x1, y1, domainAxisIndex,
548: rangeAxisIndex, transX1, transY1, orientation);
549:
550:
551: if (state.getInfo() != null) {
552: EntityCollection entities = state.getEntityCollection();
553: if (entities != null && hotspot != null) {
554: String tip = null;
555: XYToolTipGenerator generator
556: = getToolTipGenerator(series, item);
557: if (generator != null) {
558: tip = generator.generateToolTip(dataset, series, item);
559: }
560: String url = null;
561: if (getURLGenerator() != null) {
562: url = getURLGenerator().generateURL(dataset, series, item);
563: }
564: XYItemEntity entity = new XYItemEntity(hotspot, dataset,
565: series, item, tip, url);
566: entities.add(entity);
567: }
568: }
569:
570: }
571:
572:
579: public Object clone() throws CloneNotSupportedException {
580: XYAreaRenderer clone = (XYAreaRenderer) super.clone();
581: clone.legendArea = ShapeUtilities.clone(this.legendArea);
582: return clone;
583: }
584:
585:
592: public boolean equals(Object obj) {
593: if (obj == this) {
594: return true;
595: }
596: if (!(obj instanceof XYAreaRenderer)) {
597: return false;
598: }
599: XYAreaRenderer that = (XYAreaRenderer) obj;
600: if (this.plotArea != that.plotArea) {
601: return false;
602: }
603: if (this.plotLines != that.plotLines) {
604: return false;
605: }
606: if (this.plotShapes != that.plotShapes) {
607: return false;
608: }
609: if (this.showOutline != that.showOutline) {
610: return false;
611: }
612: if (!ShapeUtilities.equal(this.legendArea, that.legendArea)) {
613: return false;
614: }
615: return true;
616: }
617:
618:
626: private void readObject(ObjectInputStream stream)
627: throws IOException, ClassNotFoundException {
628: stream.defaultReadObject();
629: this.legendArea = SerialUtilities.readShape(stream);
630: }
631:
632:
639: private void writeObject(ObjectOutputStream stream) throws IOException {
640: stream.defaultWriteObject();
641: SerialUtilities.writeShape(this.legendArea, stream);
642: }
643: }