comparison flys-artifacts/src/main/java/de/intevation/flys/jfree/ShapeRenderer.java @ 3468:f37e7e8907cb

merged flys-artifacts/2.8.1
author Thomas Arendsen Hein <thomas@intevation.de>
date Fri, 28 Sep 2012 12:14:39 +0200
parents 0cf647fe2a96
children
comparison
equal deleted inserted replaced
3387:5ffad8bde8ad 3468:f37e7e8907cb
1 package de.intevation.flys.jfree;
2
3 /**
4 * Copyright (c) 2006, 2012 by Intevation GmbH
5 *
6 * @author Sascha L. Teichmann (teichmann@intevation.de)
7 *
8 * This program is free software under the LGPL (&gt;=v2.1)
9 * Read the file LGPL coming with FLYS for details.
10 */
11
12 import java.awt.Font;
13 import java.awt.Graphics2D;
14 import java.awt.Paint;
15 import java.awt.Shape;
16
17 import java.awt.geom.Point2D;
18 import java.awt.geom.Rectangle2D;
19
20 import java.util.ArrayList;
21 import java.util.List;
22 import java.util.Map;
23
24 import org.jfree.chart.axis.ValueAxis;
25
26 import org.jfree.chart.labels.ItemLabelPosition;
27 import org.jfree.chart.labels.XYItemLabelGenerator;
28
29 import org.jfree.chart.plot.CrosshairState;
30 import org.jfree.chart.plot.PlotOrientation;
31 import org.jfree.chart.plot.PlotRenderingInfo;
32 import org.jfree.chart.plot.XYPlot;
33
34 import org.jfree.chart.renderer.xy.StandardXYItemRenderer;
35 import org.jfree.chart.renderer.xy.XYItemRendererState;
36
37 import org.jfree.data.xy.XYDataset;
38
39 import org.jfree.text.TextUtilities;
40
41 import org.jfree.ui.RectangleEdge;
42
43 public class ShapeRenderer
44 extends StandardXYItemRenderer {
45
46 public static class Entry {
47 protected Shape shape;
48 protected Shape frame;
49 protected Paint paint;
50 protected boolean filled;
51
52 public Entry(
53 Shape shape,
54 Paint paint,
55 boolean filled
56 ) {
57 this.shape = shape;
58 this.paint = paint;
59 this.filled = filled;
60 }
61
62 public Entry(
63 Shape shape,
64 Shape frame,
65 Paint paint,
66 boolean filled
67 ) {
68 this.shape = shape;
69 this.frame = frame;
70 this.paint = paint;
71 this.filled = filled;
72 }
73
74 public Shape getShape() {
75 return shape;
76 }
77
78 public void setShape(Shape shape) {
79 this.shape = shape;
80 }
81
82
83 public Paint getPaint() {
84 return paint;
85 }
86
87 public void setPaint(Paint paint) {
88 this.paint = paint;
89 }
90
91 public boolean getFilled() {
92 return filled;
93 }
94
95 public void setFilled(boolean filled) {
96 this.filled = filled;
97 }
98
99 public boolean equals(Object other) {
100 Entry entry = (Entry)other;
101 return filled == entry.filled
102 && paint.equals(entry.paint)
103 && shape.equals(entry.shape);
104 }
105
106 public int hashCode() {
107 return
108 shape.hashCode() ^
109 paint.hashCode() ^
110 (filled ? 1231 : 1237);
111 }
112 } // class Entry
113
114 public interface LabelGenerator {
115 String createLabel(Entry entry);
116 } // interface EntryLabelGenerator
117
118 protected Entry [] entries;
119
120 protected List<Rectangle2D> labelBoundingBoxes;
121
122 protected Rectangle2D area;
123
124 public ShapeRenderer() {
125 this(SHAPES);
126 }
127
128 public ShapeRenderer(int type) {
129 super(type);
130 }
131
132 public ShapeRenderer(Map<Entry, Integer> map) {
133 super(SHAPES);
134 setEntries(map);
135 }
136
137 public void setEntries(Entry [] entries) {
138 this.entries = entries;
139 }
140
141 public void setEntries(Map<Entry, Integer> map) {
142 Entry [] entries = new Entry[map.size()];
143
144 for (Map.Entry<Entry, Integer> entry: map.entrySet()) {
145 entries[entry.getValue()] = entry.getKey();
146 }
147
148 setEntries(entries);
149 }
150
151 @Override
152 public Shape getSeriesShape(int series) {
153 return entries[series].shape;
154 }
155
156 public Shape getSeriesFrame(int series) {
157 return entries[series].frame;
158 }
159
160 @Override
161 public Paint getSeriesPaint(int series) {
162 return entries[series].paint;
163 }
164
165 @Override
166 public boolean getItemShapeFilled(int series, int item) {
167 return entries[series].filled;
168 }
169
170 @Override
171 public XYItemRendererState initialise(
172 Graphics2D g2,
173 Rectangle2D dataArea,
174 XYPlot plot,
175 XYDataset data,
176 PlotRenderingInfo info
177 ) {
178 if (labelBoundingBoxes == null) {
179 labelBoundingBoxes = new ArrayList<Rectangle2D>(32);
180 }
181 else {
182 labelBoundingBoxes.clear();
183 }
184
185 area = dataArea;
186
187 return super.initialise(g2, dataArea, plot, data, info);
188 }
189
190 @Override
191 public void drawItem(
192 Graphics2D g2,
193 XYItemRendererState state,
194 Rectangle2D dataArea,
195 PlotRenderingInfo info,
196 XYPlot plot,
197 ValueAxis domainAxis,
198 ValueAxis rangeAxis,
199 XYDataset dataset,
200 int series,
201 int item,
202 CrosshairState crosshairState,
203 int pass
204 ) {
205 if (!getItemVisible(series, item)) {
206 return;
207 }
208
209 // get the data point...
210 double x1 = dataset.getXValue(series, item);
211 double y1 = dataset.getYValue(series, item);
212 if (Double.isNaN(x1) || Double.isNaN(y1)) {
213 return;
214 }
215
216 RectangleEdge xAxisLocation = plot.getDomainAxisEdge();
217 RectangleEdge yAxisLocation = plot.getRangeAxisEdge();
218 double x = domainAxis.valueToJava2D(x1, dataArea, xAxisLocation);
219 double y = rangeAxis.valueToJava2D(y1, dataArea, yAxisLocation);
220
221 if (dataArea.contains(x, y))
222 super.drawItem(
223 g2,
224 state,
225 dataArea,
226 info,
227 plot,
228 domainAxis,
229 rangeAxis,
230 dataset,
231 series,
232 item,
233 crosshairState,
234 pass);
235 }
236
237 protected Point2D shiftBox(Rectangle2D box) {
238
239 double cx1 = area.getX();
240 double cy1 = area.getY();
241 double cx2 = cx1 + area.getWidth();
242 double cy2 = cy1 + area.getHeight();
243
244 double bx1 = box.getX();
245 double by1 = box.getY();
246 double bx2 = bx1 + box.getWidth();
247 double by2 = by1 + box.getHeight();
248
249 double dx;
250 double dy;
251
252 if (bx1 < cx1) {
253 dx = cx1 - bx1;
254 }
255 else if (bx2 > cx2) {
256 dx = cx2 - bx2;
257 }
258 else {
259 dx = 0d;
260 }
261
262 if (by1 < cy1) {
263 dy = cy1 - by1;
264 }
265 else if (by2 > cy2) {
266 dy = cy2 - by2;
267 }
268 else {
269 dy = 0d;
270 }
271
272 return new Point2D.Double(dx, dy);
273 }
274
275 @Override
276 protected void drawItemLabel(
277 Graphics2D g2,
278 PlotOrientation orientation,
279 XYDataset dataset,
280 int series,
281 int item,
282 double x,
283 double y,
284 boolean negative
285 ) {
286 XYItemLabelGenerator generator = getItemLabelGenerator(series, item);
287 if (generator == null) {
288 return;
289 }
290
291 Font labelFont = getItemLabelFont(series, item);
292
293 Paint paint = getItemLabelPaint(series, item);
294
295 g2.setFont(labelFont);
296 g2.setPaint(paint);
297
298 String label = generator.generateLabel(dataset, series, item);
299
300 ATTEMPS: for (int attempt = 0; attempt < 2; ++attempt) {
301 // get the label position..
302 ItemLabelPosition position = null;
303
304 boolean pos;
305 switch (attempt) {
306 case 0: pos = negative; break;
307 case 1: pos = !negative; break;
308 default: break ATTEMPS;
309 }
310
311 if (pos) {
312 position = getNegativeItemLabelPosition(series, item);
313 }
314 else {
315 position = getPositiveItemLabelPosition(series, item);
316 }
317
318 // work out the label anchor point...
319 Point2D anchorPoint = calculateLabelAnchorPoint(
320 position.getItemLabelAnchor(), x, y, orientation);
321
322 Shape labelShape = TextUtilities.calculateRotatedStringBounds(
323 label, g2,
324 (float)anchorPoint.getX(), (float)anchorPoint.getY(),
325 position.getTextAnchor(), position.getAngle(),
326 position.getRotationAnchor());
327
328 Rectangle2D bbox = labelShape.getBounds2D();
329
330 Point2D shift = shiftBox(bbox);
331
332 bbox = new Rectangle2D.Double(
333 bbox.getX() + shift.getX(),
334 bbox.getY() + shift.getY(),
335 bbox.getWidth(),
336 bbox.getHeight());
337
338 if (labelBoundingBoxes != null) {
339 for (Rectangle2D old: labelBoundingBoxes) {
340 if (old.intersects(bbox)) {
341 continue ATTEMPS;
342 }
343 }
344 labelBoundingBoxes.add(bbox);
345 }
346
347 TextUtilities.drawRotatedString(
348 label, g2,
349 (float)(anchorPoint.getX() + shift.getX()),
350 (float)(anchorPoint.getY() + shift.getY()),
351 position.getTextAnchor(), position.getAngle(),
352 position.getRotationAnchor());
353 break;
354 }
355 }
356 }
357 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org