Mercurial > dive4elements > river
comparison artifacts/src/main/java/org/dive4elements/river/jfree/AnnotationHelper.java @ 8341:130160b8d245
Introduce annotations, which know to which axis they belong.
author | Tom Gottfried <tom@intevation.de> |
---|---|
date | Tue, 30 Sep 2014 11:50:43 +0200 |
parents | c086b06b81e5 |
children | 31272d799dad |
comparison
equal
deleted
inserted
replaced
8340:8679875f2c09 | 8341:130160b8d245 |
---|---|
8 package org.dive4elements.river.jfree; | 8 package org.dive4elements.river.jfree; |
9 | 9 |
10 import org.dive4elements.river.themes.ThemeDocument; | 10 import org.dive4elements.river.themes.ThemeDocument; |
11 | 11 |
12 import java.util.List; | 12 import java.util.List; |
13 import java.util.ArrayList; | |
13 import java.util.Map; | 14 import java.util.Map; |
15 import java.util.SortedMap; | |
16 import java.util.TreeMap; | |
14 | 17 |
15 import java.awt.BasicStroke; | 18 import java.awt.BasicStroke; |
16 import java.awt.Color; | 19 import java.awt.Color; |
17 import java.awt.Font; | 20 import java.awt.Font; |
18 | 21 |
20 import org.jfree.chart.plot.XYPlot; | 23 import org.jfree.chart.plot.XYPlot; |
21 import org.jfree.chart.LegendItem; | 24 import org.jfree.chart.LegendItem; |
22 import org.jfree.chart.LegendItemCollection; | 25 import org.jfree.chart.LegendItemCollection; |
23 import org.jfree.chart.annotations.XYTextAnnotation; | 26 import org.jfree.chart.annotations.XYTextAnnotation; |
24 import org.jfree.chart.annotations.XYLineAnnotation; | 27 import org.jfree.chart.annotations.XYLineAnnotation; |
28 import org.jfree.chart.renderer.xy.XYItemRenderer; | |
25 | 29 |
26 import org.dive4elements.river.themes.LineStyle; | 30 import org.dive4elements.river.themes.LineStyle; |
27 import org.dive4elements.river.themes.TextStyle; | 31 import org.dive4elements.river.themes.TextStyle; |
28 import org.dive4elements.river.exports.ChartSettings; | 32 import org.dive4elements.river.exports.ChartSettings; |
29 import org.dive4elements.river.exports.LegendSection; | 33 import org.dive4elements.river.exports.LegendSection; |
39 | 43 |
40 /* arr this would be better in chartsettings */ | 44 /* arr this would be better in chartsettings */ |
41 public static final int DEFAULT_FONT_SIZE = 12; | 45 public static final int DEFAULT_FONT_SIZE = 12; |
42 public static final String DEFAULT_FONT_NAME = "Tahoma"; | 46 public static final String DEFAULT_FONT_NAME = "Tahoma"; |
43 | 47 |
48 | |
49 public static void addYAnnotationsToRenderer( | |
50 SortedMap<Integer, RiverAnnotation> yAnnotations, | |
51 XYPlot plot, | |
52 ChartSettings settings, | |
53 Map<Integer, AxisDataset> datasets | |
54 ) { | |
55 List<RiverAnnotation> annotations = new ArrayList<RiverAnnotation>(); | |
56 | |
57 for (Map.Entry<Integer, RiverAnnotation> entry: | |
58 yAnnotations.entrySet()) { | |
59 int axis = entry.getKey(); | |
60 AxisDataset dataset = datasets.get(new Integer(axis)); | |
61 | |
62 if (dataset == null || dataset.getRange() == null) { | |
63 log.warn("No dataset available and active for axis " + axis); | |
64 } | |
65 else { | |
66 RiverAnnotation ya = entry.getValue(); | |
67 for (StickyAxisAnnotation sta: ya.getAxisTextAnnotations()) { | |
68 sta.setAxisSymbol(axis); | |
69 } | |
70 annotations.add(ya); | |
71 } | |
72 } | |
73 | |
74 addAnnotationsToRenderer(annotations, plot, settings, datasets); | |
75 } | |
76 | |
44 /** | 77 /** |
45 * Add annotations (Sticky, Text and hyk zones) to a plot. | 78 * Add annotations (Sticky, Text and hyk zones) to a plot. |
46 * @param annotations Annotations to add | 79 * @param annotations Annotations to add |
47 * @param plot Plot to add annotations to. | 80 * @param plot XYPlot to add annotations to. |
48 * @param settings ChartSettings object for settings. | 81 * @param settings ChartSettings object for settings. |
49 */ | 82 * @param datasets Map of axis index and datasets |
50 public static void addAnnotationsToRenderer(List<RiverAnnotation> annotations, | 83 */ |
51 XYPlot plot, ChartSettings settings, Map<Integer, AxisDataset> datasets) { | 84 public static void addAnnotationsToRenderer( |
52 log.debug("addAnnotationsToRenderer"); | 85 List<RiverAnnotation> annotations, |
53 | 86 XYPlot plot, |
87 ChartSettings settings, | |
88 Map<Integer, AxisDataset> datasets | |
89 ) { | |
54 if (annotations == null || annotations.isEmpty()) { | 90 if (annotations == null || annotations.isEmpty()) { |
55 log.debug("addAnnotationsToRenderer: no annotations."); | 91 log.debug("addAnnotationsToRenderer: no annotations."); |
56 return; | 92 return; |
57 } | 93 } |
58 | 94 |
67 // Access text styling, if any. | 103 // Access text styling, if any. |
68 ThemeDocument theme = fa.getTheme(); | 104 ThemeDocument theme = fa.getTheme(); |
69 TextStyle textStyle = null; | 105 TextStyle textStyle = null; |
70 LineStyle lineStyle = null; | 106 LineStyle lineStyle = null; |
71 | 107 |
72 // Get Themeing information and add legend item. | 108 // Get Theming information and add legend item. |
73 if (theme != null) { | 109 if (theme != null) { |
74 textStyle = theme.parseComplexTextStyle(); | 110 textStyle = theme.parseComplexTextStyle(); |
75 lineStyle = theme.parseComplexLineStyle(); | 111 lineStyle = theme.parseComplexLineStyle(); |
76 if (fa.getLabel() != null) { | 112 if (fa.getLabel() != null) { |
77 // Legend handling, maybe misplaced? | 113 // Legend handling, maybe misplaced? |
148 final float TEXT_OFF = 0.03f; | 184 final float TEXT_OFF = 0.03f; |
149 | 185 |
150 XYLineAnnotation lineAnnotation = null; | 186 XYLineAnnotation lineAnnotation = null; |
151 XYTextAnnotation textAnnotation = null; | 187 XYTextAnnotation textAnnotation = null; |
152 | 188 |
153 int rendererIndex = 0; | 189 int axisIndex = annotation.getAxisSymbol(); |
190 XYItemRenderer renderer = null; | |
191 if (dataset.getDatasets().length > 0) { | |
192 renderer = plot.getRendererForDataset(dataset.getDatasets()[0]); | |
193 } | |
194 else { | |
195 renderer = plot.getRenderer(); | |
196 } | |
154 | 197 |
155 if (annotation.atX()) { | 198 if (annotation.atX()) { |
156 textAnnotation = new CollisionFreeXYTextAnnotation( | 199 textAnnotation = new CollisionFreeXYTextAnnotation( |
157 annotation.getText(), annotation.getPos(), area.ofGround(TEXT_OFF)); | 200 annotation.getText(), annotation.getPos(), area.ofGround(TEXT_OFF)); |
158 // OPTIMIZE externalize the calculation involving PI. | 201 // OPTIMIZE externalize the calculation involving PI. |
161 area, annotation.getPos(), lineStyle); | 204 area, annotation.getPos(), lineStyle); |
162 textAnnotation.setRotationAnchor(TextAnchor.CENTER_LEFT); | 205 textAnnotation.setRotationAnchor(TextAnchor.CENTER_LEFT); |
163 textAnnotation.setTextAnchor(TextAnchor.CENTER_LEFT); | 206 textAnnotation.setTextAnchor(TextAnchor.CENTER_LEFT); |
164 } | 207 } |
165 else { | 208 else { |
166 // Do the more complicated case where we stick to the Y-Axis. | |
167 // There is one nasty case (duration curves, where annotations | |
168 // might stick to the second y-axis). | |
169 if (dataset == null) { | |
170 log.warn("Annotation should stick to unfindable y-axis: " | |
171 + annotation.getAxisSymbol()); | |
172 rendererIndex = 0; | |
173 } | |
174 else { | |
175 rendererIndex = dataset.getPlotAxisIndex(); | |
176 } | |
177 | |
178 // Stick to the "right" (opposed to left) Y-Axis. | 209 // Stick to the "right" (opposed to left) Y-Axis. |
179 if (rendererIndex != 0) { | 210 if (axisIndex != 0 && plot.getRangeAxis(axisIndex) != null) { |
180 // OPTIMIZE: Pass a different area to this function, | 211 // OPTIMIZE: Pass a different area to this function, |
181 // do the adding to renderer outside (let this | 212 // do the adding to renderer outside (let this |
182 // function return the annotations). | 213 // function return the annotations). |
183 // Note that this path is travelled rarely. | 214 // Note that this path is travelled rarely. |
184 ChartArea area2 = new ChartArea(plot.getDomainAxis(), plot.getRangeAxis(rendererIndex)); | |
185 textAnnotation = new CollisionFreeXYTextAnnotation( | 215 textAnnotation = new CollisionFreeXYTextAnnotation( |
186 annotation.getText(), area2.ofRight(TEXT_OFF), annotation.getPos()); | 216 annotation.getText(), |
217 area.ofRight(TEXT_OFF), | |
218 annotation.getPos() | |
219 ); | |
187 textAnnotation.setRotationAnchor(TextAnchor.CENTER_RIGHT); | 220 textAnnotation.setRotationAnchor(TextAnchor.CENTER_RIGHT); |
188 textAnnotation.setTextAnchor(TextAnchor.CENTER_RIGHT); | 221 textAnnotation.setTextAnchor(TextAnchor.CENTER_RIGHT); |
189 lineAnnotation = createRightStickAnnotation( | 222 lineAnnotation = createRightStickAnnotation( |
190 area2, annotation.getPos(), lineStyle); | 223 area, annotation.getPos(), lineStyle); |
224 | |
225 // hit-lines for duration curve | |
226 ChartArea area2 = new ChartArea( | |
227 plot.getDomainAxis(), plot.getRangeAxis(axisIndex)); | |
191 if (!Float.isNaN(annotation.getHitPoint()) && theme != null) { | 228 if (!Float.isNaN(annotation.getHitPoint()) && theme != null) { |
192 // New line annotation to hit curve. | 229 // New line annotation to hit curve. |
193 if (theme.parseShowVerticalLine()) { | 230 if (theme.parseShowVerticalLine()) { |
194 XYLineAnnotation hitLineAnnotation = | 231 XYLineAnnotation hitLineAnnotation = |
195 createStickyLineAnnotation( | 232 createStickyLineAnnotation( |
196 StickyAxisAnnotation.SimpleAxis.X_AXIS, | 233 StickyAxisAnnotation.SimpleAxis.X_AXIS, |
197 annotation.getHitPoint(), annotation.getPos(),// annotation.getHitPoint(), | 234 annotation.getHitPoint(), annotation.getPos(),// annotation.getHitPoint(), |
198 area2, lineStyle); | 235 area2, lineStyle); |
199 plot.getRenderer(rendererIndex).addAnnotation(hitLineAnnotation, | 236 renderer.addAnnotation(hitLineAnnotation, |
200 org.jfree.ui.Layer.BACKGROUND); | 237 org.jfree.ui.Layer.BACKGROUND); |
201 } | 238 } |
202 if (theme.parseShowHorizontalLine()) { | 239 if (theme.parseShowHorizontalLine()) { |
203 XYLineAnnotation lineBackAnnotation = | 240 XYLineAnnotation lineBackAnnotation = |
204 createStickyLineAnnotation( | 241 createStickyLineAnnotation( |
205 StickyAxisAnnotation.SimpleAxis.Y_AXIS2, | 242 StickyAxisAnnotation.SimpleAxis.Y_AXIS2, |
206 annotation.getPos(), annotation.getHitPoint(), | 243 annotation.getPos(), annotation.getHitPoint(), |
207 area2, lineStyle); | 244 area2, lineStyle); |
208 plot.getRenderer(rendererIndex).addAnnotation(lineBackAnnotation, | 245 renderer.addAnnotation(lineBackAnnotation, |
209 org.jfree.ui.Layer.BACKGROUND); | 246 org.jfree.ui.Layer.BACKGROUND); |
210 } | 247 } |
211 } | 248 } |
212 } | 249 } |
213 else { // Stick to the left y-axis. | 250 else { // Stick to the left y-axis. |
222 XYLineAnnotation hitLineAnnotation = | 259 XYLineAnnotation hitLineAnnotation = |
223 createStickyLineAnnotation( | 260 createStickyLineAnnotation( |
224 StickyAxisAnnotation.SimpleAxis.Y_AXIS, | 261 StickyAxisAnnotation.SimpleAxis.Y_AXIS, |
225 annotation.getPos(), annotation.getHitPoint(), | 262 annotation.getPos(), annotation.getHitPoint(), |
226 area, lineStyle); | 263 area, lineStyle); |
227 plot.getRenderer(rendererIndex).addAnnotation(hitLineAnnotation, | 264 renderer.addAnnotation(hitLineAnnotation, |
228 org.jfree.ui.Layer.BACKGROUND); | 265 org.jfree.ui.Layer.BACKGROUND); |
229 } | 266 } |
230 if (theme.parseShowVerticalLine()) { | 267 if (theme.parseShowVerticalLine()) { |
231 XYLineAnnotation lineBackAnnotation = | 268 XYLineAnnotation lineBackAnnotation = |
232 createStickyLineAnnotation( | 269 createStickyLineAnnotation( |
233 StickyAxisAnnotation.SimpleAxis.X_AXIS, | 270 StickyAxisAnnotation.SimpleAxis.X_AXIS, |
234 annotation.getHitPoint(), annotation.getPos(), | 271 annotation.getHitPoint(), annotation.getPos(), |
235 area, lineStyle); | 272 area, lineStyle); |
236 plot.getRenderer(rendererIndex).addAnnotation(lineBackAnnotation, | 273 renderer.addAnnotation(lineBackAnnotation, |
237 org.jfree.ui.Layer.BACKGROUND); | 274 org.jfree.ui.Layer.BACKGROUND); |
238 } | 275 } |
239 } | 276 } |
240 } | 277 } |
241 } | 278 } |
244 if (textStyle != null) { | 281 if (textStyle != null) { |
245 textStyle.apply(textAnnotation); | 282 textStyle.apply(textAnnotation); |
246 } | 283 } |
247 | 284 |
248 // Add the Annotations to renderer. | 285 // Add the Annotations to renderer. |
249 plot.getRenderer(rendererIndex).addAnnotation(textAnnotation, | 286 renderer.addAnnotation(textAnnotation, org.jfree.ui.Layer.FOREGROUND); |
250 org.jfree.ui.Layer.FOREGROUND); | 287 renderer.addAnnotation(lineAnnotation, org.jfree.ui.Layer.FOREGROUND); |
251 plot.getRenderer(rendererIndex).addAnnotation(lineAnnotation, | |
252 org.jfree.ui.Layer.FOREGROUND); | |
253 } | 288 } |
254 | 289 |
255 /** | 290 /** |
256 * Create annotation that sticks to "ground" (X) axis. | 291 * Create annotation that sticks to "ground" (X) axis. |
257 * @param area helper to calculate coordinates | 292 * @param area helper to calculate coordinates |
286 ChartArea area, float pos, LineStyle lineStyle | 321 ChartArea area, float pos, LineStyle lineStyle |
287 ) { | 322 ) { |
288 // Style the line. | 323 // Style the line. |
289 if (lineStyle != null) { | 324 if (lineStyle != null) { |
290 return new XYLineAnnotation( | 325 return new XYLineAnnotation( |
326 area.atRight(), pos, | |
291 area.ofRight(ANNOTATIONS_AXIS_OFFSET), pos, | 327 area.ofRight(ANNOTATIONS_AXIS_OFFSET), pos, |
292 area.atRight(), pos, | |
293 new BasicStroke(lineStyle.getWidth()), lineStyle.getColor()); | 328 new BasicStroke(lineStyle.getWidth()), lineStyle.getColor()); |
294 } | 329 } |
295 else { | 330 else { |
296 return new XYLineAnnotation( | 331 return new XYLineAnnotation( |
297 area.atRight(), pos, | 332 area.atRight(), pos, |