Mercurial > dive4elements > gnv-client
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 : |