Mercurial > dive4elements > gnv-client
comparison gnv-artifacts/src/main/java/de/intevation/gnv/chart/ChartFactory.java @ 65:8b75d01fa5b5
Insert Chart-Classes from old Repository
gnv-artifacts/trunk@48 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author | Tim Englich <tim.englich@intevation.de> |
---|---|
date | Wed, 09 Sep 2009 12:02:09 +0000 |
parents | |
children | 0e9762ebd18d |
comparison
equal
deleted
inserted
replaced
64:5db77e0a8594 | 65:8b75d01fa5b5 |
---|---|
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.BufferedOutputStream; | |
22 import java.io.FileOutputStream; | |
23 import java.io.FileReader; | |
24 import java.io.IOException; | |
25 import java.util.Date; | |
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 au.com.bytecode.opencsv.CSVReader; | |
45 import de.conterra.bsh.gdi.gnviewer.data.filter.IdValue; | |
46 import de.conterra.bsh.gdi.gnviewer.data.filter.MeasurementId; | |
47 import de.conterra.bsh.gdi.gnviewer.data.filter.ParameterId; | |
48 import de.conterra.bsh.gdi.gnviewer.datasources.ResultSet; | |
49 import de.conterra.bsh.gdi.gnviewer.datasources.Row; | |
50 import de.conterra.bsh.gdi.gnviewer.exception.TechnicalException; | |
51 import de.conterra.bsh.gdi.gnviewer.renderer.DiagramRenderer; | |
52 import de.conterra.bsh.gdi.gnviewer.util.TempFile; | |
53 import de.conterra.bsh.gdi.gnviewer.util.TemporaryFileDirectory; | |
54 | |
55 /** | |
56 * The class <code>ChartFactory</code> fulfills the following purposes: | |
57 * <ol> | |
58 * <li></li> | |
59 * </ol> | |
60 * | |
61 * @author blume | |
62 * @version 1.0 | |
63 * @serial 1.0 | |
64 * @see | |
65 * @since 06.12.2007 17:25:59 | |
66 */ | |
67 public class ChartFactory { | |
68 | |
69 /** | |
70 * Default Logging instance | |
71 */ | |
72 private static Logger sLogger = Logger.getLogger(ChartFactory.class); | |
73 private static boolean sDebug = sLogger.isDebugEnabled(); | |
74 private final TemporaryFileDirectory mTmpImageDir; | |
75 | |
76 /** | |
77 * | |
78 */ | |
79 public ChartFactory(TemporaryFileDirectory pTmpImageDir) { | |
80 mTmpImageDir = pTmpImageDir; | |
81 } | |
82 | |
83 public synchronized TempFile createSimpleTimeSeriesChart( | |
84 ChartLabels pLabels, ChartStyle pStyle, String pTimeSeriesName, | |
85 TempFile tempF, IdValue[] pParameterId, | |
86 IdValue[] pMeasurementId, IdValue[] pFeatureId | |
87 ) throws IOException, TechnicalException { | |
88 if (sDebug) | |
89 sLogger.debug("createSimpleTimeSeriesChart()"); | |
90 int lLowerLevel = Integer.MIN_VALUE; | |
91 int lUpperLevel = Integer.MAX_VALUE; | |
92 if (pStyle.isUseUpperDataLevel() | |
93 && pStyle.getUpperLevel() < Integer.MAX_VALUE) { | |
94 lUpperLevel = pStyle.getUpperLevel(); | |
95 } | |
96 if (pStyle.isUseLowerDataLevel() | |
97 && pStyle.getLowerLevel() > Integer.MIN_VALUE) { | |
98 lLowerLevel = pStyle.getLowerLevel(); | |
99 } | |
100 if (sDebug) | |
101 sLogger.debug(" vor createDataset()"); | |
102 XYDataset lSet = createDataset(pTimeSeriesName, tempF, lUpperLevel, | |
103 lLowerLevel,pParameterId,pMeasurementId,pFeatureId); | |
104 if (sDebug) | |
105 sLogger.debug(" nach createDataset()"); | |
106 final Color[] color = {Color.black, Color.red, Color.green, Color.blue}; | |
107 DateAxis domain = new DateAxis("Zeit [UTC]"); | |
108 NumberAxis axis; | |
109 StandardXYItemRenderer renderer = new StandardXYItemRenderer(); | |
110 XYPlot plot = new XYPlot(); | |
111 //Global settings | |
112 | |
113 plot.setOrientation(PlotOrientation.VERTICAL); | |
114 plot.setBackgroundPaint(Color.lightGray); | |
115 plot.setDomainGridlinePaint(Color.white); | |
116 plot.setRangeGridlinePaint(Color.white); | |
117 plot.setAxisOffset(new RectangleInsets(5.0,5.0,5.0,5.0)); | |
118 //plot.getRangeAxis().setFixedDimension(10.0); | |
119 plot.setDomainAxis(domain); | |
120 plot.setDomainAxisLocation(AxisLocation.BOTTOM_OR_LEFT); | |
121 if (pParameterId.length == 1) { | |
122 axis = new NumberAxis(pParameterId[0].getTitle()); | |
123 if(pParameterId[0].getTitle().contains("richtung")){ | |
124 NumberAxis axis1 = new NumberAxis( | |
125 ((String) pParameterId[0].getTitle()));//,new Range(0.0,360.0)); | |
126 axis1.setTickUnit(new NumberTickUnit(30.0)); | |
127 axis1.setUpperBound(360.0); | |
128 axis1.setLowerBound(0.0); | |
129 //axis1.setDisplayRange(0.0,360.0); | |
130 plot.setRangeAxis( axis1); | |
131 }else{ | |
132 axis.setFixedDimension(10.0); | |
133 axis.setAutoRangeIncludesZero(false); | |
134 plot.setRangeAxis(axis); | |
135 } | |
136 axis.configure(); | |
137 plot.setRangeAxisLocation( AxisLocation.BOTTOM_OR_LEFT); | |
138 plot.setRenderer(renderer); | |
139 plot.setDataset(lSet); | |
140 } else { | |
141 // Individual settings for different parameters | |
142 for (int i = 0; i < lSet.getSeriesCount(); i++) { | |
143 | |
144 plot.setDataset(i, getDataset((TimeSeriesCollection) lSet, i)); | |
145 Color mColor=color[i % color.length]; // zyklische Farbvergabe | |
146 mColor = color[0]; | |
147 // if ( pParameterId.length==1){ | |
148 | |
149 if(((String) lSet.getSeriesKey(i)).contains("richtung")){ | |
150 NumberAxis axis1 = new NumberAxis(((String) lSet.getSeriesKey(i)));//,new Range(0.0,360.0)); | |
151 axis1.setTickUnit(new NumberTickUnit(30.0)); | |
152 //axis1.setDisplayRange(0.0,360.0); | |
153 axis1.setLabelPaint(mColor); | |
154 axis1.setTickLabelPaint(mColor); | |
155 axis1.setUpperBound(360.0); | |
156 axis1.setLowerBound(0.0); | |
157 plot.setRangeAxis(i, axis1); | |
158 | |
159 | |
160 } | |
161 else { | |
162 axis = new NumberAxis((String) lSet.getSeriesKey(i)); | |
163 axis.setFixedDimension(10.0); | |
164 axis.setAutoRangeIncludesZero(false); | |
165 axis.setLabelPaint(mColor); | |
166 axis.setTickLabelPaint(mColor); | |
167 plot.setRangeAxis(i, axis); | |
168 axis.configure(); | |
169 } | |
170 if (i % 2 != 0) | |
171 plot.setRangeAxisLocation(i, AxisLocation.BOTTOM_OR_RIGHT); | |
172 else | |
173 plot.setRangeAxisLocation(i, AxisLocation.BOTTOM_OR_LEFT); | |
174 plot.mapDatasetToRangeAxis(i, i); | |
175 // } | |
176 renderer = new StandardXYItemRenderer(); | |
177 renderer.setSeriesPaint(i, mColor); | |
178 // renderer.setSeriesStroke(i,stroke[j]); | |
179 plot.setRenderer(i, renderer); | |
180 } | |
181 } | |
182 JFreeChart chart = new JFreeChart( | |
183 pLabels.getTitle(), | |
184 new Font ("SansSerif",Font.BOLD,24), | |
185 plot,true); | |
186 | |
187 | |
188 setStyle(chart, pStyle); | |
189 configureRenderingOptions(chart); | |
190 if (sDebug) | |
191 sLogger.debug(" vor encodeChart()"); | |
192 | |
193 return encodeChart(chart, pStyle); | |
194 } | |
195 private static XYDataset getDataset(TimeSeriesCollection T, int pIndex){ //throws TechnicalException{ | |
196 //if (T.getSeriesCount() < pIndex) throw TechnicalException(); | |
197 TimeSeriesCollection TSC = new TimeSeriesCollection(); | |
198 TSC.addSeries(T.getSeries(pIndex)); | |
199 return (XYDataset) TSC; | |
200 } | |
201 public synchronized TempFile createScatterPlot(ChartStyle pStyle, | |
202 ResultSet pResults) throws TechnicalException, IOException { | |
203 ScatterPlot lPlot = new ScatterPlot("ScatterPlot", pResults); | |
204 return encodeChart(lPlot.getChart(), pStyle); | |
205 } | |
206 | |
207 private void configureRenderingOptions(JFreeChart pJfreechart) { | |
208 org.jfree.chart.renderer.xy.XYItemRenderer xyitemrenderer = ((XYPlot) pJfreechart | |
209 .getPlot()).getRenderer(); | |
210 if (xyitemrenderer instanceof XYLineAndShapeRenderer) { | |
211 XYLineAndShapeRenderer xylineandshaperenderer = (XYLineAndShapeRenderer) xyitemrenderer; | |
212 xylineandshaperenderer.setBaseShapesVisible(true); | |
213 xylineandshaperenderer.setBaseShapesFilled(true); | |
214 } | |
215 } | |
216 | |
217 private void setStyle(JFreeChart pJfreechart, ChartStyle pStyle) { | |
218 if (sDebug) | |
219 sLogger.debug("setStyle()"); | |
220 pJfreechart.setBackgroundPaint(pStyle.getCanvasColor()); | |
221 XYPlot xyplot = (XYPlot) pJfreechart.getPlot(); | |
222 xyplot.setBackgroundPaint(pStyle.getPlotBackgroundColor()); | |
223 xyplot.setDomainGridlinePaint(pStyle.getDomainGridlineColor()); | |
224 xyplot.setRangeGridlinePaint(pStyle.getRangeGridlineColor()); | |
225 | |
226 Insets lOffsets = pStyle.getAxisOffset(); | |
227 RectangleInsets lRectangleInsets = new RectangleInsets(lOffsets.mUpper, | |
228 lOffsets.mLeft, lOffsets.mLower, lOffsets.mRight); | |
229 xyplot.setAxisOffset(lRectangleInsets); | |
230 xyplot.setDomainCrosshairVisible(pStyle.isDomainCrosshairVisible()); | |
231 xyplot.setRangeCrosshairVisible(pStyle.isRangeCrosshairVisible()); | |
232 | |
233 } | |
234 | |
235 | |
236 private TimeSeries createTimeSeries(String pTimeSeriesName, TempFile tempF, | |
237 int lUpperCut, int lLowerCut,int pStart,int pEnd, Date dStart, Date dEnd) throws TechnicalException{ | |
238 if (sDebug) | |
239 sLogger.debug("createTimeSeries()"); | |
240 Row lRow0, lRow1, lRowVorEnd; | |
241 | |
242 Date lDate=null, lDate0=null; | |
243 DiagramRenderer mDiagramRenderer = new DiagramRenderer(); | |
244 | |
245 CSVReader reader = null; | |
246 TimeSeries lTimeseries = new TimeSeries(pTimeSeriesName, | |
247 org.jfree.data.time.Minute.class); | |
248 try { | |
249 reader = new CSVReader (new FileReader(tempF.getFile()), ';'); | |
250 | |
251 | |
252 | |
253 long maxGap=0, lDateDiff=0; | |
254 double lValue=0; | |
255 String [] lRow = null; | |
256 | |
257 int i = 0; | |
258 while ((lRow = reader.readNext()) != null){ | |
259 | |
260 if (i >= pStart+1 && i <= pEnd){ | |
261 if (i == pStart+1){ | |
262 lRow0 = new Row(lRow);// | |
263 | |
264 // Handle Gaps > 0.5% timeserieslength, i.e do not draw here | |
265 // +TODO mache maxGap variabel über diagram options | |
266 maxGap = (dEnd.getTime() - dStart.getTime()) / 200; // 0,5 prozent der Länge | |
267 if (maxGap < 3600000) maxGap=3600010; | |
268 if (maxGap <(dEnd.getTime() - dStart.getTime())/(pEnd-pStart)) | |
269 maxGap = (dEnd.getTime() - dStart.getTime())/(pEnd-pStart) + 1000; | |
270 | |
271 if (sDebug) | |
272 sLogger.debug("MaxGap : "+maxGap/1000+" Länge : "+(dEnd.getTime() - dStart.getTime())/1000+ | |
273 "Intervall "+(dEnd.getTime() - dStart.getTime())/(pEnd-pStart)/1000); | |
274 lDate = lRow0.getDateValue(0); | |
275 lDate0 = lDate; | |
276 lValue = lRow0.getDoubleValue(1); | |
277 if (lValue > lLowerCut && lValue < lUpperCut){ | |
278 //lTimeseries.addOrUpdate(new Minute(lDate), lValue); | |
279 lTimeseries.add(new Minute(lDate), lValue); | |
280 } | |
281 } | |
282 //for (int i = pStart+1; i <= pEnd; i++) { | |
283 lRow1 = new Row (lRow); | |
284 lDate = lRow1.getDateValue(0); | |
285 lValue = lRow1.getDoubleValue(1); | |
286 lDateDiff = lDate.getTime() - lDate0.getTime(); | |
287 if (lDateDiff > maxGap) { | |
288 // add 1 minute in millisecs to left hand side Date | |
289 // and insert Dummy to break line | |
290 lDate0.setTime((lDate0.getTime() + 60000)); | |
291 lTimeseries.addOrUpdate(new Minute(lDate0), null); | |
292 lTimeseries.addOrUpdate(new Minute(lDate), lValue); | |
293 //lTimeseries.add(new Minute(lDate0), null); | |
294 } else if (lDateDiff == 0) { | |
295 if (sDebug) | |
296 sLogger.debug("Datediff: "+lDateDiff+" bei index : "+i+" Datum : "+lDate+" "+lDate0); | |
297 } | |
298 else if (lValue > lLowerCut && lValue < lUpperCut) { | |
299 lTimeseries.addOrUpdate(new Minute(lDate), lValue); | |
300 //lTimeseries.add(new Minute(lDate), lValue); | |
301 } | |
302 lRow0 = lRow1; | |
303 lDate0 = lDate; | |
304 } | |
305 i++; | |
306 } | |
307 | |
308 | |
309 } catch (OutOfMemoryError e) { | |
310 sLogger.error(e.getMessage(), e); | |
311 return lTimeseries; | |
312 | |
313 } catch (Exception e) { //TechnicalException | |
314 sLogger.error(e.getMessage(), e); | |
315 } | |
316 finally { | |
317 try{ | |
318 reader.close(); | |
319 } | |
320 catch (Exception e){ | |
321 sLogger.error(e.getMessage(), e); | |
322 } | |
323 } | |
324 | |
325 return lTimeseries; | |
326 } | |
327 | |
328 private XYDataset createDataset(String pTimeseriesName, TempFile tempF, | |
329 int lUpperCut, int lLowerCut,IdValue[] pParameterId, | |
330 IdValue[] pMeasurementId, IdValue[] pFeatureID) throws TechnicalException { | |
331 | |
332 CSVReader reader=null; | |
333 TimeSeriesCollection lTimeSeriesCollection = new TimeSeriesCollection(); | |
334 try{ | |
335 for (int i=0;i<pMeasurementId.length;i++) System.out.println("Measurement Depth "+ | |
336 pMeasurementId[i].getTitle() ); | |
337 for (int i=0;i<pParameterId.length;i++) System.out.println("Parameter "+ | |
338 pParameterId[i].getTitle() ); | |
339 | |
340 Date dStart = null, dEnd= null; | |
341 int break1, break2, break3; | |
342 int mStart = 0; | |
343 int mEnd = 0; | |
344 | |
345 reader = new CSVReader (new FileReader(tempF.getFile()), ';'); | |
346 | |
347 String [] sArrayStrLine = reader.readNext(); | |
348 | |
349 Row row = new Row(sArrayStrLine); | |
350 | |
351 break1 = new Integer (sArrayStrLine[2]).intValue(); | |
352 break2 = new Integer (sArrayStrLine[3]).intValue(); | |
353 break3 = new Integer (sArrayStrLine[4]).intValue(); | |
354 dStart = row.getDateValue(0); | |
355 int i = 1; | |
356 while ((sArrayStrLine = reader.readNext()) != null) { | |
357 row = new Row(sArrayStrLine); | |
358 if (break1 != new Integer (sArrayStrLine[2]).intValue() | |
359 || break2 != new Integer (sArrayStrLine[3]).intValue() | |
360 || break3 != new Integer (sArrayStrLine[4]).intValue()){ | |
361 String mTimeSeriesName = findValueTitle(pParameterId,break1)+" "+ | |
362 findValueTitle(pMeasurementId,break2)+"m"; | |
363 | |
364 lTimeSeriesCollection.addSeries(createTimeSeries(mTimeSeriesName, | |
365 tempF, lUpperCut, lLowerCut, mStart, mEnd, dStart, dEnd)); | |
366 mStart = i; | |
367 dStart = row.getDateValue(0); | |
368 break1 = new Integer (sArrayStrLine[2]).intValue(); | |
369 break2 = new Integer (sArrayStrLine[3]).intValue(); | |
370 break3 = new Integer (sArrayStrLine[4]).intValue(); | |
371 | |
372 } | |
373 mEnd = i; | |
374 //mEnd ++; | |
375 dEnd = row.getDateValue(0); | |
376 i = i + 1; | |
377 } | |
378 String mTimeSeriesName = findValueTitle(pParameterId,break1)+" "+ | |
379 findValueTitle(pMeasurementId,break2)+"m"; | |
380 lTimeSeriesCollection.addSeries(createTimeSeries(mTimeSeriesName, | |
381 tempF, lUpperCut, lLowerCut, mStart, mEnd, dStart, dEnd)); | |
382 | |
383 } | |
384 catch (Exception e){ | |
385 sLogger.error(e.getMessage(), e); | |
386 } | |
387 finally{ | |
388 try{ | |
389 reader.close(); | |
390 } | |
391 catch (Exception e){ | |
392 sLogger.error(e.getMessage(), e); | |
393 } | |
394 } | |
395 return lTimeSeriesCollection; | |
396 } | |
397 | |
398 | |
399 | |
400 private TempFile encodeChart(JFreeChart pChart, ChartStyle pStyle) | |
401 throws IOException { | |
402 if (sDebug) | |
403 sLogger.debug("encodeChart()"); | |
404 KeypointPNGEncoderAdapter lEncoder = new KeypointPNGEncoderAdapter(); | |
405 lEncoder.setEncodingAlpha(true); | |
406 | |
407 int lWidth = (int) pStyle.getChartSize().getWidth(); | |
408 int lHeight = (int) pStyle.getChartSize().getHeight(); | |
409 | |
410 FileOutputStream lFileOutputStream = null; | |
411 BufferedOutputStream lBufferedOutputStream = null; | |
412 | |
413 TempFile lImageFile = mTmpImageDir.createFile(".png"); | |
414 | |
415 BufferedImage lImage = pChart.createBufferedImage(lWidth, lHeight, | |
416 BufferedImage.BITMASK, null); | |
417 lFileOutputStream = new FileOutputStream(lImageFile.getFile()); | |
418 lBufferedOutputStream = new BufferedOutputStream(lFileOutputStream); | |
419 lEncoder.encode(lImage, lBufferedOutputStream); | |
420 lBufferedOutputStream.close(); | |
421 lFileOutputStream.close(); | |
422 | |
423 return lImageFile; | |
424 | |
425 } | |
426 | |
427 private String findValueTitle(IdValue[] pValueId,int pMmtId){ | |
428 for (int i=0;i<pValueId.length;i++){ | |
429 if ((long) pMmtId ==pValueId[i].getValue())return pValueId[i].getTitle(); | |
430 } | |
431 return ""; | |
432 } | |
433 private String findValueTitle(IdValue[] pValueId,long pMmtId){ | |
434 for (int i=0;i<pValueId.length;i++){ | |
435 if ( pMmtId ==pValueId[i].getValue())return pValueId[i].getTitle(); | |
436 } | |
437 return ""; | |
438 } | |
439 } |