comparison flys-artifacts/src/main/java/de/intevation/flys/exports/LongitudinalSectionGenerator.java @ 1038:4dcc635d6ca6

Extracted and renamed CustomAnnotation to StickyAxisAnnotation. Also removed needless imports. flys-artifacts/trunk@2499 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Felix Wolfsteller <felix.wolfsteller@intevation.de>
date Wed, 17 Aug 2011 12:53:55 +0000
parents 75cf1b11c97e
children 5411a33014e0
comparison
equal deleted inserted replaced
1037:75cf1b11c97e 1038:4dcc635d6ca6
1 package de.intevation.flys.exports; 1 package de.intevation.flys.exports;
2 2
3 import java.util.ArrayList; 3 import java.util.ArrayList;
4 import java.util.Iterator;
5 import java.util.List; 4 import java.util.List;
6 5
7 import org.apache.log4j.Logger; 6 import org.apache.log4j.Logger;
8 7
9 import java.awt.Shape;
10 import java.awt.geom.Rectangle2D;
11 import java.awt.geom.Line2D;
12
13 import org.jfree.chart.annotations.XYLineAnnotation;
14 import org.jfree.chart.annotations.XYTextAnnotation;
15 import org.jfree.chart.JFreeChart; 8 import org.jfree.chart.JFreeChart;
16 import org.jfree.chart.axis.NumberAxis; 9 import org.jfree.chart.axis.NumberAxis;
17 import org.jfree.chart.axis.ValueAxis; 10 import org.jfree.chart.axis.ValueAxis;
18 import org.jfree.chart.plot.XYPlot; 11 import org.jfree.chart.plot.XYPlot;
19 import org.jfree.chart.title.TextTitle; 12 import org.jfree.chart.title.TextTitle;
20 import org.jfree.data.Range; 13 import org.jfree.data.Range;
21 import org.jfree.data.xy.XYSeries; 14 import org.jfree.data.xy.XYSeries;
22 import org.jfree.ui.TextAnchor; 15 import org.jfree.ui.TextAnchor;
23 import org.jfree.chart.plot.PlotRenderingInfo;
24 import org.jfree.text.TextUtilities;
25 import org.jfree.chart.entity.XYAnnotationEntity;
26 import org.jfree.chart.plot.PlotOrientation;
27 import org.jfree.ui.RectangleEdge;
28 import org.jfree.chart.plot.Plot;
29 import org.jfree.chart.ChartRenderingInfo;
30 import org.jfree.chart.util.LineUtilities;
31 16
32 import org.w3c.dom.Document; 17 import org.w3c.dom.Document;
33 18
34 import de.intevation.artifacts.Artifact; 19 import de.intevation.artifacts.Artifact;
35 20
39 24
40 import de.intevation.flys.artifacts.model.FacetTypes; 25 import de.intevation.flys.artifacts.model.FacetTypes;
41 import de.intevation.flys.artifacts.model.WQKms; 26 import de.intevation.flys.artifacts.model.WQKms;
42 27
43 import de.intevation.flys.model.Annotation; 28 import de.intevation.flys.model.Annotation;
44
45 /**
46 * Custom Annotations class that is drawn only if no collisions with other
47 * already drawn CustomAnnotations in current plot are found.
48 * Draws a given text and a line to it from either axis.
49 */
50 class CustomAnnotation extends XYTextAnnotation {
51
52 /** Logger for this class. */
53 private static Logger logger =
54 Logger.getLogger(CustomAnnotation.class);
55
56 /** Simplified view on axes. */
57 public static enum SimpleAxis {
58 X_AXIS, /** Usually "horizontal". */
59 Y_AXIS /** Usually "vertical". */
60 }
61
62 /** Which axis to stick to. */
63 protected SimpleAxis stickyAxis = SimpleAxis.X_AXIS;
64
65
66 /**
67 * Trivial constructor.
68 *
69 * @param text Text to display.
70 * @param x X-position in dataspace (typical horizontal, in km).
71 * @param y Y-position in dataspace (typical vertical, in m).
72 */
73 public CustomAnnotation(String text, float x, float y) {
74 super(text, x, y);
75 }
76
77
78 /**
79 * Sets the "sticky axis" (whether to draw annotations at the
80 * X- or the Y-Axis.
81 *
82 * @param stickyAxis axis to stick to.
83 */
84 public void setStickyAxis(SimpleAxis stickyAxis) {
85 this.stickyAxis = stickyAxis;
86 }
87
88
89 /**
90 * Draws a small line at axis where this annotation resides.
91 *
92 * @param g2 the graphics device.
93 * @param dataArea the data area.
94 * @param domainAxis the domain axis.
95 * @param rangeAxis the range axis.
96 * @param domainEdge the domain edge.
97 * @param rangeEdge the range edge.
98 * @param orientation the plot orientation.
99 */
100 protected void drawAxisMark(
101 java.awt.Graphics2D g2,
102 java.awt.geom.Rectangle2D dataArea,
103 ValueAxis domainAxis,
104 ValueAxis rangeAxis,
105 RectangleEdge domainEdge,
106 RectangleEdge rangeEdge,
107 PlotOrientation orientation) {
108 float j2DX1 = 0.0f;
109 float j2DX2 = 0.0f;
110 float j2DY1 = 0.0f;
111 float j2DY2 = 0.0f;
112 float x = (float) getX();
113 float y = (float) getY();
114 /* When dependent on X/Y-Axis and orientation, following
115 can be used as a base:
116 if (orientation == PlotOrientation.VERTICAL) {
117 j2DX1 = (float) domainAxis.valueToJava2D(x, dataArea,
118 domainEdge);
119 j2DY1 = (float) rangeAxis.valueToJava2D(y, dataArea,
120 rangeEdge);
121 j2DX2 = (float) domainAxis.valueToJava2D(x, dataArea,
122 domainEdge);
123 j2DY2 = (float) rangeAxis.valueToJava2D(y, dataArea,
124 rangeEdge);
125 }
126 else if (orientation == PlotOrientation.HORIZONTAL) {
127 j2DY1 = (float) domainAxis.valueToJava2D(x, dataArea,
128 domainEdge);
129 j2DX1 = (float) rangeAxis.valueToJava2D(y, dataArea,
130 rangeEdge);
131 j2DY2 = (float) domainAxis.valueToJava2D(x, dataArea,
132 domainEdge);
133 j2DX2 = (float) rangeAxis.valueToJava2D(y, dataArea,
134 rangeEdge);
135 }
136
137 g2.setPaint(this.paint);
138 g2.setStroke(this.stroke);
139 */
140 j2DY1 = (float) RectangleEdge.coordinate(dataArea, domainEdge);
141 j2DY2 = j2DY1 - 0.10f * (float)
142 (rangeAxis.getRange().getUpperBound()
143 - rangeAxis.getRange().getLowerBound());
144 j2DX1 = (float) domainAxis.valueToJava2D(x, dataArea, domainEdge);
145 j2DX2 = j2DX1;
146
147 Line2D line = new Line2D.Float(j2DX1, j2DY1, j2DX2, j2DY2);
148
149 // line is clipped to avoid JRE bug 6574155, for more info
150 // see JFreeChart bug 2221495
151 boolean visible = LineUtilities.clipLine(line, dataArea);
152 if (visible) {
153 g2.draw(line);
154 }
155 }
156
157
158 /**
159 * Draw the Annotiation if it does not collide with other already drawn
160 * Annotations.
161 *
162 * @param g2 the graphics device.
163 * @param plot the plot.
164 * @param dataArea the data area.
165 * @param domainAxis the domain axis.
166 * @param rangeAxis the range axis.
167 * @param rendererIndex the render index.
168 * @param info state information, escpecially collects info about
169 * already drawn shapes (and thus annotations), used
170 * for collision detection.
171 */
172 @Override
173 public void draw(
174 java.awt.Graphics2D g2,
175 XYPlot plot,
176 java.awt.geom.Rectangle2D dataArea,
177 ValueAxis domainAxis,
178 ValueAxis rangeAxis,
179 int rendererIndex,
180 PlotRenderingInfo info) {
181
182 if (info == null)
183 return;
184
185 // Calculate the bounding box.
186 ChartRenderingInfo chartInfo = info.getOwner();
187
188 PlotOrientation orientation = plot.getOrientation();
189 RectangleEdge domainEdge = Plot.resolveDomainAxisLocation(
190 plot.getDomainAxisLocation(), orientation);
191 RectangleEdge rangeEdge = Plot.resolveRangeAxisLocation(
192 plot.getRangeAxisLocation(), orientation);
193 float anchorX = (float) domainAxis.valueToJava2D(
194 getX(), dataArea, domainEdge);
195 float anchorY = (float) rangeAxis.valueToJava2D(
196 getY(), dataArea, rangeEdge);
197 if (orientation == PlotOrientation.HORIZONTAL) {
198 float tempAnchor = anchorX;
199 anchorX = anchorY;
200 anchorY = tempAnchor;
201 }
202
203 // Always draw the small line at axis.
204 drawAxisMark(g2, dataArea, domainAxis, rangeAxis, domainEdge,
205 rangeEdge, orientation);
206
207 g2.setFont(getFont());
208 Shape hotspot = TextUtilities.calculateRotatedStringBounds(
209 getText(), g2, anchorX, anchorY, getTextAnchor(),
210 getRotationAngle(), getRotationAnchor());
211 Rectangle2D hotspotBox = hotspot.getBounds2D();
212 // Check for collisions with other XYAnnotations.
213 for (Iterator i = chartInfo.getEntityCollection().iterator();
214 i.hasNext(); ) {
215 Object next = i.next();
216 // Collision with other stuff than XYAnnotations are okay.
217 if (next instanceof XYAnnotationEntity) {
218 XYAnnotationEntity drawnShape = (XYAnnotationEntity) next;
219 if (drawnShape.getArea().intersects(hotspotBox)) {
220 // Found collision, early stop.
221 return;
222 }
223 }
224 }
225
226 // Actuall drawing.
227 if (getBackgroundPaint() != null) {
228 g2.setPaint(getBackgroundPaint());
229 g2.fill(hotspot);
230 }
231 g2.setPaint(getPaint());
232 TextUtilities.drawRotatedString(getText(), g2, anchorX, anchorY,
233 getTextAnchor(), getRotationAngle(), getRotationAnchor());
234 // Draw outline.
235 if (false) {
236 g2.setStroke(getOutlineStroke());
237 g2.setPaint(getOutlinePaint());
238 g2.draw(hotspot);
239 }
240
241 // Add info that we have drawn this Annotation.
242 addEntity(info, hotspot, rendererIndex, getToolTipText(), getURL());
243 }
244 }
245 29
246 30
247 /** 31 /**
248 * An OutGenerator that generates discharge curves. 32 * An OutGenerator that generates discharge curves.
249 * 33 *
355 * @param axis the value axis. 139 * @param axis the value axis.
356 */ 140 */
357 protected void redoAnnotations(XYPlot plot, ValueAxis axis) { 141 protected void redoAnnotations(XYPlot plot, ValueAxis axis) {
358 plot.clearAnnotations(); 142 plot.clearAnnotations();
359 // TODO Position calculation could/should be done in 143 // TODO Position calculation could/should be done in
360 // the CustomAnnotation-Implementation itself. 144 // the StickyAxisAnnotation-Implementation itself.
361 ValueAxis yAxis = plot.getRangeAxis(); 145 ValueAxis yAxis = plot.getRangeAxis();
362 float posY = 140.f; 146 float posY = 140.f;
363 if (yAxis != null) { 147 if (yAxis != null) {
364 posY = (float) yAxis.getRange().getLowerBound(); 148 posY = (float) yAxis.getRange().getLowerBound();
365 posYLess = posY;
366 // Add some (2%) space between Text and axis. 149 // Add some (2%) space between Text and axis.
367 posY += 0.02f * (yAxis.getRange().getUpperBound() 150 posY += 0.02f * (yAxis.getRange().getUpperBound()
368 - yAxis.getRange().getLowerBound()); 151 - yAxis.getRange().getLowerBound());
369 } 152 }
370 153
371 // Add all annotations. 154 // Add all annotations.
372 for (Annotation a: annotations) { 155 for (Annotation a: annotations) {
373 float posX = (float) a.getRange().getA().doubleValue(); 156 float posX = (float) a.getRange().getA().doubleValue();
374 String text = a.getPosition().getValue(); 157 String text = a.getPosition().getValue();
375 158
376 XYTextAnnotation ta = new CustomAnnotation(text, posX, posY); 159 StickyAxisAnnotation ta = new StickyAxisAnnotation(text, posX, posY);
377 double rotation = 270.0f * (Math.PI / 180.0f); 160 double rotation = 270.0f * (Math.PI / 180.0f);
378 ta.setRotationAngle(rotation); 161 ta.setRotationAngle(rotation);
379 ta.setRotationAnchor(TextAnchor.CENTER_LEFT); 162 ta.setRotationAnchor(TextAnchor.CENTER_LEFT);
380 ta.setTextAnchor(TextAnchor.CENTER_LEFT); 163 ta.setTextAnchor(TextAnchor.CENTER_LEFT);
381 plot.getRenderer().addAnnotation(ta); 164 plot.getRenderer().addAnnotation(ta);

http://dive4elements.wald.intevation.org