comparison flys-artifacts/src/main/java/de/intevation/flys/jfree/ShapeRenderer.java @ 3162:0d8146989012

Added labeling for Q/W points FixingsKMChartService. flys-artifacts/trunk@4774 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Mon, 25 Jun 2012 11:38:33 +0000
parents
children 6d0567a8387d
comparison
equal deleted inserted replaced
3161:cd8d81b2824d 3162:0d8146989012
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 protected Entry [] entries;
115
116 protected List<Rectangle2D> labelBoundingBoxes;
117
118 protected Rectangle2D area;
119
120 public ShapeRenderer() {
121 this(SHAPES);
122 }
123
124 public ShapeRenderer(int type) {
125 super(type);
126 }
127
128 public ShapeRenderer(Map<Entry, Integer> map) {
129 super(SHAPES);
130 setEntries(map);
131 }
132
133 public void setEntries(Entry [] entries) {
134 this.entries = entries;
135 }
136
137 public void setEntries(Map<Entry, Integer> map) {
138 Entry [] entries = new Entry[map.size()];
139
140 for (Map.Entry<Entry, Integer> entry: map.entrySet()) {
141 entries[entry.getValue()] = entry.getKey();
142 }
143
144 setEntries(entries);
145 }
146
147 @Override
148 public Shape getSeriesShape(int series) {
149 return entries[series].shape;
150 }
151
152 public Shape getSeriesFrame(int series) {
153 return entries[series].frame;
154 }
155
156 @Override
157 public Paint getSeriesPaint(int series) {
158 return entries[series].paint;
159 }
160
161 @Override
162 public boolean getItemShapeFilled(int series, int item) {
163 return entries[series].filled;
164 }
165
166 @Override
167 public XYItemRendererState initialise(
168 Graphics2D g2,
169 Rectangle2D dataArea,
170 XYPlot plot,
171 XYDataset data,
172 PlotRenderingInfo info
173 ) {
174 if (labelBoundingBoxes == null) {
175 labelBoundingBoxes = new ArrayList<Rectangle2D>(32);
176 }
177 else {
178 labelBoundingBoxes.clear();
179 }
180
181 area = dataArea;
182
183 return super.initialise(g2, dataArea, plot, data, info);
184 }
185
186 @Override
187 public void drawItem(
188 Graphics2D g2,
189 XYItemRendererState state,
190 Rectangle2D dataArea,
191 PlotRenderingInfo info,
192 XYPlot plot,
193 ValueAxis domainAxis,
194 ValueAxis rangeAxis,
195 XYDataset dataset,
196 int series,
197 int item,
198 CrosshairState crosshairState,
199 int pass
200 ) {
201 if (!getItemVisible(series, item)) {
202 return;
203 }
204
205 // get the data point...
206 double x1 = dataset.getXValue(series, item);
207 double y1 = dataset.getYValue(series, item);
208 if (Double.isNaN(x1) || Double.isNaN(y1)) {
209 return;
210 }
211
212 RectangleEdge xAxisLocation = plot.getDomainAxisEdge();
213 RectangleEdge yAxisLocation = plot.getRangeAxisEdge();
214 double x = domainAxis.valueToJava2D(x1, dataArea, xAxisLocation);
215 double y = rangeAxis.valueToJava2D(y1, dataArea, yAxisLocation);
216
217 if (dataArea.contains(x, y))
218 super.drawItem(
219 g2,
220 state,
221 dataArea,
222 info,
223 plot,
224 domainAxis,
225 rangeAxis,
226 dataset,
227 series,
228 item,
229 crosshairState,
230 pass);
231 }
232
233 protected Point2D shiftBox(Rectangle2D box) {
234
235 double cx1 = area.getX();
236 double cy1 = area.getY();
237 double cx2 = cx1 + area.getWidth();
238 double cy2 = cy1 + area.getHeight();
239
240 double bx1 = box.getX();
241 double by1 = box.getY();
242 double bx2 = bx1 + box.getWidth();
243 double by2 = by1 + box.getHeight();
244
245 double dx;
246 double dy;
247
248 if (bx1 < cx1) {
249 dx = cx1 - bx1;
250 }
251 else if (bx2 > cx2) {
252 dx = cx2 - bx2;
253 }
254 else {
255 dx = 0d;
256 }
257
258 if (by1 < cy1) {
259 dy = cy1 - by1;
260 }
261 else if (by2 > cy2) {
262 dy = cy2 - by2;
263 }
264 else {
265 dy = 0d;
266 }
267
268 return new Point2D.Double(dx, dy);
269 }
270
271 @Override
272 protected void drawItemLabel(
273 Graphics2D g2,
274 PlotOrientation orientation,
275 XYDataset dataset,
276 int series,
277 int item,
278 double x,
279 double y,
280 boolean negative
281 ) {
282 XYItemLabelGenerator generator = getItemLabelGenerator(series, item);
283 if (generator == null) {
284 return;
285 }
286
287 Font labelFont = getItemLabelFont(series, item);
288
289 Paint paint = getItemLabelPaint(series, item);
290
291 g2.setFont(labelFont);
292 g2.setPaint(paint);
293
294 String label = generator.generateLabel(dataset, series, item);
295
296 // get the label position..
297 ItemLabelPosition position = null;
298 if (!negative) {
299 position = getPositiveItemLabelPosition(series, item);
300 }
301 else {
302 position = getNegativeItemLabelPosition(series, item);
303 }
304
305 // work out the label anchor point...
306 Point2D anchorPoint = calculateLabelAnchorPoint(
307 position.getItemLabelAnchor(), x, y, orientation);
308
309 Shape labelShape = TextUtilities.calculateRotatedStringBounds(
310 label, g2,
311 (float)anchorPoint.getX(), (float)anchorPoint.getY(),
312 position.getTextAnchor(), position.getAngle(),
313 position.getRotationAnchor());
314
315 Rectangle2D bbox = labelShape.getBounds2D();
316
317 Point2D shift = shiftBox(bbox);
318
319 bbox = new Rectangle2D.Double(
320 bbox.getX() + shift.getX(),
321 bbox.getY() + shift.getY(),
322 bbox.getWidth(),
323 bbox.getHeight());
324
325 if (labelBoundingBoxes != null) {
326 for (Rectangle2D old: labelBoundingBoxes) {
327 if (old.intersects(bbox)) {
328 return;
329 }
330 }
331 labelBoundingBoxes.add(bbox);
332 }
333
334 TextUtilities.drawRotatedString(
335 label, g2,
336 (float)(anchorPoint.getX() + shift.getX()),
337 (float)(anchorPoint.getY() + shift.getY()),
338 position.getTextAnchor(), position.getAngle(),
339 position.getRotationAnchor());
340 }
341 }
342 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org