Mercurial > dive4elements > gnv-client
view gnv-artifacts/src/main/java/de/intevation/gnv/jfreechart/PolygonPlot.java @ 799:feeaf5aec552
ISSUE213: Wrong Geometrytype used for the generation of an Layer with Multipolygon-Geometries
gnv-artifacts/trunk@881 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author | Tim Englich <tim.englich@intevation.de> |
---|---|
date | Tue, 06 Apr 2010 11:56:53 +0000 |
parents | cdade5005cba |
children | feae2f9d6c6f |
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.PlotOrientation; import org.jfree.chart.plot.PlotRenderingInfo; import org.jfree.chart.plot.PlotState; import org.jfree.data.Range; import org.jfree.ui.RectangleEdge; import org.jfree.ui.RectangleInsets; import org.jfree.util.ObjectList; /** * A class for plotting polygons into a 2D chart. This plot makes use of <code> * PolygonRenderer</code>. * * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a> */ // 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; /** * Constructs a new PolygonPlot with a dataset and a renderer. * * @param dataset Dataset containing polygons. * @param renderer The renderer used to draw polygons. */ public PolygonPlot(PolygonDataset dataset, PolygonRenderer renderer) { this(dataset, renderer, null, null, PlotOrientation.HORIZONTAL); } /** * * @param dataset Dataset containing polygons. * @param renderer The renderer used to draw polygons. * @param orientation The orientation used for this plot. */ public PolygonPlot( PolygonDataset dataset, PolygonRenderer renderer, PlotOrientation orientation ) { this(dataset, renderer, null, null, orientation); } /** * * @param dataset Dataset containing polygons. * @param renderer The renderer used to draw polygons. * @param domainAxis The x axis. * @param rangeAxis The y axis. * @param orientation The orientation used for this plot. */ 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); } } } /** * * @return */ public ValueAxis getDomainAxis() { return getDomainAxis(0); } /** * * @param index * @return */ public ValueAxis getDomainAxis(int index) { return index < domainAxes.size() ? (ValueAxis)domainAxes.get(index) : null; } /** * * @return */ public ValueAxis getRangeAxis() { return getRangeAxis(0); } /** * * @param index * @return */ 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); } } } /** * * @return */ public PolygonDataset getDataset(){ return this.dataset; } /** * * @return */ public String getPlotType() { return PLOT_TYPE; } /** * * @param dataset */ public void setDataset(PolygonDataset dataset) { this.dataset = dataset; } /** * This is the major method to draw the into a given Graphic2D object. * * @param g2 Graphics object where the plot is drawn into. * @param area The bounds for drawing this plot. * @param anchor An anchor point. * @param parentState The plot state. * @param info */ 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); } /** * Method to draw the axis for this plot. * * @param g2 * @param plotArea * @param dataArea * @param plotState */ 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); } } /** * Put some labels at data items into the plot. Uses PolygonRenderer to do * this job. * * @param g2 * @param area * @param info */ private void drawLabels( Graphics2D g2, Rectangle2D area, PlotRenderingInfo info ) { renderer.drawLabels(g2, this, area, dataset); } /** * Plot the polygons. Uses PolygonRenderer to do this job. * * @param g2 * @param area * @param info */ private void drawPolygons( Graphics2D g2, Rectangle2D area, PlotRenderingInfo info ) { renderer.drawPolygons(g2, this, area, dataset); } /** * * @param g2 * @param plotArea * @return */ 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; } /** * * @param g2 * @param plotArea * @param space * @return */ 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; } /** * * @param g2 * @param plotArea * @param space * @return */ 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; } /** * * @return */ public RectangleEdge getDomainAxisEdge() { return Plot.resolveDomainAxisLocation( getDomainAxisLocation(), orientation ); } /** * * @param idx * @return */ public RectangleEdge getDomainAxisEdge(int idx) { AxisLocation location = getDomainAxisLocation(idx); RectangleEdge result = Plot.resolveDomainAxisLocation( location, orientation ); if (result == null) result = RectangleEdge.opposite(getDomainAxisEdge()); return result; } /** * * @return */ public RectangleEdge getRangeAxisEdge() { return Plot.resolveRangeAxisLocation( getRangeAxisLocation(), orientation ); } /** * * @param idx * @return */ public RectangleEdge getRangeAxisEdge(int idx) { AxisLocation location = getRangeAxisLocation(idx); RectangleEdge result = Plot.resolveRangeAxisLocation( location, orientation ); if (result == null) result = RectangleEdge.opposite(getRangeAxisEdge()); return result; } /** * * @return */ public AxisLocation getDomainAxisLocation() { return (AxisLocation) domainAxisLocation.get(0); } /** * * @param idx * @return */ public AxisLocation getDomainAxisLocation(int idx) { if (idx < domainAxisLocation.size()) return (AxisLocation) domainAxisLocation.get(idx); return null; } /** * * @return */ public AxisLocation getRangeAxisLocation() { return (AxisLocation) rangeAxisLocation.get(0); } /** * * @param idx * @return */ public AxisLocation getRangeAxisLocation(int idx) { if (idx < rangeAxisLocation.size()) return (AxisLocation) rangeAxisLocation.get(idx); return null; } /** * * @param dataset * @return true, if dataset is null or if it does not contain any * PolygonSeries, otherwise false. */ 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; } } // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :