Mercurial > dive4elements > gnv-client
diff gnv-artifacts/src/main/java/de/intevation/gnv/jfreechart/PolygonPlot.java @ 657:af3f56758f59
merged gnv-artifacts/0.5
author | Thomas Arendsen Hein <thomas@intevation.de> |
---|---|
date | Fri, 28 Sep 2012 12:13:53 +0200 |
parents | bc5901bb4525 |
children | 9a828e5a2390 |
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 Fri Sep 28 12:13:53 2012 +0200 @@ -0,0 +1,440 @@ +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; + } +}