Mercurial > dive4elements > gnv-client
diff gnv-artifacts/src/main/java/de/intevation/gnv/jfreechart/PolygonRenderer.java @ 450:20a480753ff9
Render labels in vertical cross section charts.
gnv-artifacts/trunk@498 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Mon, 04 Jan 2010 02:49:42 +0000 |
parents | 92b7ccbf6163 |
children | bc5901bb4525 |
line wrap: on
line diff
--- a/gnv-artifacts/src/main/java/de/intevation/gnv/jfreechart/PolygonRenderer.java Sun Jan 03 15:57:02 2010 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/jfreechart/PolygonRenderer.java Mon Jan 04 02:49:42 2010 +0000 @@ -1,54 +1,83 @@ package de.intevation.gnv.jfreechart; +import java.util.ArrayList; + import java.awt.Color; import java.awt.Graphics2D; import java.awt.Paint; import java.awt.Shape; import java.awt.BasicStroke; +import java.awt.FontMetrics; +import java.awt.Font; import java.awt.geom.GeneralPath; import java.awt.geom.Rectangle2D; import java.awt.geom.Rectangle2D.Double; +import java.awt.geom.AffineTransform; import org.jfree.data.Range; +import org.jfree.chart.axis.ValueAxis; + +import org.jfree.ui.RectangleEdge; + import org.apache.log4j.Logger; +import org.jfree.text.TextUtilities; + + /** - * @author Ingo Weinzierl <ingo.weinzierl@intevation.de> + * @author Ingo Weinzierl (ingo.weinzierl@intevation.de) + * @author Sascha L. Teichmann (sascha.teichmann@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; + public static class DefaultLabelGenerator + implements PolygonSeriesLabelGenerator + { + public DefaultLabelGenerator() { + } - protected PaintLookup lookup; + public String generateLabel(PolygonSeries series) { + Object label = series.getAttribute("label"); + return label != null + ? toString(label) + : null; + } - protected PolygonPlot plot; + protected String toString(Object label) { + return label.toString(); + } + } // class DefaultLabelGenerator + public static final PolygonSeriesLabelGenerator + DEFAULT_LABEL_GENERATOR_INSTANCE = new DefaultLabelGenerator(); + + protected PaintLookup lookup; + protected PolygonSeriesLabelGenerator labelGenerator; public PolygonRenderer(PaintLookup lookup) { - this(lookup, AREA); + this(lookup, null); } - public PolygonRenderer(PaintLookup lookup, int type) { - this.lookup = lookup; - this.type = type; + public PolygonRenderer( + PaintLookup lookup, + PolygonSeriesLabelGenerator labelGenerator + ) { + this.lookup = lookup; + this.labelGenerator = labelGenerator; } - public void draw( + public void drawPolygons( Graphics2D graphics, Rectangle2D rectangle, PolygonDataset dataset @@ -66,6 +95,8 @@ sy = -sy; // mirror } + AffineTransform xform = graphics.getTransform(); + graphics.translate(tx, ty); graphics.scale(sx, sy); @@ -88,6 +119,73 @@ graphics.draw(constructShape(series, false)); } } + + graphics.setTransform(xform); + } + + public void drawLabels( + final Graphics2D graphics, + final PolygonPlot plot, + final Rectangle2D area, + PolygonDataset dataset + ) { + if (labelGenerator == null) { + return; + } + + final ArrayList<Rectangle2D> bboxes = new ArrayList<Rectangle2D>(); + + Font font = graphics.getFont(); + font = font.deriveFont(Font.PLAIN, Math.max(8, font.getSize()-3)); + graphics.setFont(font); + FontMetrics metrics = graphics.getFontMetrics(font); + + for (int i = dataset.getSeriesCount()-1; i >= 0; --i) { + PolygonSeries series = dataset.getSeries(i); + + String label = labelGenerator.generateLabel(series); + if (label == null) { + continue; + } + + final Rectangle2D box = TextUtilities.getTextBounds( + label, graphics, metrics); + + for (int j = series.getItemCount()-1; j >= 0; --j) { + final CompactXYItems ring = series.getItem(j); + LevelOrderIndices loi = new LevelOrderIndices(ring.size()-1); + Rectangle2D r = (Rectangle2D)loi.visit( + new LevelOrderIndices.Visitor() + { + ValueAxis da = plot.getDomainAxis(); + ValueAxis ra = plot.getRangeAxis(); + RectangleEdge de = plot.getDomainAxisEdge(); + RectangleEdge re = plot.getRangeAxisEdge(); + Rectangle2D.Double r = new Rectangle2D.Double( + 0d, 0d, box.getWidth(), box.getHeight()); + + public Object visit(int index) { + r.x = da.valueToJava2D(ring.getX(index), area, de) + - 0.5*box.getWidth(); + r.y = ra.valueToJava2D(ring.getY(index), area, re) + + 0.5*box.getHeight(); + + for (Rectangle2D b: bboxes) { + if (b.intersects(r)) { + return null; + } + } + return r; + } + }); + + if (r != null) { + bboxes.add(r); + graphics.drawString( + label, (float)r.getX(), (float)r.getY()); + } + } // for all items in series + } // for all series } protected Shape constructShape(PolygonSeries series, boolean close) {