view gnv-artifacts/src/main/java/de/intevation/gnv/jfreechart/PolygonRenderer.java @ 447:92b7ccbf6163

Improved generation of iso lines in vertical cross section. gnv-artifacts/trunk@495 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Fri, 01 Jan 2010 21:52:41 +0000
parents f5a041000357
children 20a480753ff9
line wrap: on
line source
package de.intevation.gnv.jfreechart;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.Shape;
import java.awt.BasicStroke;

import java.awt.geom.GeneralPath;
import java.awt.geom.Rectangle2D;
import java.awt.geom.Rectangle2D.Double;

import org.jfree.data.Range;

import org.apache.log4j.Logger;

/**
 * @author Ingo Weinzierl <ingo.weinzierl@intevation.de>
 */
public class PolygonRenderer
{
	private static Logger log = Logger.getLogger(
		PolygonRenderer.class);

    public static final int AREA           = 1;
    public static final int LINES          = 2;
    public static final int AREA_AND_LINES = AREA | LINES;

    public interface PaintLookup {

        Paint getPaint(int index);

    } // interface PaintLookup

    protected int type;

    protected PaintLookup lookup;

    protected PolygonPlot plot;


    public PolygonRenderer(PaintLookup lookup) {
        this(lookup, AREA);
    }

    public PolygonRenderer(PaintLookup lookup, int type) {
        this.lookup = lookup;
        this.type   = type;
    }

    public void draw(
        Graphics2D     graphics,
        Rectangle2D    rectangle,
        PolygonDataset dataset
    ) {
        Rectangle2D bbox = getBoundingBox(dataset);

        double sx = (double)rectangle.getWidth()/bbox.getWidth();
        double sy = (double)rectangle.getHeight()/bbox.getHeight();
        double tx = rectangle.getMinX();
        double ty = rectangle.getMinY();

        // XXX: Little hack to draw correctly if data is
        // below 0 in y direction.
        if (bbox.getMinY() <= 0d && bbox.getMaxY() <= 0d) {
            sy = -sy; // mirror
        }

        graphics.translate(tx, ty);
        graphics.scale(sx, sy);

        int seriesCount = dataset.getSeriesCount();
        for (int i = 0; i < seriesCount; i++) {
            PolygonSeries series   = dataset.getSeries(i);
            Integer       colorIdx = (Integer)series.getAttribute("fill");

            if (colorIdx != null) {
                Paint paint = lookup.getPaint(colorIdx.intValue());
                graphics.setPaint(paint != null ? paint : Color.black);
                graphics.fill(constructShape(series, true));
            }
            else {
                Number lineWidth = (Number)series.getAttribute("line.width");
                BasicStroke stroke = new BasicStroke(
                    lineWidth != null ? lineWidth.floatValue() : 1f);
                graphics.setStroke(stroke);
                graphics.setPaint(Color.black);
                graphics.draw(constructShape(series, false));
            }
        }
    }

    protected Shape constructShape(PolygonSeries series, boolean close) {
        CompactXYItems [] rings = series.getRings();
        GeneralPath path = new GeneralPath();
        for (int i = 0; i < rings.length; ++i) {
            CompactXYItems ring = rings[i];
            double [] data = ring.getData();
            if (data.length >= 2) {
                path.moveTo((float)data[0], (float)data[1]);
            }
            for (int j = 2; j < data.length;) {
                float x = (float)data[j++];
                float y = (float)data[j++];
                path.lineTo(x, y);
            }
            if (close) {
                path.closePath();
            }
        }
        return path;
    }

    public Rectangle2D getBoundingBox(PolygonDataset dataset) {
        Rectangle2D bbox = null;

        for (int i = 0, N = dataset.getSeriesCount(); i < N; i++) {
            Range domain = dataset.getSeries(i).getDomainBounds();
            Range range  = dataset.getSeries(i).getRangeBounds();

            double x = domain.getLowerBound();
            double y = range.getLowerBound();
            double w = Math.abs(domain.getUpperBound() - x);
            double h = Math.abs(range.getUpperBound() - y);

            if (bbox == null) {
                bbox = new Rectangle2D.Double(x, y, w, h);
            }
            else {
                bbox.add(new Rectangle2D.Double(x, y, w, h));
            }
        }

        return bbox;
    }

    public Rectangle2D getBounds(PolygonSeries series) {

        Range domain = series.getDomainBounds();
        Range range  = series.getRangeBounds();

        return new Rectangle2D.Double(
            domain.getLowerBound(), range.getLowerBound(),
            domain.getUpperBound(), range.getUpperBound()
        );
    }
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :

http://dive4elements.wald.intevation.org