Mercurial > dive4elements > river
comparison flys-artifacts/src/main/java/de/intevation/flys/jfree/EnhancedLineAndShapeRenderer.java @ 3818:dc18457b1cef
merged flys-artifacts/pre2.7-2012-03-16
author | Thomas Arendsen Hein <thomas@intevation.de> |
---|---|
date | Fri, 28 Sep 2012 12:14:59 +0200 |
parents | 74c02dbf17ca |
children | 42b05a4bed25 |
comparison
equal
deleted
inserted
replaced
2456:60ab1054069d | 3818:dc18457b1cef |
---|---|
1 package de.intevation.flys.jfree; | |
2 | |
3 import java.awt.Color; | |
4 import java.awt.Graphics2D; | |
5 import java.awt.Paint; | |
6 import java.awt.Shape; | |
7 import java.awt.geom.Rectangle2D; | |
8 import java.util.HashMap; | |
9 import java.util.Map; | |
10 | |
11 import org.apache.log4j.Logger; | |
12 | |
13 import org.jfree.chart.axis.ValueAxis; | |
14 import org.jfree.chart.entity.EntityCollection; | |
15 import org.jfree.chart.plot.CrosshairState; | |
16 import org.jfree.chart.plot.PlotOrientation; | |
17 import org.jfree.chart.plot.XYPlot; | |
18 import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer; | |
19 import org.jfree.data.xy.XYDataset; | |
20 import org.jfree.ui.RectangleEdge; | |
21 import org.jfree.util.BooleanList; | |
22 import org.jfree.util.ShapeUtilities; | |
23 | |
24 | |
25 public class EnhancedLineAndShapeRenderer extends XYLineAndShapeRenderer { | |
26 | |
27 private static final Logger logger = | |
28 Logger.getLogger(EnhancedLineAndShapeRenderer.class); | |
29 | |
30 protected BooleanList isMinimumShapeVisible; | |
31 protected BooleanList isMaximumShapeVisible; | |
32 | |
33 protected Map<Integer, Double> seriesMinimum; | |
34 protected Map<Integer, Double> seriesMaximum; | |
35 | |
36 | |
37 public EnhancedLineAndShapeRenderer(boolean lines, boolean shapes) { | |
38 super(lines, shapes); | |
39 this.isMinimumShapeVisible = new BooleanList(); | |
40 this.isMaximumShapeVisible = new BooleanList(); | |
41 this.seriesMinimum = new HashMap<Integer, Double>(); | |
42 this.seriesMaximum = new HashMap<Integer, Double>(); | |
43 } | |
44 | |
45 | |
46 public boolean getItemShapeVisible(XYDataset dataset, int series, int item){ | |
47 if (super.getItemShapeVisible(series, item)) { | |
48 return true; | |
49 } | |
50 | |
51 if (isMinimumShapeVisible(series) && isMinimum(dataset, series, item)) { | |
52 return true; | |
53 } | |
54 | |
55 if (isMaximumShapeVisible(series) && isMaximum(dataset, series, item)) { | |
56 return true; | |
57 } | |
58 | |
59 return false; | |
60 } | |
61 | |
62 | |
63 public Shape getMaximumShape(int series, int column) { | |
64 return new Rectangle2D.Double(-5d, -5d, 10d, 10d); | |
65 } | |
66 | |
67 | |
68 public Shape getMinimumShape(int series, int column) { | |
69 return new Rectangle2D.Double(-5d, -5d, 10d, 10d); | |
70 } | |
71 | |
72 | |
73 public Paint getMaximumFillPaint(int series, int column) { | |
74 Paint p = getItemPaint(series, column); | |
75 | |
76 if (p instanceof Color) { | |
77 Color c = (Color) p; | |
78 Color b = c; | |
79 | |
80 for (int i = 0; i < 2; i++) { | |
81 b = b.darker(); | |
82 } | |
83 | |
84 return b; | |
85 } | |
86 | |
87 logger.warn("Item paint is no instance of Color!"); | |
88 return p; | |
89 } | |
90 | |
91 | |
92 public Paint getMinimumFillPaint(int series, int column) { | |
93 Paint p = getItemPaint(series, column); | |
94 | |
95 if (p instanceof Color) { | |
96 Color c = (Color) p; | |
97 Color b = c; | |
98 | |
99 for (int i = 0; i < 2; i++) { | |
100 b = b.darker(); | |
101 } | |
102 | |
103 return b; | |
104 } | |
105 | |
106 logger.warn("Item paint is no instance of Color!"); | |
107 return p; | |
108 } | |
109 | |
110 | |
111 /** | |
112 * Overrides XYLineAndShapeRenderer.drawSecondaryPass() to call an adapted | |
113 * method getItemShapeVisible() which now takes an XYDataset. So, 99% of | |
114 * code equal the code in XYLineAndShapeRenderer. | |
115 */ | |
116 @Override | |
117 protected void drawSecondaryPass( | |
118 Graphics2D g2, | |
119 XYPlot plot, | |
120 XYDataset dataset, | |
121 int pass, | |
122 int series, | |
123 int item, | |
124 ValueAxis domainAxis, | |
125 Rectangle2D dataArea, | |
126 ValueAxis rangeAxis, | |
127 CrosshairState crosshairState, | |
128 EntityCollection entities | |
129 ) { | |
130 Shape entityArea = null; | |
131 | |
132 // get the data point... | |
133 double x1 = dataset.getXValue(series, item); | |
134 double y1 = dataset.getYValue(series, item); | |
135 if (Double.isNaN(y1) || Double.isNaN(x1)) { | |
136 return; | |
137 } | |
138 | |
139 PlotOrientation orientation = plot.getOrientation(); | |
140 RectangleEdge xAxisLocation = plot.getDomainAxisEdge(); | |
141 RectangleEdge yAxisLocation = plot.getRangeAxisEdge(); | |
142 double transX1 = domainAxis.valueToJava2D(x1, dataArea, xAxisLocation); | |
143 double transY1 = rangeAxis.valueToJava2D(y1, dataArea, yAxisLocation); | |
144 | |
145 if (getItemShapeVisible(dataset, series, item)) { | |
146 Shape shape = null; | |
147 | |
148 boolean isMinimum = isMinimumShapeVisible(series) | |
149 && isMinimum(dataset, series, item); | |
150 | |
151 boolean isMaximum = isMaximumShapeVisible(series) | |
152 && isMaximum(dataset, series, item); | |
153 | |
154 if (isMinimum) { | |
155 logger.debug("Create a Minimum shape."); | |
156 shape = getMinimumShape(series, item); | |
157 } | |
158 else if (isMaximum) { | |
159 logger.debug("Create a Maximum shape."); | |
160 shape = getMaximumShape(series, item); | |
161 } | |
162 else { | |
163 shape = getItemShape(series, item); | |
164 } | |
165 | |
166 if (orientation == PlotOrientation.HORIZONTAL) { | |
167 shape = ShapeUtilities.createTranslatedShape(shape, transY1, | |
168 transX1); | |
169 } | |
170 else if (orientation == PlotOrientation.VERTICAL) { | |
171 shape = ShapeUtilities.createTranslatedShape(shape, transX1, | |
172 transY1); | |
173 } | |
174 entityArea = shape; | |
175 if (shape.intersects(dataArea)) { | |
176 if (getItemShapeFilled(series, item)) { | |
177 if (getUseFillPaint()) { | |
178 g2.setPaint(getItemFillPaint(series, item)); | |
179 } | |
180 else { | |
181 g2.setPaint(getItemPaint(series, item)); | |
182 } | |
183 g2.fill(shape); | |
184 } | |
185 if (getDrawOutlines()) { | |
186 if (getUseOutlinePaint()) { | |
187 g2.setPaint(getItemOutlinePaint(series, item)); | |
188 } | |
189 else { | |
190 g2.setPaint(getItemPaint(series, item)); | |
191 } | |
192 g2.setStroke(getItemOutlineStroke(series, item)); | |
193 g2.draw(shape); | |
194 } | |
195 | |
196 if (isMinimum) { | |
197 g2.setPaint(getMinimumFillPaint(series, item)); | |
198 g2.fill(shape); | |
199 g2.setPaint(getItemOutlinePaint(series, item)); | |
200 g2.setStroke(getItemOutlineStroke(series, item)); | |
201 g2.draw(shape); | |
202 } | |
203 else if (isMaximum) { | |
204 g2.setPaint(getMaximumFillPaint(series, item)); | |
205 g2.fill(shape); | |
206 g2.setPaint(getItemOutlinePaint(series, item)); | |
207 g2.setStroke(getItemOutlineStroke(series, item)); | |
208 g2.draw(shape); | |
209 } | |
210 } | |
211 } | |
212 | |
213 double xx = transX1; | |
214 double yy = transY1; | |
215 if (orientation == PlotOrientation.HORIZONTAL) { | |
216 xx = transY1; | |
217 yy = transX1; | |
218 } | |
219 | |
220 // draw the item label if there is one... | |
221 if (isItemLabelVisible(series, item)) { | |
222 drawItemLabel(g2, orientation, dataset, series, item, xx, yy, | |
223 (y1 < 0.0)); | |
224 } | |
225 | |
226 int domainAxisIndex = plot.getDomainAxisIndex(domainAxis); | |
227 int rangeAxisIndex = plot.getRangeAxisIndex(rangeAxis); | |
228 updateCrosshairValues(crosshairState, x1, y1, domainAxisIndex, | |
229 rangeAxisIndex, transX1, transY1, orientation); | |
230 | |
231 // add an entity for the item, but only if it falls within the data | |
232 // area... | |
233 if (entities != null && isPointInRect(dataArea, xx, yy)) { | |
234 addEntity(entities, entityArea, dataset, series, item, xx, yy); | |
235 } | |
236 } | |
237 | |
238 | |
239 public void setIsMinimumShapeVisisble(int series, boolean isVisible) { | |
240 this.isMinimumShapeVisible.setBoolean(series, isVisible); | |
241 } | |
242 | |
243 | |
244 public boolean isMinimumShapeVisible(int series) { | |
245 if (this.isMinimumShapeVisible.size() <= series) { | |
246 return false; | |
247 } | |
248 | |
249 return isMinimumShapeVisible.getBoolean(series); | |
250 } | |
251 | |
252 | |
253 public void setIsMaximumShapeVisible(int series, boolean isVisible) { | |
254 this.isMaximumShapeVisible.setBoolean(series, isVisible); | |
255 } | |
256 | |
257 | |
258 public boolean isMaximumShapeVisible(int series) { | |
259 if (this.isMaximumShapeVisible.size() <= series) { | |
260 return false; | |
261 } | |
262 | |
263 return isMaximumShapeVisible.getBoolean(series); | |
264 } | |
265 | |
266 | |
267 public boolean isMinimum(XYDataset dataset, int series, int item) { | |
268 return dataset.getYValue(series, item) == getMinimum(dataset, series); | |
269 } | |
270 | |
271 | |
272 public double getMinimum(XYDataset dataset, int series) { | |
273 Integer key = Integer.valueOf(series); | |
274 Double old = seriesMinimum.get(key); | |
275 | |
276 if (old != null) { | |
277 return old.doubleValue(); | |
278 } | |
279 | |
280 logger.debug("Compute minimum of Series: " + series); | |
281 | |
282 double min = Double.MAX_VALUE; | |
283 | |
284 for (int i = 0, n = dataset.getItemCount(series); i < n; i++) { | |
285 double tmpValue = dataset.getYValue(series, i); | |
286 | |
287 if (tmpValue < min) { | |
288 min = tmpValue; | |
289 } | |
290 } | |
291 | |
292 seriesMinimum.put(key, Double.valueOf(min)); | |
293 | |
294 return min; | |
295 } | |
296 | |
297 | |
298 public boolean isMaximum(XYDataset dataset, int series, int item) { | |
299 return dataset.getYValue(series, item) == getMaximum(dataset, series); | |
300 } | |
301 | |
302 | |
303 public double getMaximum(XYDataset dataset, int series) { | |
304 Integer key = Integer.valueOf(series); | |
305 Double old = seriesMaximum.get(key); | |
306 | |
307 if (old != null) { | |
308 return old.doubleValue(); | |
309 } | |
310 | |
311 logger.debug("Compute maximum of Series: " + series); | |
312 | |
313 double max = -Double.MAX_VALUE; | |
314 | |
315 for (int i = 0, n = dataset.getItemCount(series); i < n; i++) { | |
316 double tmpValue = dataset.getYValue(series, i); | |
317 | |
318 if (tmpValue > max) { | |
319 max = tmpValue; | |
320 } | |
321 } | |
322 | |
323 seriesMaximum.put(key, Double.valueOf(max)); | |
324 | |
325 return max; | |
326 } | |
327 } | |
328 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : |