Mercurial > dive4elements > river
comparison flys-artifacts/src/main/java/de/intevation/flys/exports/XYChartGenerator.java @ 2238:23c7c51df772
Some more refactoring in XYChartGenerator and ChartGenerator; implemented necessary stuff in TimeseriesChartGenerator and return new empty instances of timeseries charts.
flys-artifacts/trunk@3885 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author | Ingo Weinzierl <ingo.weinzierl@intevation.de> |
---|---|
date | Thu, 02 Feb 2012 15:44:13 +0000 |
parents | c2b15d9c0f43 |
children | 7e8e1d5384c0 |
comparison
equal
deleted
inserted
replaced
2237:60615235e951 | 2238:23c7c51df772 |
---|---|
81 * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a> | 81 * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a> |
82 */ | 82 */ |
83 public abstract class XYChartGenerator extends ChartGenerator { | 83 public abstract class XYChartGenerator extends ChartGenerator { |
84 | 84 |
85 // TODO Consider storing the renderer here. | 85 // TODO Consider storing the renderer here. |
86 private class AxisDataset { | 86 private class XYAxisDataset implements AxisDataset { |
87 /** Symbolic integer, but also coding the priority (0 goes first). */ | 87 /** Symbolic integer, but also coding the priority (0 goes first). */ |
88 protected int axisSymbol; | 88 protected int axisSymbol; |
89 /** List of assigned datasets (in order). */ | 89 /** List of assigned datasets (in order). */ |
90 protected List<XYDataset> datasets; | 90 protected List<XYDataset> datasets; |
91 /** Range to use to include all given datasets. */ | 91 /** Range to use to include all given datasets. */ |
92 protected Range range; | 92 protected Range range; |
93 /** Index of axis in plot. */ | 93 /** Index of axis in plot. */ |
94 protected int plotAxisIndex; | 94 protected int plotAxisIndex; |
95 | 95 |
96 /** Create AxisDataset. */ | 96 /** Create AxisDataset. */ |
97 public AxisDataset(int symb) { | 97 public XYAxisDataset(int symb) { |
98 this.axisSymbol = symb; | 98 this.axisSymbol = symb; |
99 datasets = new ArrayList<XYDataset>(); | 99 datasets = new ArrayList<XYDataset>(); |
100 } | 100 } |
101 | 101 |
102 /** Merge (or create given range with range so far (if any). */ | 102 /** Merge (or create given range with range so far (if any). */ |
112 return; | 112 return; |
113 } | 113 } |
114 range = Range.combine(range, subRange); | 114 range = Range.combine(range, subRange); |
115 } | 115 } |
116 | 116 |
117 | |
118 @Override | |
119 public void addDataset(XYDataset dataset) { | |
120 datasets.add(dataset); | |
121 includeYRange(((XYSeriesCollection) dataset).getSeries(0)); | |
122 } | |
123 | |
117 /** Add a dataset, include its range. */ | 124 /** Add a dataset, include its range. */ |
118 public void addDataset(XYSeries dataset) { | 125 public void addDataset(XYSeries series) { |
119 this.datasets.add(new XYSeriesCollection(dataset)); | 126 addDataset(new XYSeriesCollection(series)); |
120 includeYRange(dataset); | |
121 } | 127 } |
122 | 128 |
123 public void addArea(StyledAreaSeriesCollection series) { | 129 public void addArea(StyledAreaSeriesCollection series) { |
124 this.datasets.add(series); | 130 this.datasets.add(series); |
125 } | 131 } |
170 | 176 |
171 | 177 |
172 /** The logger that is used in this generator. */ | 178 /** The logger that is used in this generator. */ |
173 private static Logger logger = Logger.getLogger(XYChartGenerator.class); | 179 private static Logger logger = Logger.getLogger(XYChartGenerator.class); |
174 | 180 |
175 /** Map of datasets ("index"). */ | |
176 protected SortedMap<Integer, AxisDataset> datasets; | |
177 | |
178 /** List of annotations to insert in plot. */ | 181 /** List of annotations to insert in plot. */ |
179 protected List<FLYSAnnotation> annotations; | 182 protected List<FLYSAnnotation> annotations; |
180 | 183 |
181 /** The max X range to include all X values of all series for each axis. */ | 184 /** The max X range to include all X values of all series for each axis. */ |
182 protected Map<Integer, Range> xRanges; | 185 protected Map<Integer, Range> xRanges; |
184 /** The max Y range to include all Y values of all series for each axis. */ | 187 /** The max Y range to include all Y values of all series for each axis. */ |
185 protected Map<Integer, Range> yRanges; | 188 protected Map<Integer, Range> yRanges; |
186 | 189 |
187 | 190 |
188 public XYChartGenerator() { | 191 public XYChartGenerator() { |
192 super(); | |
193 | |
189 xRanges = new HashMap<Integer, Range>(); | 194 xRanges = new HashMap<Integer, Range>(); |
190 yRanges = new HashMap<Integer, Range>(); | 195 yRanges = new HashMap<Integer, Range>(); |
191 datasets = new TreeMap<Integer, AxisDataset>(); | |
192 } | 196 } |
193 | 197 |
194 | 198 |
195 /** | 199 /** |
196 * Generate the chart anew (including localized axis and all). | 200 * Generate the chart anew (including localized axis and all). |
231 | 235 |
232 // These have to go after the autozoom. | 236 // These have to go after the autozoom. |
233 addAnnotationsToRenderer(plot); | 237 addAnnotationsToRenderer(plot); |
234 | 238 |
235 return chart; | 239 return chart; |
240 } | |
241 | |
242 | |
243 @Override | |
244 protected AxisDataset createAxisDataset(int idx) { | |
245 logger.debug("Create new XYAxisDataset for index: " + idx); | |
246 return new XYAxisDataset(idx); | |
236 } | 247 } |
237 | 248 |
238 | 249 |
239 /** | 250 /** |
240 * Put debug output about datasets. | 251 * Put debug output about datasets. |
286 int axisIndex = 0; | 297 int axisIndex = 0; |
287 int datasetIndex = 0; | 298 int datasetIndex = 0; |
288 for (Map.Entry<Integer, AxisDataset> entry: datasets.entrySet()) { | 299 for (Map.Entry<Integer, AxisDataset> entry: datasets.entrySet()) { |
289 if (!entry.getValue().isEmpty()) { | 300 if (!entry.getValue().isEmpty()) { |
290 // Add axis and range information. | 301 // Add axis and range information. |
291 AxisDataset axisDataset = entry.getValue(); | 302 XYAxisDataset axisDataset = (XYAxisDataset) entry.getValue(); |
292 NumberAxis axis = createYAxis(entry.getKey()); | 303 NumberAxis axis = createYAxis(entry.getKey()); |
293 | 304 |
294 plot.setRangeAxis(axisIndex, axis); | 305 plot.setRangeAxis(axisIndex, axis); |
295 if (axis.getAutoRangeIncludesZero()) { | 306 if (axis.getAutoRangeIncludesZero()) { |
296 axisDataset.range = Range.expandToInclude(axisDataset.range, 0d); | 307 axisDataset.range = Range.expandToInclude(axisDataset.range, 0d); |
322 public void addAreaSeries(StyledAreaSeriesCollection area, int index, boolean visible) { | 333 public void addAreaSeries(StyledAreaSeriesCollection area, int index, boolean visible) { |
323 if (area == null) { | 334 if (area == null) { |
324 logger.warn("Cannot yet render above/under curve."); | 335 logger.warn("Cannot yet render above/under curve."); |
325 return; | 336 return; |
326 } | 337 } |
327 AxisDataset axisDataset = datasets.get(index); | 338 |
328 | 339 XYAxisDataset axisDataset = (XYAxisDataset) getAxisDataset(index); |
329 if (axisDataset == null) { | |
330 axisDataset = new AxisDataset(index); | |
331 datasets.put(index, axisDataset); | |
332 } | |
333 | 340 |
334 if (visible) { | 341 if (visible) { |
335 axisDataset.addArea(area); | 342 axisDataset.addArea(area); |
336 } | 343 } |
337 else { | 344 else { |
347 * @param series the dataseries to include in plot. | 354 * @param series the dataseries to include in plot. |
348 * @param index ('symbolic') index of the series and of its axis. | 355 * @param index ('symbolic') index of the series and of its axis. |
349 * @param visible whether or not the data should be plotted. | 356 * @param visible whether or not the data should be plotted. |
350 */ | 357 */ |
351 public void addAxisSeries(XYSeries series, int index, boolean visible) { | 358 public void addAxisSeries(XYSeries series, int index, boolean visible) { |
359 addAxisDataset(new XYSeriesCollection(series), index, visible); | |
360 | |
352 if (series == null) { | 361 if (series == null) { |
353 return; | 362 return; |
354 } | 363 } |
355 | 364 |
356 AxisDataset axisDataset = datasets.get(index); | 365 XYAxisDataset axisDataset = (XYAxisDataset) getAxisDataset(index); |
357 | 366 |
358 if (axisDataset == null) { | 367 if (!visible) { |
359 axisDataset = new AxisDataset(index); | |
360 datasets.put(index, axisDataset); | |
361 } | |
362 | |
363 logger.debug("addAxisSeries: extent X " + series.getMinX() + " : " + series.getMaxX() | |
364 + " extent y " + series.getMinY() + " : " + series.getMaxY()); | |
365 | |
366 if (visible) { | |
367 axisDataset.addDataset(series); | |
368 } | |
369 else { | |
370 // Do this also when not visible to have axis scaled by default such | 368 // Do this also when not visible to have axis scaled by default such |
371 // that every data-point could be seen (except for annotations). | 369 // that every data-point could be seen (except for annotations). |
372 axisDataset.includeYRange(series); | 370 axisDataset.includeYRange(series); |
373 } | 371 } |
374 | |
375 combineXRanges(new Range(series.getMinX(), series.getMaxX()), 0); | |
376 } | 372 } |
377 | 373 |
378 | 374 |
379 /** | 375 /** |
380 * Effect: extend range of x axis to include given limits. | 376 * Effect: extend range of x axis to include given limits. |
381 * @param range the given ("minimal") range. | 377 * @param range the given ("minimal") range. |
382 * @param index index of axis to be merged. | 378 * @param index index of axis to be merged. |
383 */ | 379 */ |
384 private void combineXRanges(Range range, int index) { | 380 protected void combineXRanges(Range range, int index) { |
385 | 381 |
386 if (range == null | 382 if (range == null |
387 || Double.isNaN(range.getLowerBound()) | 383 || Double.isNaN(range.getLowerBound()) |
388 || Double.isNaN(range.getUpperBound())) { | 384 || Double.isNaN(range.getUpperBound())) { |
389 return; | 385 return; |
410 if (annotations == null) { | 406 if (annotations == null) { |
411 annotations = new ArrayList<FLYSAnnotation>(); | 407 annotations = new ArrayList<FLYSAnnotation>(); |
412 } | 408 } |
413 | 409 |
414 annotations.add(annotation); | 410 annotations.add(annotation); |
415 } | |
416 | |
417 | |
418 /** | |
419 * Create Y (range) axis for given index. | |
420 * Shall be overriden by subclasses. | |
421 */ | |
422 protected NumberAxis createYAxis(int index) { | |
423 YAxisWalker walker = getYAxisWalker(); | |
424 | |
425 Font labelFont = new Font( | |
426 DEFAULT_FONT_NAME, | |
427 Font.BOLD, | |
428 getYAxisFontSize(index)); | |
429 | |
430 IdentifiableNumberAxis axis = new IdentifiableNumberAxis( | |
431 walker.getId(index), | |
432 getYAxisLabel(index)); | |
433 | |
434 axis.setAutoRangeIncludesZero(false); | |
435 axis.setLabelFont(labelFont); | |
436 | |
437 return axis; | |
438 } | 411 } |
439 | 412 |
440 | 413 |
441 /** | 414 /** |
442 * If no data is visible, draw at least empty axis. | 415 * If no data is visible, draw at least empty axis. |
685 } | 658 } |
686 else { | 659 else { |
687 // Do the more complicated case where we stick to the Y-Axis. | 660 // Do the more complicated case where we stick to the Y-Axis. |
688 // There is one nasty case (duration curves, where annotations | 661 // There is one nasty case (duration curves, where annotations |
689 // might stick to the second y-axis). | 662 // might stick to the second y-axis). |
690 AxisDataset dataset = this.datasets.get( | 663 XYAxisDataset dataset = (XYAxisDataset) getAxisDataset( |
691 new Integer(annotation.getAxisSymbol())); | 664 new Integer(annotation.getAxisSymbol())); |
692 if (dataset == null) { | 665 if (dataset == null) { |
693 logger.warn("Annotation should stick to unfindable y-axis: " | 666 logger.warn("Annotation should stick to unfindable y-axis: " |
694 + annotation.getAxisSymbol()); | 667 + annotation.getAxisSymbol()); |
695 rendererIndex = 0; | 668 rendererIndex = 0; |