sascha@422: package de.intevation.gnv.jfreechart; sascha@422: sascha@422: import java.awt.Color; sascha@422: import java.awt.Graphics2D; sascha@422: import java.awt.Paint; sascha@422: import java.awt.Shape; sascha@447: import java.awt.BasicStroke; sascha@447: sascha@422: import java.awt.geom.GeneralPath; sascha@422: import java.awt.geom.Rectangle2D; sascha@422: import java.awt.geom.Rectangle2D.Double; sascha@422: sascha@422: import org.jfree.data.Range; sascha@422: sascha@447: import org.apache.log4j.Logger; sascha@447: sascha@422: /** sascha@422: * @author Ingo Weinzierl sascha@422: */ sascha@422: public class PolygonRenderer sascha@422: { sascha@447: private static Logger log = Logger.getLogger( sascha@447: PolygonRenderer.class); sascha@447: sascha@422: public static final int AREA = 1; sascha@422: public static final int LINES = 2; sascha@422: public static final int AREA_AND_LINES = AREA | LINES; sascha@422: sascha@422: public interface PaintLookup { sascha@422: sascha@422: Paint getPaint(int index); sascha@422: sascha@422: } // interface PaintLookup sascha@422: sascha@422: protected int type; sascha@422: sascha@422: protected PaintLookup lookup; sascha@422: sascha@422: protected PolygonPlot plot; sascha@422: sascha@422: sascha@422: public PolygonRenderer(PaintLookup lookup) { sascha@422: this(lookup, AREA); sascha@422: } sascha@422: sascha@422: public PolygonRenderer(PaintLookup lookup, int type) { sascha@422: this.lookup = lookup; sascha@422: this.type = type; sascha@422: } sascha@422: sascha@422: public void draw( sascha@422: Graphics2D graphics, sascha@422: Rectangle2D rectangle, sascha@422: PolygonDataset dataset sascha@422: ) { sascha@422: Rectangle2D bbox = getBoundingBox(dataset); sascha@422: sascha@422: double sx = (double)rectangle.getWidth()/bbox.getWidth(); sascha@422: double sy = (double)rectangle.getHeight()/bbox.getHeight(); sascha@422: double tx = rectangle.getMinX(); sascha@422: double ty = rectangle.getMinY(); sascha@422: sascha@446: // XXX: Little hack to draw correctly if data is sascha@446: // below 0 in y direction. sascha@446: if (bbox.getMinY() <= 0d && bbox.getMaxY() <= 0d) { sascha@446: sy = -sy; // mirror sascha@446: } sascha@446: sascha@422: graphics.translate(tx, ty); sascha@422: graphics.scale(sx, sy); sascha@422: sascha@422: int seriesCount = dataset.getSeriesCount(); sascha@422: for (int i = 0; i < seriesCount; i++) { sascha@422: PolygonSeries series = dataset.getSeries(i); sascha@422: Integer colorIdx = (Integer)series.getAttribute("fill"); sascha@422: sascha@422: if (colorIdx != null) { sascha@422: Paint paint = lookup.getPaint(colorIdx.intValue()); sascha@422: graphics.setPaint(paint != null ? paint : Color.black); sascha@437: graphics.fill(constructShape(series, true)); sascha@422: } sascha@422: else { sascha@447: Number lineWidth = (Number)series.getAttribute("line.width"); sascha@447: BasicStroke stroke = new BasicStroke( sascha@447: lineWidth != null ? lineWidth.floatValue() : 1f); sascha@447: graphics.setStroke(stroke); sascha@422: graphics.setPaint(Color.black); sascha@437: graphics.draw(constructShape(series, false)); sascha@422: } sascha@422: } sascha@422: } sascha@422: sascha@437: protected Shape constructShape(PolygonSeries series, boolean close) { sascha@422: CompactXYItems [] rings = series.getRings(); sascha@422: GeneralPath path = new GeneralPath(); sascha@422: for (int i = 0; i < rings.length; ++i) { sascha@422: CompactXYItems ring = rings[i]; sascha@422: double [] data = ring.getData(); sascha@422: if (data.length >= 2) { sascha@422: path.moveTo((float)data[0], (float)data[1]); sascha@422: } sascha@422: for (int j = 2; j < data.length;) { sascha@422: float x = (float)data[j++]; sascha@422: float y = (float)data[j++]; sascha@422: path.lineTo(x, y); sascha@422: } sascha@437: if (close) { sascha@437: path.closePath(); sascha@437: } sascha@422: } sascha@422: return path; sascha@422: } sascha@422: sascha@422: public Rectangle2D getBoundingBox(PolygonDataset dataset) { sascha@422: Rectangle2D bbox = null; sascha@422: sascha@422: for (int i = 0, N = dataset.getSeriesCount(); i < N; i++) { sascha@422: Range domain = dataset.getSeries(i).getDomainBounds(); sascha@422: Range range = dataset.getSeries(i).getRangeBounds(); sascha@422: sascha@422: double x = domain.getLowerBound(); sascha@422: double y = range.getLowerBound(); sascha@422: double w = Math.abs(domain.getUpperBound() - x); sascha@422: double h = Math.abs(range.getUpperBound() - y); sascha@422: sascha@422: if (bbox == null) { sascha@422: bbox = new Rectangle2D.Double(x, y, w, h); sascha@422: } sascha@422: else { sascha@422: bbox.add(new Rectangle2D.Double(x, y, w, h)); sascha@422: } sascha@422: } sascha@422: sascha@422: return bbox; sascha@422: } sascha@422: sascha@422: public Rectangle2D getBounds(PolygonSeries series) { sascha@422: sascha@422: Range domain = series.getDomainBounds(); sascha@422: Range range = series.getRangeBounds(); sascha@422: sascha@422: return new Rectangle2D.Double( sascha@422: domain.getLowerBound(), range.getLowerBound(), sascha@422: domain.getUpperBound(), range.getUpperBound() sascha@422: ); sascha@422: } sascha@422: } sascha@422: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :