comparison artifacts/src/main/java/org/dive4elements/river/exports/DiagramGenerator.java @ 9123:1cc7653ca84f

Cleanup of ChartGenerator and ChartGenerator2 code. Put some of the copy/pasted code into a common abstraction.
author gernotbelger
date Tue, 05 Jun 2018 19:21:16 +0200
parents 07d51fd4864c
children 55e2155ab52d
comparison
equal deleted inserted replaced
9122:b8e7f6becf78 9123:1cc7653ca84f
8 8
9 package org.dive4elements.river.exports; 9 package org.dive4elements.river.exports;
10 10
11 import java.awt.Color; 11 import java.awt.Color;
12 import java.awt.Font; 12 import java.awt.Font;
13
14 import java.text.NumberFormat; 13 import java.text.NumberFormat;
15
16 import java.util.ArrayList; 14 import java.util.ArrayList;
17 import java.util.Collection; 15 import java.util.Collection;
18 import java.util.HashMap; 16 import java.util.HashMap;
19 import java.util.HashSet; 17 import java.util.HashSet;
20 import java.util.LinkedHashSet; 18 import java.util.LinkedHashSet;
21 import java.util.List; 19 import java.util.List;
22 import java.util.Map; 20 import java.util.Map;
23 import java.util.Set; 21 import java.util.Set;
24 22 import java.util.regex.Matcher;
25 import java.util.regex.Pattern; 23 import java.util.regex.Pattern;
26 import java.util.regex.Matcher;
27
28 import java.io.OutputStream;
29 24
30 import javax.swing.ImageIcon; 25 import javax.swing.ImageIcon;
31 26
27 import org.apache.commons.lang.StringUtils;
32 import org.apache.log4j.Logger; 28 import org.apache.log4j.Logger;
33
34 import org.dive4elements.artifactdatabase.state.ArtifactAndFacet; 29 import org.dive4elements.artifactdatabase.state.ArtifactAndFacet;
35 import org.dive4elements.artifactdatabase.state.Facet; 30 import org.dive4elements.artifactdatabase.state.Facet;
36
37 import org.dive4elements.artifacts.CallContext; 31 import org.dive4elements.artifacts.CallContext;
38
39 import org.dive4elements.river.artifacts.D4EArtifact; 32 import org.dive4elements.river.artifacts.D4EArtifact;
40 import org.dive4elements.river.exports.DiagramAttributes.AxisAttributes; 33 import org.dive4elements.river.exports.DiagramAttributes.AxisAttributes;
41 import org.dive4elements.river.exports.process.Processor; 34 import org.dive4elements.river.exports.process.Processor;
42
43 import org.dive4elements.river.jfree.RiverAnnotation;
44 import org.dive4elements.river.jfree.AnnotationHelper;
45 import org.dive4elements.river.jfree.AxisDataset; 35 import org.dive4elements.river.jfree.AxisDataset;
46 import org.dive4elements.river.jfree.Bounds; 36 import org.dive4elements.river.jfree.Bounds;
47 import org.dive4elements.river.jfree.DoubleBounds; 37 import org.dive4elements.river.jfree.DoubleBounds;
38 import org.dive4elements.river.jfree.RiverAnnotation;
48 import org.dive4elements.river.jfree.StyledAreaSeriesCollection; 39 import org.dive4elements.river.jfree.StyledAreaSeriesCollection;
49 import org.dive4elements.river.jfree.XYMetaSeriesCollection; 40 import org.dive4elements.river.jfree.XYMetaSeriesCollection;
50
51 import org.dive4elements.river.themes.ThemeDocument; 41 import org.dive4elements.river.themes.ThemeDocument;
52
53 import org.jfree.chart.ChartFactory; 42 import org.jfree.chart.ChartFactory;
54 import org.jfree.chart.JFreeChart; 43 import org.jfree.chart.JFreeChart;
55 import org.jfree.chart.LegendItem; 44 import org.jfree.chart.LegendItem;
56
57 import org.jfree.chart.annotations.XYAnnotation; 45 import org.jfree.chart.annotations.XYAnnotation;
58 import org.jfree.chart.annotations.XYImageAnnotation; 46 import org.jfree.chart.annotations.XYImageAnnotation;
59
60 import org.jfree.chart.axis.LogarithmicAxis; 47 import org.jfree.chart.axis.LogarithmicAxis;
61 import org.jfree.chart.axis.NumberAxis; 48 import org.jfree.chart.axis.NumberAxis;
62 import org.jfree.chart.axis.ValueAxis; 49 import org.jfree.chart.axis.ValueAxis;
63
64 import org.jfree.chart.plot.Marker; 50 import org.jfree.chart.plot.Marker;
65 import org.jfree.chart.plot.PlotOrientation; 51 import org.jfree.chart.plot.PlotOrientation;
66 import org.jfree.chart.plot.XYPlot; 52 import org.jfree.chart.plot.XYPlot;
67
68 import org.jfree.data.Range; 53 import org.jfree.data.Range;
69
70 import org.jfree.data.general.Series; 54 import org.jfree.data.general.Series;
71
72 import org.jfree.data.xy.XYDataset; 55 import org.jfree.data.xy.XYDataset;
73 import org.jfree.data.xy.XYSeries; 56 import org.jfree.data.xy.XYSeries;
74 import org.jfree.data.xy.XYSeriesCollection; 57 import org.jfree.data.xy.XYSeriesCollection;
75
76 import org.w3c.dom.Document;
77
78 import org.apache.commons.lang.StringUtils;
79 58
80 59
81 /** 60 /**
82 * The main diagram creation class. 61 * The main diagram creation class.
83 * 62 *
100 public static final int AXIS_SPACE = 5; 79 public static final int AXIS_SPACE = 5;
101 80
102 /** The log that is used in this generator. */ 81 /** The log that is used in this generator. */
103 private static Logger log = Logger.getLogger(DiagramGenerator.class); 82 private static Logger log = Logger.getLogger(DiagramGenerator.class);
104 83
105 protected List<Marker> domainMarkers = new ArrayList<Marker>(); 84 protected List<Marker> domainMarkers = new ArrayList<>();
106 85
107 protected List<Marker> valueMarkers = new ArrayList<Marker>(); 86 protected List<Marker> valueMarkers = new ArrayList<>();
108 87
109 /** The max X range to include all X values of all series for each axis. */ 88 /** The max X range to include all X values of all series for each axis. */
110 protected Map<Integer, Bounds> xBounds; 89 protected Map<Integer, Bounds> xBounds;
111 90
112 /** The max Y range to include all Y values of all series for each axis. */ 91 /** The max Y range to include all Y values of all series for each axis. */
142 } 121 }
143 DiagramAttributes da = (DiagramAttributes)config; 122 DiagramAttributes da = (DiagramAttributes)config;
144 diagramAttributes = da.new Instance(); 123 diagramAttributes = da.new Instance();
145 } 124 }
146 125
147 @Override 126 private void setInvertedFromConfig(CallContext context) {
148 public void init(
149 String outName,
150 Document request,
151 OutputStream out,
152 CallContext context
153 ) {
154 super.init(outName, request, out, context);
155 }
156
157 private void setInvertedFromConfig() {
158 DiagramAttributes.DomainAxisAttributes dx = 127 DiagramAttributes.DomainAxisAttributes dx =
159 diagramAttributes.getDomainAxis(); 128 diagramAttributes.getDomainAxis();
160 129
161 if (dx != null) { 130 if (dx != null) {
162 inverted = (Boolean)dx.isInverted() 131 inverted = (Boolean)dx.isInverted()
173 142
174 /** 143 /**
175 * Generate the chart anew (including localized axis and all). 144 * Generate the chart anew (including localized axis and all).
176 */ 145 */
177 @Override 146 @Override
178 public JFreeChart generateChart() { 147 protected JFreeChart generateChart(CallContext context) {
179 log.debug("DiagramGenerator.generateChart"); 148 log.debug("DiagramGenerator.generateChart");
180 149
181 postProcess(); 150 postProcess();
182 151
183 JFreeChart chart = ChartFactory.createXYLineChart( 152 JFreeChart chart = ChartFactory.createXYLineChart(
184 getChartTitle(), 153 getChartTitle(context),
185 "", 154 "",
186 "", 155 "",
187 null, 156 null,
188 PlotOrientation.VERTICAL, 157 PlotOrientation.VERTICAL,
189 isLegendVisible(), 158 isLegendVisible(),
190 false, 159 false,
191 false); 160 false);
192 161
193 XYPlot plot = (XYPlot) chart.getPlot(); 162 XYPlot plot = (XYPlot) chart.getPlot();
194 ValueAxis axis = createXAxis(getXAxisLabel()); 163 ValueAxis axis = createXAxis(context, getXAxisLabel());
195 plot.setDomainAxis(axis); 164 plot.setDomainAxis(axis);
196 165
197 chart.setBackgroundPaint(Color.WHITE); 166 chart.setBackgroundPaint(Color.WHITE);
198 plot.setBackgroundPaint(Color.WHITE); 167 plot.setBackgroundPaint(Color.WHITE);
199 addSubtitles(chart); 168 addSubtitles(context, chart);
200 addMetadataSubtitle(chart); 169 addMetadataSubtitle(context, chart);
201 adjustPlot(plot); 170 adjustPlot(plot);
202 171
203 //debugAxis(plot); 172 //debugAxis(plot);
204 173
205 addDatasets(plot); 174 addDatasets(plot);
213 182
214 //debugAxis(plot); 183 //debugAxis(plot);
215 184
216 localizeAxes(plot); 185 localizeAxes(plot);
217 186
218 setInvertedFromConfig(); 187 setInvertedFromConfig(context);
219 188
220 adjustAxes(plot); 189 adjustAxes(plot);
221 if (!(axis instanceof LogarithmicAxis)) { 190 if (!(axis instanceof LogarithmicAxis)) {
222 // XXX: 191 // XXX:
223 // The auto zoom without a range tries 192 // The auto zoom without a range tries
228 } 197 }
229 198
230 //debugAxis(plot); 199 //debugAxis(plot);
231 200
232 // These have to go after the autozoom. 201 // These have to go after the autozoom.
233 AnnotationHelper.addAnnotationsToRenderer(annotations, plot, 202 addAnnotationsToRenderer(plot);
234 getChartSettings(), datasets); 203 addYAnnotationsToRenderer(plot);
235 AnnotationHelper.addYAnnotationsToRenderer(yAnnotations, plot,
236 getChartSettings(), datasets);
237 204
238 // Add a logo (maybe). 205 // Add a logo (maybe).
239 addLogo(plot); 206 addLogo(plot);
240 207
241 aggregateLegendEntries(plot); 208 aggregateLegendEntries(plot);
245 for (final ChartExtender extender : extenders) { 212 for (final ChartExtender extender : extenders) {
246 extender.afterGenerateChart(this, plot); 213 extender.afterGenerateChart(this, plot);
247 } 214 }
248 215
249 return chart; 216 return chart;
250 }
251
252 public String getOutName() {
253 return outName;
254 } 217 }
255 218
256 /** 219 /**
257 * Return left most data points x value (on first axis). 220 * Return left most data points x value (on first axis).
258 */ 221 */
391 plot.getRenderer().addAnnotation( 354 plot.getRenderer().addAnnotation(
392 xyannotation, org.jfree.ui.Layer.BACKGROUND); 355 xyannotation, org.jfree.ui.Layer.BACKGROUND);
393 } 356 }
394 357
395 358
396 protected NumberAxis createXAxis(String label) { 359 protected NumberAxis createXAxis(final CallContext context, String label) {
397 boolean logarithmic = (Boolean)diagramAttributes.getDomainAxis(). 360 boolean logarithmic = (Boolean)diagramAttributes.getDomainAxis().
398 isLog().evaluate((D4EArtifact)getMaster(), context); 361 isLog().evaluate((D4EArtifact)getMaster(), context);
399 362
400 if (logarithmic) { 363 if (logarithmic) {
401 final LogarithmicAxis axis = new LogarithmicAxis(label); 364 final LogarithmicAxis axis = new LogarithmicAxis(label);
1111 inverted = value; 1074 inverted = value;
1112 } 1075 }
1113 } 1076 }
1114 1077
1115 @Override 1078 @Override
1116 public String getDefaultChartTitle() { 1079 protected final String getDefaultChartTitle(CallContext context) {
1117 DiagramAttributes.Title dTitle = diagramAttributes.getTitle(); 1080 DiagramAttributes.Title dTitle = diagramAttributes.getTitle();
1118 if (dTitle == null) { 1081 if (dTitle == null) {
1119 return "Title not configured in conf.xml"; 1082 return "Title not configured in conf.xml";
1120 } 1083 }
1121 1084
1122 return dTitle.evaluate((D4EArtifact)getMaster(), context); 1085 return dTitle.evaluate((D4EArtifact)getMaster(), context);
1123 } 1086 }
1124 1087
1125 @Override 1088
1126 public String getDefaultChartSubtitle() { 1089 @Override
1090 protected String getDefaultChartSubtitle(CallContext context) {
1127 String parts = ""; 1091 String parts = "";
1128 DiagramAttributes.Title dTitle = diagramAttributes.getSubtitle(); 1092 DiagramAttributes.Title dTitle = diagramAttributes.getSubtitle();
1129 if (dTitle == null && 1093 if (dTitle == null &&
1130 (subTitleParts == null || subTitleParts.isEmpty())) { 1094 (subTitleParts == null || subTitleParts.isEmpty())) {
1131 /* Subtitle is optional */ 1095 /* Subtitle is optional */
1152 1116
1153 /** 1117 /**
1154 * Get internationalized label for the x axis. 1118 * Get internationalized label for the x axis.
1155 */ 1119 */
1156 @Override 1120 @Override
1157 protected String getDefaultXAxisLabel() { 1121 protected String getDefaultXAxisLabel(CallContext context) {
1158 DiagramAttributes.DomainAxisAttributes dx = 1122 DiagramAttributes.DomainAxisAttributes dx =
1159 diagramAttributes.getDomainAxis(); 1123 diagramAttributes.getDomainAxis();
1160 1124
1161 if (dx != null) { 1125 if (dx != null) {
1162 DiagramAttributes.Title t = dx.getTitle(); 1126 DiagramAttributes.Title t = dx.getTitle();
1165 } 1129 }
1166 } 1130 }
1167 return "Domain Axis Title not configured in conf.xml"; 1131 return "Domain Axis Title not configured in conf.xml";
1168 } 1132 }
1169 1133
1170 @Override 1134 protected final String getDefaultYAxisLabel(String axisName) {
1171 protected String getDefaultYAxisLabel(String axisName) {
1172 Set labelSet = axesLabels.get(diagramAttributes.getAxisIndex(axisName)); 1135 Set labelSet = axesLabels.get(diagramAttributes.getAxisIndex(axisName));
1173 log.debug("Labels for axis: " + labelSet); 1136 log.debug("Labels for axis: " + labelSet);
1174 if (labelSet != null && !labelSet.isEmpty()) { 1137 if (labelSet != null && !labelSet.isEmpty()) {
1175 String label = StringUtils.join(labelSet, ", "); 1138 String label = StringUtils.join(labelSet, ", ");
1176 Matcher units = UNIT_PATTERN.matcher(label); 1139 Matcher units = UNIT_PATTERN.matcher(label);
1196 /** 1159 /**
1197 * Creates a list of Section for the chart's Y axes. 1160 * Creates a list of Section for the chart's Y axes.
1198 * 1161 *
1199 * @return a list of Y axis sections. 1162 * @return a list of Y axis sections.
1200 */ 1163 */
1201 protected List<AxisSection> buildYAxisSections() { 1164 @Override
1202 List<AxisSection> axisSections = new ArrayList<AxisSection>(); 1165 protected final List<AxisSection> buildYAxisSections() {
1166 List<AxisSection> axisSections = new ArrayList<>();
1203 1167
1204 List<DiagramAttributes.AxisAttributes> axesAttrs = 1168 List<DiagramAttributes.AxisAttributes> axesAttrs =
1205 diagramAttributes.getAxesAttributes(); 1169 diagramAttributes.getAxesAttributes();
1206 1170
1207 for (int i = 0, n = axesAttrs.size(); i < n; i++) { 1171 for (int i = 0, n = axesAttrs.size(); i < n; i++) {
1313 @Override 1277 @Override
1314 protected NumberAxis createYAxis(int index) { 1278 protected NumberAxis createYAxis(int index) {
1315 1279
1316 final AxisAttributes axisAttributes = diagramAttributes.getAxesAttributes().get(index); 1280 final AxisAttributes axisAttributes = diagramAttributes.getAxesAttributes().get(index);
1317 1281
1318 boolean logarithmic = (Boolean)axisAttributes.isLog().evaluate((D4EArtifact)getMaster(), context); 1282 boolean logarithmic = (Boolean)axisAttributes.isLog().evaluate((D4EArtifact)getMaster(), getContext());
1319 1283
1320 NumberAxis axis; 1284 NumberAxis axis;
1321 if (logarithmic) { 1285 if (logarithmic) {
1322 axis = new LogarithmicAxis(getYAxisLabel(index)); 1286 axis = new LogarithmicAxis(getYAxisLabel(index));
1323 } else { 1287 } else {

http://dive4elements.wald.intevation.org