Mercurial > dive4elements > river
diff flys-artifacts/src/main/java/de/intevation/flys/exports/XYChartGenerator.java @ 1931:7c52e9cb2a72
Allow more than two datasets and more flexibility with axes in plots. Based on patch by S. Teichmann.
flys-artifacts/trunk@3312 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author | Felix Wolfsteller <felix.wolfsteller@intevation.de> |
---|---|
date | Thu, 24 Nov 2011 07:20:46 +0000 |
parents | de0c2bbb27f9 |
children | 17e18948fe5e |
line wrap: on
line diff
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/XYChartGenerator.java Wed Nov 23 14:09:29 2011 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/XYChartGenerator.java Thu Nov 24 07:20:46 2011 +0000 @@ -10,8 +10,10 @@ import java.util.ArrayList; import java.util.HashMap; +import java.util.TreeMap; import java.util.List; import java.util.Map; +import java.util.SortedMap; import org.w3c.dom.Document; @@ -31,6 +33,7 @@ import org.jfree.data.Range; import org.jfree.data.xy.XYSeries; import org.jfree.data.xy.XYSeriesCollection; +import org.jfree.data.xy.XYDataset; import org.jfree.ui.RectangleInsets; @@ -52,11 +55,8 @@ /** The logger that is used in this generator. */ private static Logger logger = Logger.getLogger(XYChartGenerator.class); - /** SeriesCollection used for the first axis. */ - protected XYSeriesCollection first; - - /** SeriesCollection used for the second axis. */ - protected XYSeriesCollection second; + /** Map of datasets ("index"). */ + protected SortedMap<Integer, List<XYDataset>> datasets; /** List of annotations to insert in plot. */ protected List<FLYSAnnotation> annotations; @@ -71,6 +71,13 @@ public static final float DEFAULT_GRID_LINE_WIDTH = 0.3f; + public XYChartGenerator() { + xRanges = new HashMap<Integer, Range>(); + yRanges = new HashMap<Integer, Range>(); + datasets = new TreeMap<Integer, List<XYDataset>>(); + } + + /** * Returns the title of a chart. * @@ -157,10 +164,9 @@ false, false); + XYPlot plot = (XYPlot) chart.getPlot(); chart.setBackgroundPaint(Color.WHITE); - chart.getPlot().setBackgroundPaint(Color.WHITE); - - XYPlot plot = (XYPlot) chart.getPlot(); + plot.setBackgroundPaint(Color.WHITE); addDatasets(plot); addAnnotations(plot); @@ -169,6 +175,7 @@ localizeAxes(plot); removeEmptyRangeAxes(plot); + createAxes(plot); adjustAxes(plot); preparePointRanges(plot); @@ -181,73 +188,67 @@ /** - * Add first and second dataset to plot. + * Add datasets to plot. * @param plot plot to add datasets to. */ protected void addDatasets(XYPlot plot) { - if (first != null) { - logger.debug("Set the first axis dataset."); - plot.setDataset(0, first); - } - if (second != null) { - logger.debug("Set the second axis dataset."); - plot.setDataset(1, second); - } - } - - - public void addFirstAxisSeries(XYSeries series, boolean visible) { - if (first == null) { - first = new XYSeriesCollection(); - } - - if (series != null) { - if (visible) { - first.addSeries(series); + int count = 0; + for (Map.Entry<Integer, List<XYDataset>> entry: datasets.entrySet()) { + List<Integer> axisList = new ArrayList<Integer>(1); + axisList.add(entry.getKey()); + for (XYDataset dataset: entry.getValue()) { + int index = count++; + plot.setDataset(index, dataset); + plot.mapDatasetToRangeAxes(index, axisList); } - - combineYRanges(new Range(series.getMinY(), series.getMaxY()), 0); - combineXRanges(new Range(series.getMinX(), series.getMaxX()), 0); } } - public void addSecondAxisSeries(XYSeries series, boolean visible) { - if (second == null) { - second = new XYSeriesCollection(); - } - - if (series != null) { - if (visible) { - second.addSeries(series); - } - - combineYRanges(new Range(series.getMinY(), series.getMaxY()), 1); - combineXRanges(new Range(series.getMinX(), series.getMaxX()), 0); - } - } - - - private void combineXRanges(Range range, int index) { - Integer key = Integer.valueOf(index); - - if (xRanges == null) { - xRanges = new HashMap<Integer, Range>(); - xRanges.put(key, range); + /** + * Add given series. + * @param series the dataseries to include in plot. + * @param index index of the series and of its axis. + * @param visible whether or not the data should be plotted. + */ + public void addAxisSeries(XYSeries series, int index, boolean visible) { + if (series == null) { return; } - Range newX = null; - Range oldX = xRanges.get(key); + if (visible) { + XYSeriesCollection collection = new XYSeriesCollection(series); - if (oldX != null) { - newX = Range.combine(oldX, range); - } - else { - newX = range; + List<XYDataset> dataset = datasets.get(index); + + if (dataset == null) { + dataset = new ArrayList<XYDataset>(); + datasets.put(index, dataset); + } + + dataset.add(collection); } - xRanges.put(key, newX); + // Do this also when not visible to have axis scaled by default such + // that every data-point could be seen (except for annotations). + combineXRanges(new Range(series.getMinX(), series.getMaxX()), 0); + combineYRanges(new Range(series.getMinY(), series.getMaxY()), index); + } + + /** + * Effect: extend range of x axis to include given limits. + * @param range the given ("minimal") range. + * @param index index of axis to be merged. + */ + private void combineXRanges(Range range, int index) { + + Range old = xRanges.get(index); + + if (old != null) { + range = Range.combine(old, range); + } + + xRanges.put(index, range); } @@ -255,25 +256,14 @@ * @param range the new range. */ private void combineYRanges(Range range, int index) { - Integer key = Integer.valueOf(index); - if (yRanges == null) { - yRanges = new HashMap<Integer, Range>(); - yRanges.put(key, range); - return; + Range old = yRanges.get(index); + + if (old != null) { + range = Range.combine(old, range); } - Range newY = null; - Range oldY = yRanges.get(key); - - if (oldY != null) { - newY = Range.combine(oldY, range); - } - else { - newY = range; - } - - yRanges.put(key, newY); + yRanges.put(index, range); } @@ -293,17 +283,47 @@ } + /** + * Create y-axes. + */ + public void createAxes(XYPlot plot) { + logger.debug("XYChartGenerator.createAxes"); + Integer last = datasets.lastKey(); + + if (last != null) { + for (int i = last; i >= 0; --i) { + if (datasets.containsKey(i)) { + plot.setRangeAxis(i, createYAxis(i)); + } + } + } + } + + /** + * Create Y (range) axis for given index. + * Shall be overriden by subclasses. + */ + protected NumberAxis createYAxis(int index) { + NumberAxis axis = new NumberAxis("default axis"); + return axis; + } + private void removeEmptyRangeAxes(XYPlot plot) { - if (first == null) { - plot.setRangeAxis(0, null); - } + Integer last = datasets.lastKey(); - if (second == null) { - plot.setRangeAxis(1, null); + if (last != null) { + for (int i = last-1; i >= 0; --i) { + if (!datasets.containsKey(i)) { + plot.setRangeAxis(i, null); + } + } } } + /** + * Expands X and Y axes if only a point is shown. + */ private void preparePointRanges(XYPlot plot) { for (int i = 0, num = plot.getDomainAxisCount(); i < num; i++) { Integer key = Integer.valueOf(i); @@ -325,6 +345,9 @@ } + /** + * Expand range by percent. + */ public static Range expandRange(Range range, double percent) { if (range == null) { return null; @@ -479,14 +502,18 @@ /** - * Adjusts the axes of a plot. + * Adjusts the axes of a plot (the first axis does not include zero). * * @param plot The XYPlot of the chart. */ protected void adjustAxes(XYPlot plot) { NumberAxis yAxis = (NumberAxis) plot.getRangeAxis(); - - yAxis.setAutoRangeIncludesZero(false); + if (yAxis == null) { + logger.warn("No Axis to setAutoRangeIncludeZero."); + } + else { + yAxis.setAutoRangeIncludesZero(false); + } } @@ -508,14 +535,6 @@ plot.setRangeGridlinesVisible(true); plot.setAxisOffset(new RectangleInsets(0d, 0d, 0d, 0d)); - - if (plot.getDataset(0) != null) { - plot.mapDatasetToRangeAxis(0, 0); - } - - if (plot.getDataset(1) != null) { - plot.mapDatasetToRangeAxis(1, 1); - } } @@ -581,12 +600,14 @@ protected void applyThemes(XYPlot plot) { - if (first != null) { - applyThemes(plot, first, 0); - } - if (second != null) { - applyThemes(plot, second, 1); + for (Map.Entry<Integer, List<XYDataset>> entry: datasets.entrySet()) { + int axis = entry.getKey(); + for (XYDataset dataset: entry.getValue()) { + if (dataset instanceof XYSeriesCollection) { + applyThemes(plot, (XYSeriesCollection)dataset, axis); + } + } } }