comparison flys-artifacts/src/main/java/de/intevation/flys/jfree/StickyAxisAnnotation.java @ 1039:cf39205df113

Part of refactoring (see next commit). flys-artifacts/trunk@2500 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Felix Wolfsteller <felix.wolfsteller@intevation.de>
date Wed, 17 Aug 2011 13:04:53 +0000
parents
children 8873c43119ca
comparison
equal deleted inserted replaced
1038:4dcc635d6ca6 1039:cf39205df113
1 package de.intevation.flys.jfree;
2
3 import org.apache.log4j.Logger;
4
5 import java.util.Iterator;
6
7 import java.awt.Shape;
8 import java.awt.geom.Rectangle2D;
9 import java.awt.geom.Line2D;
10
11 import org.jfree.chart.annotations.XYTextAnnotation;
12 import org.jfree.chart.axis.ValueAxis;
13 import org.jfree.chart.util.LineUtilities;
14 import org.jfree.text.TextUtilities;
15 import org.jfree.chart.plot.PlotOrientation;
16 import org.jfree.chart.plot.XYPlot;
17 import org.jfree.chart.entity.XYAnnotationEntity;
18 import org.jfree.chart.plot.PlotRenderingInfo;
19 import org.jfree.chart.ChartRenderingInfo;
20 import org.jfree.chart.plot.Plot;
21
22 import org.jfree.ui.RectangleEdge;
23
24
25 /**
26 * Custom Annotations class that is drawn only if no collisions with other
27 * already drawn CustomAnnotations in current plot are found.
28 * Draws a given text and a line to it from either axis.
29 */
30 public class StickyAxisAnnotation extends XYTextAnnotation {
31
32 /** Logger for this class. */
33 private static Logger logger =
34 Logger.getLogger(StickyAxisAnnotation.class);
35
36 /** Simplified view on axes. */
37 public static enum SimpleAxis {
38 X_AXIS, /** Usually "horizontal". */
39 Y_AXIS /** Usually "vertical". */
40 }
41
42 /** Which axis to stick to. */
43 protected SimpleAxis stickyAxis = SimpleAxis.X_AXIS;
44
45
46 /**
47 * Trivial constructor.
48 *
49 * @param text Text to display.
50 * @param x X-position in dataspace (typical horizontal, in km).
51 * @param y Y-position in dataspace (typical vertical, in m).
52 */
53 public StickyAxisAnnotation(String text, float x, float y) {
54 super(text, x, y);
55 }
56
57
58 /**
59 * Sets the "sticky axis" (whether to draw annotations at the
60 * X- or the Y-Axis.
61 *
62 * @param stickyAxis axis to stick to.
63 */
64 public void setStickyAxis(SimpleAxis stickyAxis) {
65 this.stickyAxis = stickyAxis;
66 }
67
68
69 /**
70 * Draws a small line at axis where this annotation resides.
71 *
72 * @param g2 the graphics device.
73 * @param dataArea the data area.
74 * @param domainAxis the domain axis.
75 * @param rangeAxis the range axis.
76 * @param domainEdge the domain edge.
77 * @param rangeEdge the range edge.
78 * @param orientation the plot orientation.
79 */
80 protected void drawAxisMark(
81 java.awt.Graphics2D g2,
82 java.awt.geom.Rectangle2D dataArea,
83 ValueAxis domainAxis,
84 ValueAxis rangeAxis,
85 RectangleEdge domainEdge,
86 RectangleEdge rangeEdge,
87 PlotOrientation orientation) {
88 float j2DX1 = 0.0f;
89 float j2DX2 = 0.0f;
90 float j2DY1 = 0.0f;
91 float j2DY2 = 0.0f;
92 float x = (float) getX();
93 float y = (float) getY();
94 /* When dependent on X/Y-Axis and orientation, following
95 can be used as a base:
96 if (orientation == PlotOrientation.VERTICAL) {
97 j2DX1 = (float) domainAxis.valueToJava2D(x, dataArea,
98 domainEdge);
99 j2DY1 = (float) rangeAxis.valueToJava2D(y, dataArea,
100 rangeEdge);
101 j2DX2 = (float) domainAxis.valueToJava2D(x, dataArea,
102 domainEdge);
103 j2DY2 = (float) rangeAxis.valueToJava2D(y, dataArea,
104 rangeEdge);
105 }
106 else if (orientation == PlotOrientation.HORIZONTAL) {
107 j2DY1 = (float) domainAxis.valueToJava2D(x, dataArea,
108 domainEdge);
109 j2DX1 = (float) rangeAxis.valueToJava2D(y, dataArea,
110 rangeEdge);
111 j2DY2 = (float) domainAxis.valueToJava2D(x, dataArea,
112 domainEdge);
113 j2DX2 = (float) rangeAxis.valueToJava2D(y, dataArea,
114 rangeEdge);
115 }
116
117 g2.setPaint(this.paint);
118 g2.setStroke(this.stroke);
119 */
120 j2DY1 = (float) RectangleEdge.coordinate(dataArea, domainEdge);
121 j2DY2 = j2DY1 - 0.10f * (float)
122 (rangeAxis.getRange().getUpperBound()
123 - rangeAxis.getRange().getLowerBound());
124 j2DX1 = (float) domainAxis.valueToJava2D(x, dataArea, domainEdge);
125 j2DX2 = j2DX1;
126
127 Line2D line = new Line2D.Float(j2DX1, j2DY1, j2DX2, j2DY2);
128
129 // line is clipped to avoid JRE bug 6574155, for more info
130 // see JFreeChart bug 2221495
131 boolean visible = LineUtilities.clipLine(line, dataArea);
132 if (visible) {
133 g2.draw(line);
134 }
135 }
136
137
138 /**
139 * Draw the Annotiation if it does not collide with other already drawn
140 * Annotations.
141 *
142 * @param g2 the graphics device.
143 * @param plot the plot.
144 * @param dataArea the data area.
145 * @param domainAxis the domain axis.
146 * @param rangeAxis the range axis.
147 * @param rendererIndex the render index.
148 * @param info state information, escpecially collects info about
149 * already drawn shapes (and thus annotations), used
150 * for collision detection.
151 */
152 @Override
153 public void draw(
154 java.awt.Graphics2D g2,
155 XYPlot plot,
156 java.awt.geom.Rectangle2D dataArea,
157 ValueAxis domainAxis,
158 ValueAxis rangeAxis,
159 int rendererIndex,
160 PlotRenderingInfo info) {
161
162 if (info == null)
163 return;
164
165 // Calculate the bounding box.
166 ChartRenderingInfo chartInfo = info.getOwner();
167
168 PlotOrientation orientation = plot.getOrientation();
169 RectangleEdge domainEdge = Plot.resolveDomainAxisLocation(
170 plot.getDomainAxisLocation(), orientation);
171 RectangleEdge rangeEdge = Plot.resolveRangeAxisLocation(
172 plot.getRangeAxisLocation(), orientation);
173 float anchorX = (float) domainAxis.valueToJava2D(
174 getX(), dataArea, domainEdge);
175 float anchorY = (float) rangeAxis.valueToJava2D(
176 getY(), dataArea, rangeEdge);
177 if (orientation == PlotOrientation.HORIZONTAL) {
178 float tempAnchor = anchorX;
179 anchorX = anchorY;
180 anchorY = tempAnchor;
181 }
182
183 // Always draw the small line at axis.
184 drawAxisMark(g2, dataArea, domainAxis, rangeAxis, domainEdge,
185 rangeEdge, orientation);
186
187 g2.setFont(getFont());
188 Shape hotspot = TextUtilities.calculateRotatedStringBounds(
189 getText(), g2, anchorX, anchorY, getTextAnchor(),
190 getRotationAngle(), getRotationAnchor());
191 Rectangle2D hotspotBox = hotspot.getBounds2D();
192 // Check for collisions with other XYAnnotations.
193 for (Iterator i = chartInfo.getEntityCollection().iterator();
194 i.hasNext(); ) {
195 Object next = i.next();
196 // Collision with other stuff than XYAnnotations are okay.
197 if (next instanceof XYAnnotationEntity) {
198 XYAnnotationEntity drawnShape = (XYAnnotationEntity) next;
199 if (drawnShape.getArea().intersects(hotspotBox)) {
200 // Found collision, early stop.
201 return;
202 }
203 }
204 }
205
206 // Actuall drawing.
207 if (getBackgroundPaint() != null) {
208 g2.setPaint(getBackgroundPaint());
209 g2.fill(hotspot);
210 }
211 g2.setPaint(getPaint());
212 TextUtilities.drawRotatedString(getText(), g2, anchorX, anchorY,
213 getTextAnchor(), getRotationAngle(), getRotationAnchor());
214 // Draw outline.
215 if (false) {
216 g2.setStroke(getOutlineStroke());
217 g2.setPaint(getOutlinePaint());
218 g2.draw(hotspot);
219 }
220
221 // Add info that we have drawn this Annotation.
222 addEntity(info, hotspot, rendererIndex, getToolTipText(), getURL());
223 }
224 }
225
226

http://dive4elements.wald.intevation.org