diff gnv-artifacts/src/main/java/de/intevation/gnv/chart/VerticalCrossSectionChart.java @ 1119:7c4f81f74c47

merged gnv-artifacts
author Thomas Arendsen Hein <thomas@intevation.de>
date Fri, 28 Sep 2012 12:14:00 +0200
parents f953c9a559d8
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gnv-artifacts/src/main/java/de/intevation/gnv/chart/VerticalCrossSectionChart.java	Fri Sep 28 12:14:00 2012 +0200
@@ -0,0 +1,367 @@
+/*
+ * Copyright (c) 2010 by Intevation GmbH
+ *
+ * This program is free software under the LGPL (>=v2.1)
+ * Read the file LGPL.txt coming with the software for details
+ * or visit http://www.gnu.org/licenses/ if it does not exist.
+ */
+
+package de.intevation.gnv.chart;
+
+import de.intevation.gnv.jfreechart.PolygonDataset;
+import de.intevation.gnv.jfreechart.PolygonPlot;
+import de.intevation.gnv.jfreechart.PolygonRenderer;
+import de.intevation.gnv.jfreechart.PolygonSeries;
+
+import de.intevation.gnv.math.AttributedXYColumns;
+
+import de.intevation.gnv.raster.Palette;
+
+import java.awt.Color;
+import java.awt.Paint;
+
+import java.text.NumberFormat;
+
+import java.util.HashSet;
+import java.util.Locale;
+import java.util.Map;
+
+import org.jfree.chart.JFreeChart;
+
+import org.jfree.chart.axis.NumberAxis;
+import org.jfree.chart.axis.SymbolAxis;
+import org.jfree.chart.axis.ValueAxis;
+
+import org.jfree.chart.plot.PlotOrientation;
+
+import org.jfree.chart.renderer.LookupPaintScale;
+
+import org.jfree.chart.title.PaintScaleLegend;
+import org.jfree.chart.title.TextTitle;
+
+import org.jfree.data.Range;
+
+import org.jfree.ui.RectangleEdge;
+import org.jfree.ui.RectangleInsets;
+
+/**
+ * This class represents a 2D chart containing polygon data.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ * @author <a href="mailto:sascha.teichmann@intevation.de">Sascha L. Teichmann</a>
+ */
+public class VerticalCrossSectionChart
+implements   Chart
+{
+    /**
+     *  Lookup class for retrieving a color which corresponds to a specific
+     *  integer value.
+     */
+    public static final class PalettePaintLookup
+    implements PolygonRenderer.PaintLookup
+    {
+        /**
+         * Object storing information about value ranges and its coresponding
+         * colors and descriptions.
+         */
+        private Palette             palette;
+
+        /**
+         * Map containing some special <code>Paint</code> like ground fillcolor.
+         */
+        private Map<Integer, Paint> special;
+
+        /**
+         * Constructor
+         *
+         * @param palette See {@link #palette}
+         */
+        public PalettePaintLookup(Palette palette) {
+            this(palette, null);
+        }
+
+        /**
+         * Constructor
+         *
+         * @param palette See {@link #palette}
+         * @param special See {@link #special}
+         */
+        public PalettePaintLookup(
+            Palette             palette,
+            Map<Integer, Paint> special
+        ) {
+            this.palette = palette;
+            this.special = special;
+        }
+
+        /**
+         * @param index Index of a <code>Paint</code>
+         *
+         * @return <code>Paint</code> object for a given index.
+         */
+        public Paint getPaint(int index) {
+            if (special != null) {
+                Paint paint = special.get(index);
+                if (paint != null) {
+                    return paint;
+                }
+            }
+            return index < 0
+                ? Color.black
+                : palette.getColor(index);
+        }
+    } // class PalettePaintLookup
+
+    /**
+     * This class is used to turn labels which represent a number into a
+     * specific format.
+     */
+    public static class LocalizedLabelGenerator
+    extends             PolygonRenderer.DefaultLabelGenerator
+    {
+        /**
+         * <code>NumberFormat</code> which is used to turn a number into a
+         * specific format.
+         */
+        protected NumberFormat format;
+
+        /**
+         * Constructor
+         */
+        public LocalizedLabelGenerator() {
+        }
+
+        /**
+         * Constructor
+         *
+         * @param format See {@link #format}
+         */
+        public LocalizedLabelGenerator(NumberFormat format) {
+            this.format = format;
+        }
+
+        /**
+         * If label is a <code>Number</code>, it is turned into a format
+         * specified by {@link #format}.
+         *
+         * @param label Label to format.
+         *
+         * @return String representation of label.
+         */
+        @Override
+        protected String toString(Object label) {
+            return label instanceof Number
+                ? format.format(((Number)label).doubleValue())
+                : super.toString(label);
+        }
+    } // class LocalizedLabelGenerator
+
+    public static double MARGIN_TOP    = 0.05d;
+    public static double MARGIN_BOTTOM = 0.00d;
+    public static double MARGIN_LEFT   = 0.00d;
+    public static double MARGIN_RIGHT  = 0.05d;
+
+    /**
+     * JFreeChart object stored at this place after chart creation.
+     */
+    protected JFreeChart chart;
+
+    /**
+     * Stores {@link de.intevation.gnv.jfreechart.PolygonDataset} which is used
+     * to create a vertical cross chart.
+     */
+    protected AttributedXYColumns columns;
+
+    /**
+     * Map which contains colors to fill polygons draw by this chart.
+     */
+    protected Map<Integer, Paint> special;
+
+    /**
+     * Object used to map value intervals to specific colors and descriptions.
+     */
+    protected Palette             palette;
+
+    /**
+     * Locale object used for i18n support.
+     */
+    protected Locale              locale;
+
+    /**
+     * Labels for decorating the chart.
+     */
+    protected ChartLabels         labels;
+
+    /**
+     * Default Constructor
+     */
+    public VerticalCrossSectionChart() {
+    }
+
+    /**
+     * Constructor for VerticalCrossSectionChart creation.
+     *
+     * @param columns See {@link #columns}
+     * @param palette See {@link #palette}
+     * @param locale See {@link #locale}
+     * @param labels See {@link #labels}
+     */
+    public VerticalCrossSectionChart(
+        AttributedXYColumns columns,
+        Palette             palette,
+        Locale              locale,
+        ChartLabels         labels
+    ) {
+        this(columns, palette, null, locale, labels);
+    }
+
+    /**
+     * Constructor for VerticalCrossSectionChart creation.
+     *
+     * @param columns See {@link #columns}
+     * @param palette See {@link #palette}
+     * @param special See {@link #special}
+     * @param locale See {@link #locale}
+     * @param labels See {@link #labels}
+     */
+    public VerticalCrossSectionChart(
+        AttributedXYColumns columns,
+        Palette             palette,
+        Map<Integer, Paint> special,
+        Locale              locale,
+        ChartLabels         labels
+    ) {
+        this.columns = columns;
+        this.palette = palette;
+        this.special = special;
+        this.locale  = locale;
+        this.labels  = labels;
+    }
+
+    /**
+     * This method is used to create a JFreeChart from this object. A 2D plot is
+     * drawn and a legend panel is created containing each value range.
+     *
+     * @return JFreeChart object
+     */
+    protected JFreeChart createChart() {
+
+        boolean legendB  = false;
+        boolean tooltips = false;
+        boolean urls     = false;
+
+        PlotOrientation po  = PlotOrientation.HORIZONTAL;
+        PolygonDataset data = columns.getPolygonDataset();
+
+        HashSet<Integer> usedColors = new HashSet<Integer>();
+
+        for (int i = data.getSeriesCount()-1; i >= 0; --i) {
+            PolygonSeries ps = data.getSeries(i);
+            Integer fill = (Integer)ps.getAttribute("fill");
+            if (fill != null
+            && (special != null && !special.containsKey(fill))) {
+                usedColors.add(fill);
+            }
+        }
+
+        NumberFormat format = NumberFormat.getInstance(locale);
+        format.setMinimumFractionDigits(0);
+        format.setMaximumFractionDigits(2);
+
+        PolygonRenderer renderer = new PolygonRenderer(
+            new PalettePaintLookup(palette, special),
+            new LocalizedLabelGenerator(format));
+
+        ValueAxis domainAxis = new NumberAxis(this.labels.getDomainAxisLabel());
+        ValueAxis rangeAxis  = new NumberAxis(this.labels.getRangeAxisLabel());
+
+        PolygonPlot plot = new PolygonPlot(
+            data,
+            renderer,
+            domainAxis,
+            rangeAxis,
+            null);
+
+        plot.setOutlinePaint(Color.WHITE);
+
+        String [] labels = new String[usedColors.size()];
+
+        int colors = palette.getSize();
+        LookupPaintScale lookupPaint =
+            new LookupPaintScale(-0.5d, labels.length-0.5d, Color.white);
+
+        Color color = null;
+
+        for (int i = 0, j = labels.length-1; i < colors && j >= 0; i++) {
+            if (usedColors.contains(i)) {
+                Palette.Entry entry = palette.getEntryByIndex(i);
+                color     = entry.getColor();
+                labels[j] = entry.getDescription();
+                lookupPaint.add(j-0.5d, color);
+                --j;
+            }
+        }
+
+        JFreeChart chart = new JFreeChart(
+            this.labels.getTitle(),
+            JFreeChart.DEFAULT_TITLE_FONT,
+            plot,
+            legendB);
+
+        chart.removeLegend();
+        chart.addSubtitle(new TextTitle(this.labels.getSubtitle()));
+
+        SymbolAxis scale = new SymbolAxis(this.labels.getParameterName(), labels);
+        scale.setRange(-1.5d, labels.length+0.5d);
+        scale.setGridBandsVisible(false);
+        scale.setPlot(plot);
+
+        PaintScaleLegend legend = new PaintScaleLegend(
+            lookupPaint, scale);
+        legend.setMargin(new RectangleInsets(3d, 10d, 3d, 10d));
+        legend.setPosition(RectangleEdge.LEFT);
+        legend.setAxisOffset(5d);
+
+        chart.addSubtitle(legend);
+
+        // XXX Workaround, because Axes labels are cut at the
+        // left/right/top/bottom edge. The following lines add a white border
+        // between data area and plot border.
+        // see http://www.jfree.org/phpBB2/viewtopic.php?f=3&t=22177&start=0&hilit=axis+labels+cut
+        ValueAxis xAxis = plot.getDomainAxis();
+        Range xRange    = xAxis.getRange();
+        xRange = Range.expand(xRange, MARGIN_LEFT, MARGIN_RIGHT);
+        xAxis.setRange(xRange);
+        plot.setDomainAxis(xAxis);
+
+        ValueAxis yAxis = plot.getRangeAxis();
+        Range yRange    = yAxis.getRange();
+        yRange = Range.expand(yRange, MARGIN_BOTTOM, MARGIN_TOP);
+        yAxis.setRange(yRange);
+        plot.setRangeAxis(yAxis);
+
+        chart.setPadding(new RectangleInsets(10d, 10d, 10d, 10d));
+
+        return chart;
+    }
+
+    /**
+     * @see de.intevation.gnv.chart.Chart#generateChart()
+     */
+    public JFreeChart generateChart() {
+        if (chart == null) {
+            chart = createChart();
+        }
+
+        return chart;
+    }
+
+    /**
+     * Set the background paint of {@link #chart}.
+     * @param paint
+     */
+    public void setBackgroundPaint(Paint paint) {
+        chart.setBackgroundPaint(paint);
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :

http://dive4elements.wald.intevation.org