Mercurial > dive4elements > river
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 { |