comparison gnv-artifacts/src/main/java/de/intevation/gnv/jfreechart/PolygonRenderer.java @ 540:80630520e25a

merged gnv-artifacts/0.4
author Thomas Arendsen Hein <thomas@intevation.de>
date Fri, 28 Sep 2012 12:13:49 +0200
parents bc5901bb4525
children 9a828e5a2390
comparison
equal deleted inserted replaced
415:9f4a0b990d27 540:80630520e25a
1 package de.intevation.gnv.jfreechart;
2
3 import java.util.ArrayList;
4
5 import java.awt.Color;
6 import java.awt.Graphics2D;
7 import java.awt.Paint;
8 import java.awt.Shape;
9 import java.awt.BasicStroke;
10 import java.awt.FontMetrics;
11 import java.awt.Font;
12
13 import java.awt.geom.GeneralPath;
14 import java.awt.geom.Rectangle2D;
15 import java.awt.geom.Rectangle2D.Double;
16
17 import org.jfree.data.Range;
18
19 import org.jfree.chart.axis.ValueAxis;
20
21 import org.jfree.ui.RectangleEdge;
22
23 import org.apache.log4j.Logger;
24
25 import org.jfree.text.TextUtilities;
26
27
28 /**
29 * @author Ingo Weinzierl (ingo.weinzierl@intevation.de)
30 * @author Sascha L. Teichmann (sascha.teichmann@intevation.de)
31 */
32 public class PolygonRenderer
33 {
34 private static Logger log = Logger.getLogger(
35 PolygonRenderer.class);
36
37 public interface PaintLookup {
38
39 Paint getPaint(int index);
40
41 } // interface PaintLookup
42
43 public static class DefaultLabelGenerator
44 implements PolygonSeriesLabelGenerator
45 {
46 public DefaultLabelGenerator() {
47 }
48
49 public String generateLabel(PolygonSeries series) {
50 Object label = series.getAttribute("label");
51 return label != null
52 ? toString(label)
53 : null;
54 }
55
56 protected String toString(Object label) {
57 return label.toString();
58 }
59 } // class DefaultLabelGenerator
60
61 public static final PolygonSeriesLabelGenerator
62 DEFAULT_LABEL_GENERATOR_INSTANCE = new DefaultLabelGenerator();
63
64 protected PaintLookup lookup;
65 protected PolygonSeriesLabelGenerator labelGenerator;
66
67 public PolygonRenderer(PaintLookup lookup) {
68 this(lookup, null);
69 }
70
71 public PolygonRenderer(
72 PaintLookup lookup,
73 PolygonSeriesLabelGenerator labelGenerator
74 ) {
75 this.lookup = lookup;
76 this.labelGenerator = labelGenerator;
77 }
78
79 public void drawPolygons(
80 Graphics2D graphics,
81 PolygonPlot plot,
82 Rectangle2D area,
83 PolygonDataset dataset
84 ) {
85 int seriesCount = dataset.getSeriesCount();
86 for (int i = 0; i < seriesCount; i++) {
87 PolygonSeries series = dataset.getSeries(i);
88 Integer colorIdx = (Integer)series.getAttribute("fill");
89
90 if (colorIdx != null) {
91 Paint paint = lookup.getPaint(colorIdx.intValue());
92 graphics.setPaint(paint != null ? paint : Color.black);
93 graphics.fill(constructShape(plot, area, series, true));
94 }
95 else {
96 Number lineWidth = (Number)series.getAttribute("line.width");
97 BasicStroke stroke = new BasicStroke(
98 lineWidth != null ? lineWidth.floatValue() : 1f);
99 graphics.setStroke(stroke);
100 graphics.setPaint(Color.black);
101 graphics.draw(constructShape(plot, area, series, false));
102 }
103 }
104 }
105
106 public void drawLabels(
107 final Graphics2D graphics,
108 final PolygonPlot plot,
109 final Rectangle2D area,
110 PolygonDataset dataset
111 ) {
112 if (labelGenerator == null) {
113 return;
114 }
115
116 final ArrayList<Rectangle2D> bboxes = new ArrayList<Rectangle2D>();
117
118 Font font = graphics.getFont();
119 font = font.deriveFont(Font.PLAIN, Math.max(8, font.getSize()-3));
120 graphics.setFont(font);
121 FontMetrics metrics = graphics.getFontMetrics(font);
122
123 for (int i = dataset.getSeriesCount()-1; i >= 0; --i) {
124 PolygonSeries series = dataset.getSeries(i);
125
126 String label = labelGenerator.generateLabel(series);
127 if (label == null) {
128 continue;
129 }
130
131 final Rectangle2D box = TextUtilities.getTextBounds(
132 label, graphics, metrics);
133
134 for (int j = series.getItemCount()-1; j >= 0; --j) {
135 final CompactXYItems ring = series.getItem(j);
136 LevelOrderIndices loi = new LevelOrderIndices(ring.size()-1);
137 Rectangle2D r = (Rectangle2D)loi.visit(
138 new LevelOrderIndices.Visitor()
139 {
140 ValueAxis da = plot.getDomainAxis();
141 ValueAxis ra = plot.getRangeAxis();
142 RectangleEdge de = plot.getDomainAxisEdge();
143 RectangleEdge re = plot.getRangeAxisEdge();
144 Rectangle2D.Double r = new Rectangle2D.Double(
145 0d, 0d, box.getWidth(), box.getHeight());
146
147 public Object visit(int index) {
148 r.x = da.valueToJava2D(ring.getX(index), area, de)
149 - 0.5*box.getWidth();
150 r.y = ra.valueToJava2D(ring.getY(index), area, re)
151 + 0.5*box.getHeight();
152
153 for (Rectangle2D b: bboxes) {
154 if (b.intersects(r)) {
155 return null;
156 }
157 }
158 return r;
159 }
160 });
161
162 if (r != null) {
163 bboxes.add(r);
164 graphics.drawString(
165 label, (float)r.getX(), (float)r.getY());
166 }
167 } // for all items in series
168 } // for all series
169 }
170
171 protected Shape constructShape(
172 PolygonPlot plot,
173 Rectangle2D area,
174 PolygonSeries series,
175 boolean close
176 ) {
177 ValueAxis da = plot.getDomainAxis();
178 ValueAxis ra = plot.getRangeAxis();
179 RectangleEdge de = plot.getDomainAxisEdge();
180 RectangleEdge re = plot.getRangeAxisEdge();
181
182 CompactXYItems [] rings = series.getRings();
183 GeneralPath path = new GeneralPath();
184
185 for (int i = 0; i < rings.length; ++i) {
186
187 CompactXYItems ring = rings[i];
188
189 double [] data = ring.getData();
190
191 if (data.length >= 2) {
192 path.moveTo(
193 (float)da.valueToJava2D(data[0], area, de),
194 (float)ra.valueToJava2D(data[1], area, re));
195 }
196 for (int j = 2; j < data.length;) {
197 path.lineTo(
198 (float)da.valueToJava2D(data[j++], area, de),
199 (float)ra.valueToJava2D(data[j++], area, re));
200 }
201 if (close) {
202 path.closePath();
203 }
204 }
205 return path;
206 }
207
208 public Rectangle2D getBoundingBox(PolygonDataset dataset) {
209 Rectangle2D bbox = null;
210
211 for (int i = 0, N = dataset.getSeriesCount(); i < N; i++) {
212 Range domain = dataset.getSeries(i).getDomainBounds();
213 Range range = dataset.getSeries(i).getRangeBounds();
214
215 double x = domain.getLowerBound();
216 double y = range.getLowerBound();
217 double w = Math.abs(domain.getUpperBound() - x);
218 double h = Math.abs(range.getUpperBound() - y);
219
220 if (bbox == null) {
221 bbox = new Rectangle2D.Double(x, y, w, h);
222 }
223 else {
224 bbox.add(new Rectangle2D.Double(x, y, w, h));
225 }
226 }
227
228 return bbox;
229 }
230
231 public Rectangle2D getBounds(PolygonSeries series) {
232
233 Range domain = series.getDomainBounds();
234 Range range = series.getRangeBounds();
235
236 return new Rectangle2D.Double(
237 domain.getLowerBound(), range.getLowerBound(),
238 domain.getUpperBound(), range.getUpperBound()
239 );
240 }
241 }
242 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :

http://dive4elements.wald.intevation.org