comparison artifacts/src/main/java/org/dive4elements/river/exports/TimeseriesChartGenerator.java @ 9555:ef5754ba5573

Implemented legend aggregation based on type of themes. Added theme-editor style configuration for aggregated legend entries. Only configured themes get aggregated.
author gernotbelger
date Tue, 23 Oct 2018 16:26:48 +0200
parents 094ed9d1f2ad
children
comparison
equal deleted inserted replaced
9554:33ce8eba9806 9555:ef5754ba5573
15 import org.dive4elements.river.jfree.CollisionFreeXYTextAnnotation; 15 import org.dive4elements.river.jfree.CollisionFreeXYTextAnnotation;
16 import org.dive4elements.river.jfree.DoubleBounds; 16 import org.dive4elements.river.jfree.DoubleBounds;
17 import org.dive4elements.river.jfree.RiverAnnotation; 17 import org.dive4elements.river.jfree.RiverAnnotation;
18 import org.dive4elements.river.jfree.StyledTimeSeries; 18 import org.dive4elements.river.jfree.StyledTimeSeries;
19 import org.dive4elements.river.jfree.TimeBounds; 19 import org.dive4elements.river.jfree.TimeBounds;
20 import org.dive4elements.river.jfree.AxisDataset;
21 import org.dive4elements.river.themes.ThemeDocument; 20 import org.dive4elements.river.themes.ThemeDocument;
22 21
23 import java.awt.Color; 22 import java.awt.Color;
24 import java.awt.Font; 23 import java.awt.Font;
25 import java.text.DateFormat; 24 import java.text.DateFormat;
26 import java.text.ParseException; 25 import java.text.ParseException;
27 import java.util.ArrayList; 26 import java.util.ArrayList;
28 import java.util.Date; 27 import java.util.Date;
29 import java.util.HashMap; 28 import java.util.HashMap;
30 import java.util.Iterator;
31 import java.util.List; 29 import java.util.List;
32 import java.util.Map; 30 import java.util.Map;
33 31
34 import javax.swing.ImageIcon; 32 import javax.swing.ImageIcon;
35 33
36 import org.apache.log4j.Logger; 34 import org.apache.log4j.Logger;
37 import org.jfree.chart.ChartFactory; 35 import org.jfree.chart.ChartFactory;
38 import org.jfree.chart.JFreeChart; 36 import org.jfree.chart.JFreeChart;
39 import org.jfree.chart.LegendItem;
40 import org.jfree.chart.LegendItemCollection;
41 import org.jfree.chart.annotations.XYAnnotation; 37 import org.jfree.chart.annotations.XYAnnotation;
42 import org.jfree.chart.annotations.XYImageAnnotation; 38 import org.jfree.chart.annotations.XYImageAnnotation;
43 import org.jfree.chart.annotations.XYTextAnnotation; 39 import org.jfree.chart.annotations.XYTextAnnotation;
44 import org.jfree.chart.axis.ValueAxis; 40 import org.jfree.chart.axis.ValueAxis;
45 import org.jfree.chart.plot.Marker; 41 import org.jfree.chart.plot.Marker;
46 import org.jfree.chart.plot.XYPlot; 42 import org.jfree.chart.plot.XYPlot;
47 import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
48 import org.jfree.data.Range; 43 import org.jfree.data.Range;
49 import org.jfree.data.general.Series; 44 import org.jfree.data.general.Series;
50 import org.jfree.data.time.FixedMillisecond; 45 import org.jfree.data.time.FixedMillisecond;
51 import org.jfree.data.time.TimeSeries; 46 import org.jfree.data.time.TimeSeries;
52 import org.jfree.data.time.TimeSeriesCollection; 47 import org.jfree.data.time.TimeSeriesCollection;
82 * The default constructor that initializes internal datastructures. 77 * The default constructor that initializes internal datastructures.
83 */ 78 */
84 public TimeseriesChartGenerator() { 79 public TimeseriesChartGenerator() {
85 super(); 80 super();
86 81
87 xBounds = new HashMap<Integer, Bounds>(); 82 xBounds = new HashMap<>();
88 yBounds = new HashMap<Integer, Bounds>(); 83 yBounds = new HashMap<>();
89 domainMarker = new ArrayList<Marker>(); 84 domainMarker = new ArrayList<>();
90 valueMarker = new ArrayList<Marker>(); 85 valueMarker = new ArrayList<>();
91 } 86 }
92 87
93 @Override 88 @Override
94 protected JFreeChart generateChart(CallContext context) { 89 protected JFreeChart generateChart(CallContext context) {
95 log.info("Generate Timeseries Chart."); 90 log.info("Generate Timeseries Chart.");
109 104
110 chart.setBackgroundPaint(Color.WHITE); 105 chart.setBackgroundPaint(Color.WHITE);
111 plot.setBackgroundPaint(Color.WHITE); 106 plot.setBackgroundPaint(Color.WHITE);
112 107
113 adjustPlot(plot); 108 adjustPlot(plot);
114 addDatasets(plot); 109
110 final LegendAggregator legendBuilder = createLegendBuilder();
111
112 addDatasets(plot, legendBuilder);
113
115 adjustAxes(plot); 114 adjustAxes(plot);
116 addDomainAxisMarker(plot); 115 addDomainAxisMarker(plot);
117 addValueAxisMarker(plot); 116 addValueAxisMarker(plot);
118 adaptZoom(plot); 117 adaptZoom(plot);
119 118
120 consumeAxisSettings(plot); 119 consumeAxisSettings(plot);
121 120
122 addAnnotationsToRenderer(plot); 121 addAnnotationsToRenderer(plot, legendBuilder);
123 122
123 legendBuilder.apply(context, plot);
124
124 addLogo(plot); 125 addLogo(plot);
125 aggregateLegendEntries(plot); 126
126 return chart; 127 return chart;
127 } 128 }
128
129 129
130 /** 130 /**
131 * Return left most data points x value (on first axis). 131 * Return left most data points x value (on first axis).
132 * Shortcut, especially to be overridden in (LS) charts where 132 * Shortcut, especially to be overridden in (LS) charts where
133 * axis could be inverted. 133 * axis could be inverted.
319 @Override 319 @Override
320 protected Series getSeriesOf(XYDataset dataset, int idx) { 320 protected Series getSeriesOf(XYDataset dataset, int idx) {
321 return ((TimeSeriesCollection) dataset).getSeries(idx); 321 return ((TimeSeriesCollection) dataset).getSeries(idx);
322 } 322 }
323 323
324
325 /**
326 * This method creates new instances of AxisDataset.
327 *
328 * @param idx The symbol for the new AxisDataset.
329 */
330 @Override
331 protected AxisDataset createAxisDataset(int idx) {
332 log.debug("Create a new AxisDataset for index: " + idx);
333 return new AxisDataset(idx);
334 }
335
336
337 @Override 324 @Override
338 protected void combineXBounds(Bounds bounds, int index) { 325 protected void combineXBounds(Bounds bounds, int index) {
339 if (bounds != null) { 326 if (bounds != null) {
340 Bounds old = getXBounds(index); 327 Bounds old = getXBounds(index);
341 328
632 ArtifactAndFacet aandf, 619 ArtifactAndFacet aandf,
633 ThemeDocument theme, 620 ThemeDocument theme,
634 boolean visible, 621 boolean visible,
635 int axisIndex 622 int axisIndex
636 ) { 623 ) {
624 final String facetName = aandf.getFacetName();
637 String seriesName = aandf.getFacetDescription(); 625 String seriesName = aandf.getFacetDescription();
638 TimeSeries series = new StyledTimeSeries(seriesName, theme); 626
627 TimeSeries series = new StyledTimeSeries(facetName, seriesName, theme);
639 628
640 // Add text annotations for single points. 629 // Add text annotations for single points.
641 List<XYTextAnnotation> xy = new ArrayList<XYTextAnnotation>(); 630 List<XYTextAnnotation> xy = new ArrayList<>();
642 HashMap<FixedMillisecond, String> names = 631 HashMap<FixedMillisecond, String> names = new HashMap<>();
643 new HashMap<FixedMillisecond, String>();
644 632
645 try { 633 try {
646 JSONArray points = new JSONArray((String) o); 634 JSONArray points = new JSONArray((String) o);
647 for (int i = 0, P = points.length(); i < P; i++) { 635 for (int i = 0, P = points.length(); i < P; i++) {
648 JSONArray array = points.getJSONArray(i); 636 JSONArray array = points.getJSONArray(i);

http://dive4elements.wald.intevation.org