Mercurial > dive4elements > river
diff flys-artifacts/src/main/java/de/intevation/flys/jfree/EnhancedLineAndShapeRenderer.java @ 3818:dc18457b1cef
merged flys-artifacts/pre2.7-2012-03-16
author | Thomas Arendsen Hein <thomas@intevation.de> |
---|---|
date | Fri, 28 Sep 2012 12:14:59 +0200 |
parents | 74c02dbf17ca |
children | 42b05a4bed25 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/jfree/EnhancedLineAndShapeRenderer.java Fri Sep 28 12:14:59 2012 +0200 @@ -0,0 +1,328 @@ +package de.intevation.flys.jfree; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.Paint; +import java.awt.Shape; +import java.awt.geom.Rectangle2D; +import java.util.HashMap; +import java.util.Map; + +import org.apache.log4j.Logger; + +import org.jfree.chart.axis.ValueAxis; +import org.jfree.chart.entity.EntityCollection; +import org.jfree.chart.plot.CrosshairState; +import org.jfree.chart.plot.PlotOrientation; +import org.jfree.chart.plot.XYPlot; +import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer; +import org.jfree.data.xy.XYDataset; +import org.jfree.ui.RectangleEdge; +import org.jfree.util.BooleanList; +import org.jfree.util.ShapeUtilities; + + +public class EnhancedLineAndShapeRenderer extends XYLineAndShapeRenderer { + + private static final Logger logger = + Logger.getLogger(EnhancedLineAndShapeRenderer.class); + + protected BooleanList isMinimumShapeVisible; + protected BooleanList isMaximumShapeVisible; + + protected Map<Integer, Double> seriesMinimum; + protected Map<Integer, Double> seriesMaximum; + + + public EnhancedLineAndShapeRenderer(boolean lines, boolean shapes) { + super(lines, shapes); + this.isMinimumShapeVisible = new BooleanList(); + this.isMaximumShapeVisible = new BooleanList(); + this.seriesMinimum = new HashMap<Integer, Double>(); + this.seriesMaximum = new HashMap<Integer, Double>(); + } + + + public boolean getItemShapeVisible(XYDataset dataset, int series, int item){ + if (super.getItemShapeVisible(series, item)) { + return true; + } + + if (isMinimumShapeVisible(series) && isMinimum(dataset, series, item)) { + return true; + } + + if (isMaximumShapeVisible(series) && isMaximum(dataset, series, item)) { + return true; + } + + return false; + } + + + public Shape getMaximumShape(int series, int column) { + return new Rectangle2D.Double(-5d, -5d, 10d, 10d); + } + + + public Shape getMinimumShape(int series, int column) { + return new Rectangle2D.Double(-5d, -5d, 10d, 10d); + } + + + public Paint getMaximumFillPaint(int series, int column) { + Paint p = getItemPaint(series, column); + + if (p instanceof Color) { + Color c = (Color) p; + Color b = c; + + for (int i = 0; i < 2; i++) { + b = b.darker(); + } + + return b; + } + + logger.warn("Item paint is no instance of Color!"); + return p; + } + + + public Paint getMinimumFillPaint(int series, int column) { + Paint p = getItemPaint(series, column); + + if (p instanceof Color) { + Color c = (Color) p; + Color b = c; + + for (int i = 0; i < 2; i++) { + b = b.darker(); + } + + return b; + } + + logger.warn("Item paint is no instance of Color!"); + return p; + } + + + /** + * Overrides XYLineAndShapeRenderer.drawSecondaryPass() to call an adapted + * method getItemShapeVisible() which now takes an XYDataset. So, 99% of + * code equal the code in XYLineAndShapeRenderer. + */ + @Override + protected void drawSecondaryPass( + Graphics2D g2, + XYPlot plot, + XYDataset dataset, + int pass, + int series, + int item, + ValueAxis domainAxis, + Rectangle2D dataArea, + ValueAxis rangeAxis, + CrosshairState crosshairState, + EntityCollection entities + ) { + Shape entityArea = null; + + // get the data point... + double x1 = dataset.getXValue(series, item); + double y1 = dataset.getYValue(series, item); + if (Double.isNaN(y1) || Double.isNaN(x1)) { + return; + } + + PlotOrientation orientation = plot.getOrientation(); + RectangleEdge xAxisLocation = plot.getDomainAxisEdge(); + RectangleEdge yAxisLocation = plot.getRangeAxisEdge(); + double transX1 = domainAxis.valueToJava2D(x1, dataArea, xAxisLocation); + double transY1 = rangeAxis.valueToJava2D(y1, dataArea, yAxisLocation); + + if (getItemShapeVisible(dataset, series, item)) { + Shape shape = null; + + boolean isMinimum = isMinimumShapeVisible(series) + && isMinimum(dataset, series, item); + + boolean isMaximum = isMaximumShapeVisible(series) + && isMaximum(dataset, series, item); + + if (isMinimum) { + logger.debug("Create a Minimum shape."); + shape = getMinimumShape(series, item); + } + else if (isMaximum) { + logger.debug("Create a Maximum shape."); + shape = getMaximumShape(series, item); + } + else { + shape = getItemShape(series, item); + } + + if (orientation == PlotOrientation.HORIZONTAL) { + shape = ShapeUtilities.createTranslatedShape(shape, transY1, + transX1); + } + else if (orientation == PlotOrientation.VERTICAL) { + shape = ShapeUtilities.createTranslatedShape(shape, transX1, + transY1); + } + entityArea = shape; + if (shape.intersects(dataArea)) { + if (getItemShapeFilled(series, item)) { + if (getUseFillPaint()) { + g2.setPaint(getItemFillPaint(series, item)); + } + else { + g2.setPaint(getItemPaint(series, item)); + } + g2.fill(shape); + } + if (getDrawOutlines()) { + if (getUseOutlinePaint()) { + g2.setPaint(getItemOutlinePaint(series, item)); + } + else { + g2.setPaint(getItemPaint(series, item)); + } + g2.setStroke(getItemOutlineStroke(series, item)); + g2.draw(shape); + } + + if (isMinimum) { + g2.setPaint(getMinimumFillPaint(series, item)); + g2.fill(shape); + g2.setPaint(getItemOutlinePaint(series, item)); + g2.setStroke(getItemOutlineStroke(series, item)); + g2.draw(shape); + } + else if (isMaximum) { + g2.setPaint(getMaximumFillPaint(series, item)); + g2.fill(shape); + g2.setPaint(getItemOutlinePaint(series, item)); + g2.setStroke(getItemOutlineStroke(series, item)); + g2.draw(shape); + } + } + } + + double xx = transX1; + double yy = transY1; + if (orientation == PlotOrientation.HORIZONTAL) { + xx = transY1; + yy = transX1; + } + + // draw the item label if there is one... + if (isItemLabelVisible(series, item)) { + drawItemLabel(g2, orientation, dataset, series, item, xx, yy, + (y1 < 0.0)); + } + + int domainAxisIndex = plot.getDomainAxisIndex(domainAxis); + int rangeAxisIndex = plot.getRangeAxisIndex(rangeAxis); + updateCrosshairValues(crosshairState, x1, y1, domainAxisIndex, + rangeAxisIndex, transX1, transY1, orientation); + + // add an entity for the item, but only if it falls within the data + // area... + if (entities != null && isPointInRect(dataArea, xx, yy)) { + addEntity(entities, entityArea, dataset, series, item, xx, yy); + } + } + + + public void setIsMinimumShapeVisisble(int series, boolean isVisible) { + this.isMinimumShapeVisible.setBoolean(series, isVisible); + } + + + public boolean isMinimumShapeVisible(int series) { + if (this.isMinimumShapeVisible.size() <= series) { + return false; + } + + return isMinimumShapeVisible.getBoolean(series); + } + + + public void setIsMaximumShapeVisible(int series, boolean isVisible) { + this.isMaximumShapeVisible.setBoolean(series, isVisible); + } + + + public boolean isMaximumShapeVisible(int series) { + if (this.isMaximumShapeVisible.size() <= series) { + return false; + } + + return isMaximumShapeVisible.getBoolean(series); + } + + + public boolean isMinimum(XYDataset dataset, int series, int item) { + return dataset.getYValue(series, item) == getMinimum(dataset, series); + } + + + public double getMinimum(XYDataset dataset, int series) { + Integer key = Integer.valueOf(series); + Double old = seriesMinimum.get(key); + + if (old != null) { + return old.doubleValue(); + } + + logger.debug("Compute minimum of Series: " + series); + + double min = Double.MAX_VALUE; + + for (int i = 0, n = dataset.getItemCount(series); i < n; i++) { + double tmpValue = dataset.getYValue(series, i); + + if (tmpValue < min) { + min = tmpValue; + } + } + + seriesMinimum.put(key, Double.valueOf(min)); + + return min; + } + + + public boolean isMaximum(XYDataset dataset, int series, int item) { + return dataset.getYValue(series, item) == getMaximum(dataset, series); + } + + + public double getMaximum(XYDataset dataset, int series) { + Integer key = Integer.valueOf(series); + Double old = seriesMaximum.get(key); + + if (old != null) { + return old.doubleValue(); + } + + logger.debug("Compute maximum of Series: " + series); + + double max = -Double.MAX_VALUE; + + for (int i = 0, n = dataset.getItemCount(series); i < n; i++) { + double tmpValue = dataset.getYValue(series, i); + + if (tmpValue > max) { + max = tmpValue; + } + } + + seriesMaximum.put(key, Double.valueOf(max)); + + return max; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :