Mercurial > dive4elements > gnv-client
view gnv-artifacts/src/main/java/de/intevation/gnv/chart/VerticalProfileChart.java @ 522:c896282c2601
Issue 156 solved. Added width, height and points as parameter to svg and pdf output mode. Width and height have an effact on the width and height of the export, points is a boolean property which enables/disables the drawing of data points.
gnv-artifacts/trunk@616 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author | Ingo Weinzierl <ingo.weinzierl@intevation.de> |
---|---|
date | Mon, 25 Jan 2010 09:18:31 +0000 |
parents | 04a242c67fe6 |
children | d2c68f2f619b |
line wrap: on
line source
package de.intevation.gnv.chart; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.Locale; import org.apache.log4j.Logger; import org.jfree.chart.ChartTheme; import org.jfree.chart.axis.Axis; import org.jfree.chart.plot.XYPlot; import org.jfree.chart.plot.PlotOrientation; import org.jfree.data.xy.XYSeries; import org.jfree.data.general.Series; import org.jfree.data.xy.XYSeriesCollection; import de.intevation.gnv.geobackend.base.Result; import de.intevation.gnv.state.describedata.KeyValueDescibeData; /** * @author Ingo Weinzierl <ingo.weinzierl@intevation.de> */ public class VerticalProfileChart extends AbstractXYLineChart { private static Logger log = Logger.getLogger(VerticalProfileChart.class); protected final double PERCENTAGE = 5.0; protected final double GAP_MAX_LEVEL = Math.sqrt(2.0); protected final int GAP_MAX_VALUES = 60; public VerticalProfileChart( ChartLabels labels, ChartTheme theme, Collection parameters, Collection measurements, Collection dates, Collection result, Collection timeGaps, Locale locale, boolean linesVisible, boolean shapesVisible ) { this.labels = labels; this.theme = theme; this.parameters = parameters; this.measurements = measurements; this.dates = dates; this.resultSet = result; this.timeGaps = timeGaps; this.locale = locale; this.PLOT_ORIENTATION = PlotOrientation.HORIZONTAL; this.linesVisible = linesVisible; this.shapesVisible = shapesVisible; this.datasets = new HashMap(); this.ranges = new HashMap(); } protected void initData() { log.debug("init data for VerticalProfileChart"); String breakPoint1 = null; String breakPoint2 = null; String breakPoint3 = null; Iterator iter = resultSet.iterator(); Result row = null; String seriesName = null; String parameter = null; XYSeries series = null; int idx = 0; int startPos = 0; int endPos = 0; double startValue = 0; double endValue = 0; Result[] results = (Result[]) resultSet.toArray(new Result[resultSet.size()]); while (iter.hasNext()) { row = (Result) iter.next(); // add current data to plot and prepare for next one if (!row.getString("GROUP1").equals(breakPoint1) || !row.getString("GROUP2").equals(breakPoint2) || !row.getString("GROUP3").equals(breakPoint3) ) { log.debug("prepare data/plot for next dataset"); if(series != null) { gapDetection(results, series, startPos, endPos); addSeries(series, parameter, idx); startPos = endPos +1; } // prepare variables for next plot breakPoint1 = row.getString("GROUP1"); breakPoint2 = row.getString("GROUP2"); breakPoint3 = row.getString("GROUP3"); seriesName = createSeriesName( breakPoint1, breakPoint2, breakPoint3 ); parameter = findParameter(seriesName); log.debug("next dataset is '" + seriesName + "'"); series = new XYSeries(seriesName); } addValue(row, series); Double value = row.getDouble("YORDINATE"); if (value != null) storeMaxRange(value, parameter); endPos++; } if (results.length == 0) return; gapDetection(results, series, startPos, endPos); addSeries(series, parameter, idx); addDatasets(); } protected void gapDetection( Result[] results, Series series, int startPos, int endPos ) { double startValue = results[startPos].getDouble("XORDINATE"); double endValue = results[endPos-1].getDouble("XORDINATE"); if (results[0].getInteger("DATAID") == 2) addGapsOnGrid(results, series, startPos, endPos); else addGaps(results, series, startValue, endValue, startPos, endPos); } protected void addValue(Result row, Series series) { ((XYSeries) series).add( row.getDouble("XORDINATE"), row.getDouble("YORDINATE") ); } protected void addSeries(Series series, String parameter, int idx) { log.debug("add series (" + parameter + ")to chart"); if (series == null) { log.warn("no data to add"); return; } XYSeriesCollection xysc = null; if (datasets.containsKey(parameter)) xysc = (XYSeriesCollection) datasets.get(parameter); else xysc = new XYSeriesCollection(); xysc.addSeries((XYSeries) series); datasets.put(parameter, xysc); } protected void addDatasets() { Iterator iter = parameters.iterator(); XYPlot plot = chart.getXYPlot(); int idx = 0; XYSeriesCollection xysc = null; KeyValueDescibeData data = null; String key = null; while (iter.hasNext()) { data = (KeyValueDescibeData) iter.next(); key = data.getValue(); if (datasets.containsKey(key)) { xysc = (XYSeriesCollection)datasets.get(key); plot.setDataset(idx, xysc ); log.debug("Added " + key + " parameter to plot."); prepareAxis(key, idx); adjustRenderer( idx++, xysc.getSeriesCount(), linesVisible, shapesVisible ); } } } protected void localizeDomainAxis(Axis axis, Locale locale) { // call localizeRangeAxis from superclass which formats NumberAxis super.localizeRangeAxis(axis, locale); } protected String createSeriesName( String breakPoint1, String breakPoint2, String breakPoint3 ) { log.debug("create seriesname of verticalprofile chart"); return findValueTitle(parameters, breakPoint1) + " " + findValueTitle(measurements, breakPoint2) + "m"; } protected void addGapsOnGrid( Result[] results, Series series, int startPos, int endPos ) { String axis = getDependendAxisName( results[startPos], results[startPos+1] ); double range = 0; int last = 0; int current = 0; for (int i = startPos+1; i < endPos; i++) { last = results[i-1].getInteger(axis); current = results[i].getInteger(axis); boolean detected = gridDetection(last, current); if (detected) { double xOld = results[i-1].getDouble("XORDINATE"); double xNow = results[i].getDouble("XORDINATE"); log.debug("Gap detected on grid between "+ xOld +" and "+ xNow); ((XYSeries) series).add(xOld+0.0001, null); } } } protected void addGaps( Result[] results, Series series, double startValue, double endValue, int startPos, int endPos ) { double last = 0; double current = 0; int num = results.length; for (int i = startPos+1; i < endPos; i++) { boolean detected = false; last = results[i-1].getDouble("YORDINATE"); current = results[i].getDouble("YORDINATE"); // gap detection for more than GAP_MAX_VALUES values if (num > GAP_MAX_VALUES) detected = simpleDetection(startValue, endValue, last, current); // gap detection for less than GAP_MAX_VALUES values else detected = specialDetection( startValue, endValue, last, current, num ); if (detected) { log.info("Gap between " + last + " and " + current); ((XYSeries) series).add((last+current)/2, null); } } } protected boolean simpleDetection( double start, double end, double last, double current ) { double delta = Math.abs(end - start); double smallDelta = Math.abs(current - last); return (smallDelta > delta / 100 * PERCENTAGE); } protected boolean specialDetection( double start, double end, double last, double current, int count ) { double delta = Math.abs(end - start); double smallDelta = Math.abs(current - last); return (smallDelta > (3.0 / (count - 1) * delta)); } protected boolean gridDetection(double last, double current) { return (Math.abs(current - last) > GAP_MAX_LEVEL); } protected String getDependendAxisName(Result first, Result second) { return "KPOSITION"; } } // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :