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,

http://dive4elements.wald.intevation.org