view gnv-artifacts/src/main/java/de/intevation/gnv/jfreechart/PolygonPlot.java @ 605:e8ebdbc7f1e3

First step of removing the cache blob. The static part of the describe document will be created by using the input data stored at each state. Some TODOs left (see ChangeLog). gnv-artifacts/trunk@671 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Ingo Weinzierl <ingo.weinzierl@intevation.de>
date Tue, 09 Feb 2010 14:27:55 +0000
parents bc5901bb4525
children 9a828e5a2390
line wrap: on
line source
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 ValueAxis getDomainAxis() {
        return getDomainAxis(0);
    }

    public ValueAxis getDomainAxis(int index) {
        return index < domainAxes.size()
            ? (ValueAxis)domainAxes.get(index)
            : null;
    }

    public ValueAxis getRangeAxis() {
        return getRangeAxis(0);
    }

    public ValueAxis getRangeAxis(int index) {
        return index < rangeAxes.size()
            ? (ValueAxis)rangeAxes.get(index)
            : null;
    }

    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
    ) {
        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);
            drawLabels(savedG2, dataArea, info);
        }

        g2.setClip(savedClip);
        g2.setComposite(originalComposite);
    }


    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 drawLabels(
        Graphics2D        g2,
        Rectangle2D       area,
        PlotRenderingInfo info
    ) {
        renderer.drawLabels(g2, this, area, dataset);
    }

    private void drawPolygons(
        Graphics2D        g2,
        Rectangle2D       area,
        PlotRenderingInfo info
    ) {
        renderer.drawPolygons(g2, this, 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;
    }

    public RectangleEdge getDomainAxisEdge() {
        return Plot.resolveDomainAxisLocation(
            getDomainAxisLocation(), orientation
        );
    }


    public RectangleEdge getDomainAxisEdge(int idx) {
        AxisLocation  location = getDomainAxisLocation(idx);
        RectangleEdge result   = Plot.resolveDomainAxisLocation(
            location, orientation
        );

        if (result == null)
            result = RectangleEdge.opposite(getDomainAxisEdge());

        return result;
    }


    public RectangleEdge getRangeAxisEdge() {
        return Plot.resolveRangeAxisLocation(
            getRangeAxisLocation(), orientation
        );
    }


    public 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