diff gnv-artifacts/src/main/java/de/intevation/gnv/jfreechart/PolygonPlot.java @ 422:f426f55d4f7a

Added Ingo Weinzierl's special JFreeChart classes. gnv-artifacts/trunk@470 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Mon, 21 Dec 2009 16:47:45 +0000
parents
children f5a041000357
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gnv-artifacts/src/main/java/de/intevation/gnv/jfreechart/PolygonPlot.java	Mon Dec 21 16:47:45 2009 +0000
@@ -0,0 +1,416 @@
+package de.intevation.gnv.jfreechart;
+
+import java.awt.AlphaComposite;
+import java.awt.Composite;
+import java.awt.Graphics2D;
+import java.awt.Shape;
+
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.jfree.chart.axis.Axis;
+import org.jfree.chart.axis.AxisCollection;
+import org.jfree.chart.axis.AxisLocation;
+import org.jfree.chart.axis.AxisSpace;
+import org.jfree.chart.axis.AxisState;
+import org.jfree.chart.axis.ValueAxis;
+
+import org.jfree.chart.plot.Plot;
+import org.jfree.chart.plot.PlotRenderingInfo;
+import org.jfree.chart.plot.PlotState;
+import org.jfree.chart.plot.PlotOrientation;
+
+import org.jfree.data.Range;
+
+import org.jfree.ui.RectangleEdge;
+import org.jfree.ui.RectangleInsets;
+
+import org.jfree.util.ObjectList;
+
+/**
+ * @author Ingo Weinzierl <ingo.weinzierl@intevation.de>
+ */
+// TODO implement cloneable
+public class PolygonPlot
+extends      Plot
+{
+    public static final String PLOT_TYPE = "PolygonPlot";
+
+    public static final PlotOrientation DEFAULT_PLOT_ORIENTATION =
+        PlotOrientation.VERTICAL;
+
+    private PolygonDataset  dataset;
+    private transient PolygonRenderer renderer;
+
+    private PlotOrientation orientation;
+
+    private RectangleInsets axisOffset;
+
+    private ObjectList      domainAxisLocation;
+    private ObjectList      rangeAxisLocation;
+    private ObjectList      domainAxes;
+    private ObjectList      rangeAxes;
+
+
+    public PolygonPlot(PolygonDataset dataset, PolygonRenderer renderer) {
+        this(dataset, renderer, null, null, PlotOrientation.HORIZONTAL);
+    }
+
+
+    public PolygonPlot(
+        PolygonDataset  dataset,
+        PolygonRenderer renderer,
+        PlotOrientation orientation
+    ) {
+        this(dataset, renderer, null, null, orientation);
+    }
+
+
+    public PolygonPlot(
+        PolygonDataset  dataset,
+        PolygonRenderer renderer,
+        ValueAxis       domainAxis,
+        ValueAxis       rangeAxis,
+        PlotOrientation orientation
+    ) {
+        super();
+
+        this.dataset            = dataset;
+        this.renderer           = renderer;
+        this.domainAxes         = new ObjectList();
+        this.rangeAxes          = new ObjectList();
+        this.domainAxisLocation = new ObjectList();
+        this.rangeAxisLocation  = new ObjectList();
+        this.axisOffset         = RectangleInsets.ZERO_INSETS;
+
+        if (orientation != null)
+            this.orientation = orientation;
+        else
+            this.orientation = DEFAULT_PLOT_ORIENTATION;
+
+        if (domainAxis != null) {
+            this.domainAxes.set(0, domainAxis);
+            domainAxis.setPlot(this);
+        }
+        domainAxisLocation.set(0, AxisLocation.BOTTOM_OR_LEFT);
+
+        if (rangeAxis != null) {
+            this.rangeAxes.set(0, rangeAxis);
+            rangeAxis.setPlot(this);
+        }
+        rangeAxisLocation.set(0, AxisLocation.BOTTOM_OR_LEFT);
+
+        configureDomainAxis();
+        configureRangeAxis();
+    }
+
+
+    public void configureDomainAxis() {
+        // we just have 1 dataset
+        Range domainAxisRange = getDataset().getDomainBounds();
+
+        for (int i = 0; i < domainAxes.size(); i++) {
+            ValueAxis axis = (ValueAxis) domainAxes.get(i);
+
+            if (axis != null) {
+                axis.configure();
+                axis.setRange(domainAxisRange);
+            }
+        }
+    }
+
+
+    public  void configureRangeAxis() {
+        // we just have 1 dataset
+        Range rangeAxisRange = getDataset().getRangeBounds();
+
+        for (int i = 0; i < rangeAxes.size(); i++) {
+            ValueAxis axis = (ValueAxis) rangeAxes.get(i);
+
+            if (axis != null) {
+                axis.configure();
+                axis.setRange(rangeAxisRange);
+            }
+        }
+    }
+
+
+    public PolygonDataset getDataset(){
+        return this.dataset;
+    }
+
+
+    public String getPlotType() {
+        return PLOT_TYPE;
+    }
+
+
+    public  void setDataset(PolygonDataset dataset) {
+        this.dataset = dataset;
+    }
+
+
+    public void draw(
+        Graphics2D        g2,
+        Rectangle2D       area,
+        Point2D           anchor,
+        PlotState         parentState,
+        PlotRenderingInfo info
+    ) {
+        System.out.println("Start drawing plot.");
+
+        Graphics2D  savedG2       = g2;
+        Rectangle2D savedDataArea = area;
+
+        if (info != null) {
+            info.setPlotArea(area);
+            info.setDataArea(area);
+        }
+
+        AxisSpace space      = calculateAxisSpace(g2, area);
+        Rectangle2D dataArea = space.shrink(area, null);
+
+        // draw background and outline
+        drawBackground(g2, area);
+        drawOutline(g2, area);
+
+        Shape savedClip = g2.getClip();
+        g2.clip(area);
+
+        Composite originalComposite = g2.getComposite();
+        g2.setComposite(AlphaComposite.getInstance(
+            AlphaComposite.SRC_OVER,
+            getForegroundAlpha()
+        ));
+            
+        // draw axis
+        drawAxes(g2, area, dataArea, info);
+
+        if (!isEmptyOrNull(dataset)) {
+            // draw data
+            drawPolygons(savedG2, dataArea, info);
+        }
+
+        g2.setClip(savedClip);
+        g2.setComposite(originalComposite);
+
+        System.out.println("Finished drawing plot.");
+    }
+
+
+    private void drawAxes(
+        Graphics2D        g2,
+        Rectangle2D       plotArea,
+        Rectangle2D       dataArea,
+        PlotRenderingInfo plotState
+    ) {
+        AxisCollection axisCollection = new AxisCollection();
+
+        for (int i = 0; i < domainAxes.size(); i++) {
+            ValueAxis axis = (ValueAxis) domainAxes.get(i);
+            if (axis != null)
+                axisCollection.add(axis, getDomainAxisEdge(i));
+        }
+
+        for (int i = 0; i < rangeAxes.size(); i++) {
+            ValueAxis axis = (ValueAxis) rangeAxes.get(i);
+            if (axis != null)
+                axisCollection.add(axis, getRangeAxisEdge(i));
+        }
+
+        Map axisStateMap = new HashMap();
+
+        // draw the top axes
+        double cursor = dataArea.getMinY() - this.axisOffset.calculateTopOutset(
+                dataArea.getHeight());
+        Iterator iterator = axisCollection.getAxesAtTop().iterator();
+        while (iterator.hasNext()) {
+            ValueAxis axis = (ValueAxis) iterator.next();
+            AxisState info = axis.draw(g2, cursor, plotArea, dataArea,
+                    RectangleEdge.TOP, plotState);
+            cursor = info.getCursor();
+            axisStateMap.put(axis, info);
+        }
+
+        // draw the bottom axes
+        cursor = dataArea.getMaxY()
+                 + this.axisOffset.calculateBottomOutset(dataArea.getHeight());
+        iterator = axisCollection.getAxesAtBottom().iterator();
+        while (iterator.hasNext()) {
+            ValueAxis axis = (ValueAxis) iterator.next();
+            AxisState info = axis.draw(g2, cursor, plotArea, dataArea,
+                    RectangleEdge.BOTTOM, plotState);
+            cursor = info.getCursor();
+            axisStateMap.put(axis, info);
+        }
+
+        // draw the left axes
+        cursor = dataArea.getMinX()
+                 - this.axisOffset.calculateLeftOutset(dataArea.getWidth());
+        iterator = axisCollection.getAxesAtLeft().iterator();
+        while (iterator.hasNext()) {
+            ValueAxis axis = (ValueAxis) iterator.next();
+            AxisState info = axis.draw(g2, cursor, plotArea, dataArea,
+                    RectangleEdge.LEFT, plotState);
+            cursor = info.getCursor();
+            axisStateMap.put(axis, info);
+        }
+
+        // draw the right axes
+        cursor = dataArea.getMaxX()
+                 + this.axisOffset.calculateRightOutset(dataArea.getWidth());
+        iterator = axisCollection.getAxesAtRight().iterator();
+        while (iterator.hasNext()) {
+            ValueAxis axis = (ValueAxis) iterator.next();
+            AxisState info = axis.draw(g2, cursor, plotArea, dataArea,
+                    RectangleEdge.RIGHT, plotState);
+            cursor = info.getCursor();
+            axisStateMap.put(axis, info);
+        }
+    }
+
+
+    private void drawPolygons(
+        Graphics2D        g2,
+        Rectangle2D       area,
+        PlotRenderingInfo info
+    ) {
+        renderer.draw(g2, area, dataset);
+    }
+
+
+    private AxisSpace calculateAxisSpace(Graphics2D  g2, Rectangle2D plotArea) {
+        AxisSpace space         = new AxisSpace();
+        space                   = calculateRangeAxisSpace(g2, plotArea, space);
+        Rectangle2D tmpPlotArea = space.shrink(plotArea, null);
+        space                   = calculateDomainAxisSpace(g2, plotArea, space);
+
+        return space;
+    }
+
+
+    private AxisSpace calculateDomainAxisSpace(
+        Graphics2D  g2,
+        Rectangle2D plotArea,
+        AxisSpace   space
+    ) {
+        if (space == null)
+            space = new AxisSpace();
+
+        for (int i = 0; i < domainAxes.size(); i++) {
+            Axis axis = (Axis) domainAxes.get(i);
+
+            if (axis != null) {
+                RectangleEdge edge = getDomainAxisEdge(i);
+                space = axis.reserveSpace(g2, this, plotArea, edge, space);
+            }
+        }
+
+        return space;
+    }
+
+
+    private AxisSpace calculateRangeAxisSpace(
+        Graphics2D  g2,
+        Rectangle2D plotArea,
+        AxisSpace   space
+    ) {
+        if (space == null)
+            space = new AxisSpace();
+
+        for (int i = 0; i < rangeAxes.size(); i++) {
+            Axis axis = (Axis) rangeAxes.get(i);
+
+            if (axis != null) {
+                RectangleEdge edge = getRangeAxisEdge(i);
+                space = axis.reserveSpace(g2, this, plotArea, edge, space);
+            }
+        }
+
+        return space;
+    }
+
+    private RectangleEdge getDomainAxisEdge() {
+        return Plot.resolveDomainAxisLocation(
+            getDomainAxisLocation(), orientation
+        );
+    }
+
+
+    private RectangleEdge getDomainAxisEdge(int idx) {
+        AxisLocation  location = getDomainAxisLocation(idx);
+        RectangleEdge result   = Plot.resolveDomainAxisLocation(
+            location, orientation
+        );
+
+        if (result == null)
+            result = RectangleEdge.opposite(getDomainAxisEdge());
+
+        return result;
+    }
+
+
+    private RectangleEdge getRangeAxisEdge() {
+        return Plot.resolveRangeAxisLocation(
+            getRangeAxisLocation(), orientation
+        );
+    }
+
+
+    private RectangleEdge getRangeAxisEdge(int idx) {
+        AxisLocation  location = getRangeAxisLocation(idx);
+        RectangleEdge result   = Plot.resolveRangeAxisLocation(
+            location,
+            orientation
+        );
+
+        if (result == null)
+            result = RectangleEdge.opposite(getRangeAxisEdge());
+
+        return result;
+    }
+
+
+    public AxisLocation getDomainAxisLocation() {
+        return (AxisLocation) domainAxisLocation.get(0);
+    }
+
+
+    public AxisLocation getDomainAxisLocation(int idx) {
+        if (idx < domainAxisLocation.size())
+            return (AxisLocation) domainAxisLocation.get(idx);
+
+        return null;
+    }
+
+
+    public AxisLocation getRangeAxisLocation() {
+        return (AxisLocation) rangeAxisLocation.get(0);
+    }
+
+
+    public AxisLocation getRangeAxisLocation(int idx) {
+        if (idx < rangeAxisLocation.size())
+            return (AxisLocation) rangeAxisLocation.get(idx);
+
+        return null;
+    }
+
+
+    private boolean isEmptyOrNull(PolygonDataset dataset) {
+        if (dataset != null) {
+            int seriesCount = dataset.getSeriesCount();
+            for (int s = 0; s < seriesCount; s++) {
+                PolygonSeries series = dataset.getSeries(s);
+                if (series.getItemCount() > 0) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+}

http://dive4elements.wald.intevation.org