comparison flys-artifacts/src/main/java/de/intevation/flys/exports/EnhancedLineAndShapeRenderer.java @ 2072:4cdd9c4896f6

#393 Added a new Renderer and Options in Themes that allow displaying minimum and maximum of a chart series. flys-artifacts/trunk@3581 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Ingo Weinzierl <ingo.weinzierl@intevation.de>
date Wed, 04 Jan 2012 12:24:35 +0000
parents
children 27ada2e4243d
comparison
equal deleted inserted replaced
2071:fd95bfbb2ec2 2072:4cdd9c4896f6
1 package de.intevation.flys.exports;
2
3 import java.awt.Graphics2D;
4 import java.awt.Shape;
5 import java.awt.geom.Rectangle2D;
6
7 import org.apache.log4j.Logger;
8
9 import org.jfree.chart.axis.ValueAxis;
10 import org.jfree.chart.entity.EntityCollection;
11 import org.jfree.chart.plot.CrosshairState;
12 import org.jfree.chart.plot.PlotOrientation;
13 import org.jfree.chart.plot.XYPlot;
14 import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
15 import org.jfree.data.xy.XYDataset;
16 import org.jfree.ui.RectangleEdge;
17 import org.jfree.util.BooleanList;
18 import org.jfree.util.ShapeUtilities;
19
20
21 public class EnhancedLineAndShapeRenderer extends XYLineAndShapeRenderer {
22
23 private static final Logger logger =
24 Logger.getLogger(EnhancedLineAndShapeRenderer.class);
25
26 protected BooleanList isMinimumShapeVisible;
27 protected BooleanList isMaximumShapeVisible;
28
29
30 public EnhancedLineAndShapeRenderer(boolean lines, boolean shapes) {
31 super(lines, shapes);
32 this.isMinimumShapeVisible = new BooleanList();
33 this.isMaximumShapeVisible = new BooleanList();
34 }
35
36
37 public boolean getItemShapeVisible(XYDataset dataset, int series, int item){
38 if (super.getItemShapeVisible(series, item)) {
39 logger.debug("Items are visible.");
40 return true;
41 }
42
43 if (isMinimumShapeVisible(series) && isMinimum(dataset, series, item)) {
44 logger.debug("Minimum is visible for series: " + series);
45 return true;
46 }
47
48 if (isMaximumShapeVisible(series) && isMaximum(dataset, series, item)) {
49 logger.debug("Maximum is visible for series: " + series);
50 return true;
51 }
52
53 logger.debug("Nothing is visible at all.");
54
55 return false;
56 }
57
58
59 /**
60 * Overrides XYLineAndShapeRenderer.drawSecondaryPass() to call an adapted
61 * method getItemShapeVisible() which now takes an XYDataset. So, 99% of
62 * code equal the code in XYLineAndShapeRenderer.
63 */
64 @Override
65 protected void drawSecondaryPass(
66 Graphics2D g2,
67 XYPlot plot,
68 XYDataset dataset,
69 int pass,
70 int series,
71 int item,
72 ValueAxis domainAxis,
73 Rectangle2D dataArea,
74 ValueAxis rangeAxis,
75 CrosshairState crosshairState,
76 EntityCollection entities
77 ) {
78 logger.debug("Draw secondary pass");
79 Shape entityArea = null;
80
81 // get the data point...
82 double x1 = dataset.getXValue(series, item);
83 double y1 = dataset.getYValue(series, item);
84 if (Double.isNaN(y1) || Double.isNaN(x1)) {
85 return;
86 }
87
88 PlotOrientation orientation = plot.getOrientation();
89 RectangleEdge xAxisLocation = plot.getDomainAxisEdge();
90 RectangleEdge yAxisLocation = plot.getRangeAxisEdge();
91 double transX1 = domainAxis.valueToJava2D(x1, dataArea, xAxisLocation);
92 double transY1 = rangeAxis.valueToJava2D(y1, dataArea, yAxisLocation);
93
94 if (getItemShapeVisible(dataset, series, item)) {
95 Shape shape = getItemShape(series, item);
96 if (orientation == PlotOrientation.HORIZONTAL) {
97 shape = ShapeUtilities.createTranslatedShape(shape, transY1,
98 transX1);
99 }
100 else if (orientation == PlotOrientation.VERTICAL) {
101 shape = ShapeUtilities.createTranslatedShape(shape, transX1,
102 transY1);
103 }
104 entityArea = shape;
105 if (shape.intersects(dataArea)) {
106 if (getItemShapeFilled(series, item)) {
107 if (getUseFillPaint()) {
108 g2.setPaint(getItemFillPaint(series, item));
109 }
110 else {
111 g2.setPaint(getItemPaint(series, item));
112 }
113 g2.fill(shape);
114 }
115 if (getDrawOutlines()) {
116 if (getUseOutlinePaint()) {
117 g2.setPaint(getItemOutlinePaint(series, item));
118 }
119 else {
120 g2.setPaint(getItemPaint(series, item));
121 }
122 g2.setStroke(getItemOutlineStroke(series, item));
123 g2.draw(shape);
124 }
125 }
126 }
127
128 double xx = transX1;
129 double yy = transY1;
130 if (orientation == PlotOrientation.HORIZONTAL) {
131 xx = transY1;
132 yy = transX1;
133 }
134
135 // draw the item label if there is one...
136 if (isItemLabelVisible(series, item)) {
137 drawItemLabel(g2, orientation, dataset, series, item, xx, yy,
138 (y1 < 0.0));
139 }
140
141 int domainAxisIndex = plot.getDomainAxisIndex(domainAxis);
142 int rangeAxisIndex = plot.getRangeAxisIndex(rangeAxis);
143 updateCrosshairValues(crosshairState, x1, y1, domainAxisIndex,
144 rangeAxisIndex, transX1, transY1, orientation);
145
146 // add an entity for the item, but only if it falls within the data
147 // area...
148 if (entities != null && isPointInRect(dataArea, xx, yy)) {
149 addEntity(entities, entityArea, dataset, series, item, xx, yy);
150 }
151 }
152
153
154 public void setIsMinimumShapeVisisble(int series, boolean isVisible) {
155 this.isMinimumShapeVisible.setBoolean(series, isVisible);
156 }
157
158
159 public boolean isMinimumShapeVisible(int series) {
160 return isMinimumShapeVisible.getBoolean(series);
161 }
162
163
164 public void setIsMaximumShapeVisible(int series, boolean isVisible) {
165 this.isMaximumShapeVisible.setBoolean(series, isVisible);
166 }
167
168
169 public boolean isMaximumShapeVisible(int series) {
170 return isMaximumShapeVisible.getBoolean(series);
171 }
172
173
174 public static boolean isMinimum(XYDataset dataset, int series, int item) {
175 return dataset.getYValue(series, item) == getMinimum(dataset, series);
176 }
177
178
179 public static double getMinimum(XYDataset dataset, int series) {
180 double min = Double.MAX_VALUE;
181
182 for (int i = 0, n = dataset.getItemCount(series); i < n; i++) {
183 double tmpValue = dataset.getYValue(series, i);
184
185 if (tmpValue < min) {
186 min = tmpValue;
187 }
188 }
189
190 return min;
191 }
192
193
194 public static boolean isMaximum(XYDataset dataset, int series, int item) {
195 return dataset.getYValue(series, item) == getMaximum(dataset, series);
196 }
197
198
199 public static double getMaximum(XYDataset dataset, int series) {
200 double max = -Double.MAX_VALUE;
201
202 for (int i = 0, n = dataset.getItemCount(series); i < n; i++) {
203 double tmpValue = dataset.getYValue(series, i);
204
205 if (tmpValue > max) {
206 max = tmpValue;
207 }
208 }
209
210 return max;
211 }
212 }
213 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org