view flys-artifacts/src/main/java/de/intevation/flys/jfree/EnhancedLineAndShapeRenderer.java @ 2089:0da8874bd378

Added initial state to map artifact to be able to advance and step back. The map artifact overrides describe() to have the complete UI information in the describe response document. flys-artifacts/trunk@3613 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Raimund Renkert <raimund.renkert@intevation.de>
date Fri, 06 Jan 2012 12:02:10 +0000
parents f42b0e624e97
children 2b232871ba28
line wrap: on
line source
package de.intevation.flys.jfree;

import java.awt.Graphics2D;
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;
    }


    /**
     * 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 = 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);
                }
            }
        }

        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) {
        return isMinimumShapeVisible.getBoolean(series);
    }


    public void setIsMaximumShapeVisible(int series, boolean isVisible) {
        this.isMaximumShapeVisible.setBoolean(series, isVisible);
    }


    public boolean isMaximumShapeVisible(int series) {
        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 :

http://dive4elements.wald.intevation.org