Mercurial > dive4elements > gnv-client
comparison gnv-artifacts/src/main/java/de/intevation/gnv/chart/ChartFactory.java @ 127:f6f0e4ce4a35
merged gnv-artifacts/0.1
author | Thomas Arendsen Hein <thomas@intevation.de> |
---|---|
date | Fri, 28 Sep 2012 12:13:41 +0200 |
parents | f07637f96312 |
children | 7fb9441dd8af |
comparison
equal
deleted
inserted
replaced
49:94a07d1d9316 | 127:f6f0e4ce4a35 |
---|---|
1 /** | |
2 * Title: ChartFactory, $Header: /share/gdi/SDI-Suite/Repository/projekte/BSH-GDI/genericViewer/src/main/java/de/conterra/bsh/gdi/gnviewer/output/chart/ChartFactory.java,v 1.8 2007/12/21 12:31:15 blume Exp $ | |
3 * Source: $Source: /share/gdi/SDI-Suite/Repository/projekte/BSH-GDI/genericViewer/src/main/java/de/conterra/bsh/gdi/gnviewer/output/chart/ChartFactory.java,v $ | |
4 * created by: Stefan Blume (blume) | |
5 * erstellt am: 06.12.2007 | |
6 * Copyright: con terra GmbH, 2005 | |
7 * | |
8 * modified by: $Author: blume $ | |
9 * modified on: $Date: 2007/12/21 12:31:15 $ | |
10 * Version: $Revision: 1.8 $ | |
11 * TAG: $Name: $ | |
12 * locked from: $Locker: $ | |
13 * CVS State: $State: Exp $ | |
14 * Project: $ProjectName$ | |
15 */ | |
16 package de.intevation.gnv.chart; | |
17 | |
18 import java.awt.Color; | |
19 import java.awt.Font; | |
20 import java.awt.image.BufferedImage; | |
21 import java.io.IOException; | |
22 import java.io.OutputStream; | |
23 import java.util.Collection; | |
24 import java.util.Date; | |
25 import java.util.Iterator; | |
26 | |
27 import org.apache.log4j.Logger; | |
28 import org.jfree.chart.JFreeChart; | |
29 import org.jfree.chart.axis.AxisLocation; | |
30 import org.jfree.chart.axis.DateAxis; | |
31 import org.jfree.chart.axis.NumberAxis; | |
32 import org.jfree.chart.axis.NumberTickUnit; | |
33 import org.jfree.chart.encoders.KeypointPNGEncoderAdapter; | |
34 import org.jfree.chart.plot.PlotOrientation; | |
35 import org.jfree.chart.plot.XYPlot; | |
36 import org.jfree.chart.renderer.xy.StandardXYItemRenderer; | |
37 import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer; | |
38 import org.jfree.data.time.Minute; | |
39 import org.jfree.data.time.TimeSeries; | |
40 import org.jfree.data.time.TimeSeriesCollection; | |
41 import org.jfree.data.xy.XYDataset; | |
42 import org.jfree.ui.RectangleInsets; | |
43 | |
44 import de.intevation.gnv.chart.exception.TechnicalChartException; | |
45 import de.intevation.gnv.geobackend.base.Result; | |
46 import de.intevation.gnv.transition.describedata.KeyValueDescibeData; | |
47 | |
48 /** | |
49 * The class <code>ChartFactory</code> fulfills the following purposes: | |
50 * <ol> | |
51 * <li></li> | |
52 * </ol> | |
53 * | |
54 * @author blume | |
55 * @version 1.0 | |
56 * @serial 1.0 | |
57 * @see | |
58 * @since 06.12.2007 17:25:59 | |
59 */ | |
60 public class ChartFactory { | |
61 | |
62 /** | |
63 * Default Logging instance | |
64 */ | |
65 private static Logger sLogger = Logger.getLogger(ChartFactory.class); | |
66 private static boolean sDebug = sLogger.isDebugEnabled(); | |
67 | |
68 | |
69 public synchronized void createSimpleTimeSeriesChart(ChartLabels pLabels, ChartStyle pStyle, Collection<KeyValueDescibeData> parameters, Collection<KeyValueDescibeData> measurements, OutputStream outputStream, Collection<Result> resultSet) throws IOException, TechnicalChartException { | |
70 if (sDebug) | |
71 sLogger.debug("createSimpleTimeSeriesChart()"); | |
72 int lLowerLevel = Integer.MIN_VALUE; | |
73 int lUpperLevel = Integer.MAX_VALUE; | |
74 if (pStyle.isUseUpperDataLevel() | |
75 && pStyle.getUpperLevel() < Integer.MAX_VALUE) { | |
76 lUpperLevel = pStyle.getUpperLevel(); | |
77 } | |
78 if (pStyle.isUseLowerDataLevel() | |
79 && pStyle.getLowerLevel() > Integer.MIN_VALUE) { | |
80 lLowerLevel = pStyle.getLowerLevel(); | |
81 } | |
82 if (sDebug) | |
83 sLogger.debug(" vor createDataset()"); | |
84 XYDataset lSet = this.createDataset(resultSet, lUpperLevel, | |
85 lLowerLevel,parameters,measurements); | |
86 if (sDebug) | |
87 sLogger.debug(" nach createDataset()"); | |
88 final Color[] color = {Color.black, Color.red, Color.green, Color.blue}; | |
89 DateAxis domain = new DateAxis(pLabels.getDomainAxisLabel()); | |
90 NumberAxis axis; | |
91 StandardXYItemRenderer renderer = new StandardXYItemRenderer(); | |
92 XYPlot plot = new XYPlot(); | |
93 //Global settings | |
94 | |
95 plot.setOrientation(PlotOrientation.VERTICAL); | |
96 plot.setBackgroundPaint(Color.lightGray); | |
97 plot.setDomainGridlinePaint(Color.white); | |
98 plot.setRangeGridlinePaint(Color.white); | |
99 plot.setAxisOffset(new RectangleInsets(5.0,5.0,5.0,5.0)); | |
100 //plot.getRangeAxis().setFixedDimension(10.0); | |
101 plot.setDomainAxis(domain); | |
102 plot.setDomainAxisLocation(AxisLocation.BOTTOM_OR_LEFT); | |
103 if (parameters.size() == 1) { | |
104 KeyValueDescibeData parameter = parameters.iterator().next(); | |
105 axis = new NumberAxis(parameter.getValue()); | |
106 if(parameter.getValue().contains("richtung")){ | |
107 NumberAxis axis1 = new NumberAxis( | |
108 ((String) parameter.getValue()));//,new Range(0.0,360.0)); | |
109 axis1.setTickUnit(new NumberTickUnit(30.0)); | |
110 axis1.setUpperBound(360.0); | |
111 axis1.setLowerBound(0.0); | |
112 //axis1.setDisplayRange(0.0,360.0); | |
113 plot.setRangeAxis( axis1); | |
114 }else{ | |
115 axis.setFixedDimension(10.0); | |
116 axis.setAutoRangeIncludesZero(false); | |
117 plot.setRangeAxis(axis); | |
118 } | |
119 axis.configure(); | |
120 plot.setRangeAxisLocation( AxisLocation.BOTTOM_OR_LEFT); | |
121 plot.setRenderer(renderer); | |
122 plot.setDataset(lSet); | |
123 } else { | |
124 // Individual settings for different parameters | |
125 for (int i = 0; i < lSet.getSeriesCount(); i++) { | |
126 | |
127 plot.setDataset(i, getDataset((TimeSeriesCollection) lSet, i)); | |
128 Color mColor=color[i % color.length]; // zyklische Farbvergabe | |
129 mColor = color[0]; | |
130 // if ( pParameterId.length==1){ | |
131 | |
132 if(((String) lSet.getSeriesKey(i)).contains("richtung")){ | |
133 NumberAxis axis1 = new NumberAxis(((String) lSet.getSeriesKey(i)));//,new Range(0.0,360.0)); | |
134 axis1.setTickUnit(new NumberTickUnit(30.0)); | |
135 //axis1.setDisplayRange(0.0,360.0); | |
136 axis1.setLabelPaint(mColor); | |
137 axis1.setTickLabelPaint(mColor); | |
138 axis1.setUpperBound(360.0); | |
139 axis1.setLowerBound(0.0); | |
140 plot.setRangeAxis(i, axis1); | |
141 | |
142 | |
143 } | |
144 else { | |
145 axis = new NumberAxis((String) lSet.getSeriesKey(i)); | |
146 axis.setFixedDimension(10.0); | |
147 axis.setAutoRangeIncludesZero(false); | |
148 axis.setLabelPaint(mColor); | |
149 axis.setTickLabelPaint(mColor); | |
150 plot.setRangeAxis(i, axis); | |
151 axis.configure(); | |
152 } | |
153 if (i % 2 != 0) | |
154 plot.setRangeAxisLocation(i, AxisLocation.BOTTOM_OR_RIGHT); | |
155 else | |
156 plot.setRangeAxisLocation(i, AxisLocation.BOTTOM_OR_LEFT); | |
157 plot.mapDatasetToRangeAxis(i, i); | |
158 // } | |
159 renderer = new StandardXYItemRenderer(); | |
160 renderer.setSeriesPaint(i, mColor); | |
161 // renderer.setSeriesStroke(i,stroke[j]); | |
162 plot.setRenderer(i, renderer); | |
163 } | |
164 } | |
165 JFreeChart chart = new JFreeChart( | |
166 pLabels.getTitle(), | |
167 new Font ("SansSerif",Font.BOLD,24), | |
168 plot,true); | |
169 | |
170 | |
171 setStyle(chart, pStyle); | |
172 configureRenderingOptions(chart); | |
173 if (sDebug) | |
174 sLogger.debug(" vor encodeChart()"); | |
175 | |
176 encodeChart(chart, pStyle, outputStream); | |
177 } | |
178 private static XYDataset getDataset(TimeSeriesCollection T, int pIndex){ //throws TechnicalChartException{ | |
179 //if (T.getSeriesCount() < pIndex) throw TechnicalChartException(); | |
180 TimeSeriesCollection TSC = new TimeSeriesCollection(); | |
181 TSC.addSeries(T.getSeries(pIndex)); | |
182 return (XYDataset) TSC; | |
183 } | |
184 | |
185 private void configureRenderingOptions(JFreeChart pJfreechart) { | |
186 org.jfree.chart.renderer.xy.XYItemRenderer xyitemrenderer = ((XYPlot) pJfreechart | |
187 .getPlot()).getRenderer(); | |
188 if (xyitemrenderer instanceof XYLineAndShapeRenderer) { | |
189 XYLineAndShapeRenderer xylineandshaperenderer = (XYLineAndShapeRenderer) xyitemrenderer; | |
190 xylineandshaperenderer.setBaseShapesVisible(true); | |
191 xylineandshaperenderer.setBaseShapesFilled(true); | |
192 } | |
193 } | |
194 | |
195 private void setStyle(JFreeChart pJfreechart, ChartStyle pStyle) { | |
196 if (sDebug) | |
197 sLogger.debug("setStyle()"); | |
198 pJfreechart.setBackgroundPaint(pStyle.getCanvasColor()); | |
199 XYPlot xyplot = (XYPlot) pJfreechart.getPlot(); | |
200 xyplot.setBackgroundPaint(pStyle.getPlotBackgroundColor()); | |
201 xyplot.setDomainGridlinePaint(pStyle.getDomainGridlineColor()); | |
202 xyplot.setRangeGridlinePaint(pStyle.getRangeGridlineColor()); | |
203 | |
204 Insets lOffsets = pStyle.getAxisOffset(); | |
205 RectangleInsets lRectangleInsets = new RectangleInsets(lOffsets.mUpper, | |
206 lOffsets.mLeft, lOffsets.mLower, lOffsets.mRight); | |
207 xyplot.setAxisOffset(lRectangleInsets); | |
208 xyplot.setDomainCrosshairVisible(pStyle.isDomainCrosshairVisible()); | |
209 xyplot.setRangeCrosshairVisible(pStyle.isRangeCrosshairVisible()); | |
210 | |
211 } | |
212 | |
213 | |
214 private TimeSeries createTimeSeries(String pTimeSeriesName, Collection<Result> resultSet, | |
215 int lUpperCut, int lLowerCut,int pStart,int pEnd, Date dStart, Date dEnd) throws TechnicalChartException{ | |
216 if (sDebug) | |
217 sLogger.debug("createTimeSeries()"); | |
218 Result lRow0, lRow1; | |
219 | |
220 Date lDate=null, lDate0=null; | |
221 | |
222 TimeSeries lTimeseries = new TimeSeries(pTimeSeriesName, | |
223 org.jfree.data.time.Minute.class); | |
224 try { | |
225 long maxGap=0, lDateDiff=0; | |
226 double lValue=0; | |
227 | |
228 | |
229 int i = 0; | |
230 Iterator<Result> resultIterator = resultSet.iterator(); | |
231 while (resultIterator.hasNext()){ | |
232 Result lRow = resultIterator.next(); | |
233 if (i >= pStart+1 && i <= pEnd){ | |
234 if (i == pStart+1){ | |
235 lRow0 = lRow;// | |
236 | |
237 // Handle Gaps > 0.5% timeserieslength, i.e do not draw here | |
238 // +TODO mache maxGap variabel über diagram options | |
239 maxGap = (dEnd.getTime() - dStart.getTime()) / 200; // 0,5 prozent der Länge | |
240 if (maxGap < 3600000) maxGap=3600010; | |
241 if (maxGap <(dEnd.getTime() - dStart.getTime())/(pEnd-pStart)) | |
242 maxGap = (dEnd.getTime() - dStart.getTime())/(pEnd-pStart) + 1000; | |
243 | |
244 if (sDebug) | |
245 sLogger.debug("MaxGap : "+maxGap/1000+" Länge : "+(dEnd.getTime() - dStart.getTime())/1000+ | |
246 "Intervall "+(dEnd.getTime() - dStart.getTime())/(pEnd-pStart)/1000); | |
247 lDate = lRow0.getDate("XORDINATE"); | |
248 lDate0 = lDate; | |
249 lValue = lRow0.getDouble("YORDINATE"); | |
250 if (lValue > lLowerCut && lValue < lUpperCut){ | |
251 //lTimeseries.addOrUpdate(new Minute(lDate), lValue); | |
252 lTimeseries.add(new Minute(lDate), lValue); | |
253 } | |
254 } | |
255 //for (int i = pStart+1; i <= pEnd; i++) { | |
256 lRow1 =lRow; | |
257 lDate = lRow1.getDate("XORDINATE"); | |
258 lValue = lRow1.getDouble("YORDINATE"); | |
259 lDateDiff = lDate.getTime() - lDate0.getTime(); | |
260 if (lDateDiff > maxGap) { | |
261 // add 1 minute in millisecs to left hand side Date | |
262 // and insert Dummy to break line | |
263 lDate0.setTime((lDate0.getTime() + 60000)); | |
264 lTimeseries.addOrUpdate(new Minute(lDate0), null); | |
265 lTimeseries.addOrUpdate(new Minute(lDate), lValue); | |
266 //lTimeseries.add(new Minute(lDate0), null); | |
267 } else if (lDateDiff == 0) { | |
268 if (sDebug) | |
269 sLogger.debug("Datediff: "+lDateDiff+" bei index : "+i+" Datum : "+lDate+" "+lDate0); | |
270 } | |
271 else if (lValue > lLowerCut && lValue < lUpperCut) { | |
272 lTimeseries.addOrUpdate(new Minute(lDate), lValue); | |
273 //lTimeseries.add(new Minute(lDate), lValue); | |
274 } | |
275 lRow0 = lRow1; | |
276 lDate0 = lDate; | |
277 }else if (i > pEnd){ | |
278 return lTimeseries; | |
279 } | |
280 i++; | |
281 } | |
282 | |
283 | |
284 } catch (OutOfMemoryError e) { | |
285 sLogger.error(e.getMessage(), e); | |
286 return lTimeseries; | |
287 | |
288 } catch (Exception e) { //TechnicalChartException | |
289 sLogger.error(e.getMessage(), e); | |
290 } | |
291 finally { | |
292 } | |
293 | |
294 return lTimeseries; | |
295 } | |
296 | |
297 private XYDataset createDataset(Collection<Result> resultSet, | |
298 int lUpperCut, int lLowerCut,Collection<KeyValueDescibeData> parameters, Collection<KeyValueDescibeData> measurements) throws TechnicalChartException { | |
299 | |
300 TimeSeriesCollection lTimeSeriesCollection = new TimeSeriesCollection(); | |
301 try{ | |
302 Date dStart = null, dEnd= null; | |
303 String break1, break2, break3; | |
304 int mStart = 0; | |
305 int mEnd = 0; | |
306 | |
307 | |
308 Iterator<Result> resultIterator = resultSet.iterator(); | |
309 if (resultIterator.hasNext()){ | |
310 Result row = resultIterator.next(); | |
311 | |
312 break1 = row.getString("GROUP1"); // 2 | |
313 break2 = row.getString("GROUP2"); //3 | |
314 break3 = row.getString("GROUP3"); // 4 | |
315 dStart = row.getDate("XORDINATE"); | |
316 int i = 1; | |
317 while (resultIterator.hasNext()) { | |
318 row = resultIterator.next(); | |
319 if (!break1.equals(row.getString("GROUP1")) | |
320 || !break2 .equals(row.getString("GROUP2")) | |
321 || !break3.equals(row.getString("GROUP3"))){ | |
322 String mTimeSeriesName = findValueTitle(parameters,break1)+" "+ | |
323 findValueTitle(measurements,break2)+"m"; | |
324 | |
325 lTimeSeriesCollection.addSeries(createTimeSeries(mTimeSeriesName, | |
326 resultSet, lUpperCut, lLowerCut, mStart, mEnd, dStart, dEnd)); | |
327 mStart = i; | |
328 dStart = row.getDate("XORDINATE"); | |
329 break1 = row.getString("GROUP1"); | |
330 break2 = row.getString("GROUP2"); //3 | |
331 break3 = row.getString("GROUP3"); // 4 | |
332 | |
333 } | |
334 mEnd = i; | |
335 dEnd = row.getDate("XORDINATE"); | |
336 i = i + 1; | |
337 } | |
338 | |
339 String mTimeSeriesName = findValueTitle(parameters,break1)+" "+ | |
340 findValueTitle(measurements,break2)+"m"; | |
341 lTimeSeriesCollection.addSeries(createTimeSeries(mTimeSeriesName, | |
342 resultSet, lUpperCut, lLowerCut, mStart, mEnd, dStart, dEnd)); | |
343 } | |
344 } | |
345 catch (Exception e){ | |
346 sLogger.error(e.getMessage(), e); | |
347 } | |
348 finally{ | |
349 } | |
350 return lTimeSeriesCollection; | |
351 } | |
352 | |
353 | |
354 | |
355 private void encodeChart(JFreeChart pChart, ChartStyle pStyle, OutputStream outputStream) | |
356 throws IOException { | |
357 if (sDebug) | |
358 sLogger.debug("encodeChart()"); | |
359 KeypointPNGEncoderAdapter lEncoder = new KeypointPNGEncoderAdapter(); | |
360 lEncoder.setEncodingAlpha(true); | |
361 | |
362 int lWidth = (int) pStyle.getChartSize().getWidth(); | |
363 int lHeight = (int) pStyle.getChartSize().getHeight(); | |
364 | |
365 BufferedImage lImage = pChart.createBufferedImage(lWidth, lHeight, | |
366 BufferedImage.BITMASK, null); | |
367 | |
368 lEncoder.encode(lImage, outputStream); | |
369 | |
370 } | |
371 | |
372 private String findValueTitle(Collection<KeyValueDescibeData> values, String pMmtId){ | |
373 int id = 0; | |
374 try { | |
375 id = Integer.parseInt(pMmtId); | |
376 } catch (NumberFormatException e) { | |
377 sLogger.warn(e,e); | |
378 return pMmtId; | |
379 } | |
380 | |
381 Iterator<KeyValueDescibeData> it = values.iterator(); | |
382 while(it.hasNext()){ | |
383 KeyValueDescibeData data = it.next(); | |
384 if (id ==Integer.parseInt(data.getKey())){ | |
385 return data.getValue(); | |
386 } | |
387 } | |
388 return ""; | |
389 } | |
390 } |