# HG changeset patch # User Felix Wolfsteller # Date 1313585635 0 # Node ID 4dcc635d6ca6f93a2b21abb41154e2774975cb4f # Parent 75cf1b11c97ede67994ac1782e27e5b643ab2a0b Extracted and renamed CustomAnnotation to StickyAxisAnnotation. Also removed needless imports. flys-artifacts/trunk@2499 c6561f87-3c4e-4783-a992-168aeb5c3f6f diff -r 75cf1b11c97e -r 4dcc635d6ca6 flys-artifacts/ChangeLog --- a/flys-artifacts/ChangeLog Wed Aug 17 12:32:26 2011 +0000 +++ b/flys-artifacts/ChangeLog Wed Aug 17 12:53:55 2011 +0000 @@ -1,3 +1,13 @@ +2011-08-17 Felix Wolfsteller + + Extracted and renamed CustomAnnotation to StickyAxisAnnotation. Also removed + needless imports. + + * src/main/java/de/intevation/flys/exports/LongitudinalSectionGenerator.java, + src/main/java/de/intevation/flys/exports/StickyAxisAnnotation.java: + Extracted class implementation CustomAnnotation and renamed to + StickyAxisAnnotation. + 2011-08-17 Felix Wolfsteller Improved CustomAnnotations and rendering thereof, now including an diff -r 75cf1b11c97e -r 4dcc635d6ca6 flys-artifacts/src/main/java/de/intevation/flys/exports/LongitudinalSectionGenerator.java --- a/flys-artifacts/src/main/java/de/intevation/flys/exports/LongitudinalSectionGenerator.java Wed Aug 17 12:32:26 2011 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/LongitudinalSectionGenerator.java Wed Aug 17 12:53:55 2011 +0000 @@ -1,17 +1,10 @@ package de.intevation.flys.exports; import java.util.ArrayList; -import java.util.Iterator; import java.util.List; import org.apache.log4j.Logger; -import java.awt.Shape; -import java.awt.geom.Rectangle2D; -import java.awt.geom.Line2D; - -import org.jfree.chart.annotations.XYLineAnnotation; -import org.jfree.chart.annotations.XYTextAnnotation; import org.jfree.chart.JFreeChart; import org.jfree.chart.axis.NumberAxis; import org.jfree.chart.axis.ValueAxis; @@ -20,14 +13,6 @@ import org.jfree.data.Range; import org.jfree.data.xy.XYSeries; import org.jfree.ui.TextAnchor; -import org.jfree.chart.plot.PlotRenderingInfo; -import org.jfree.text.TextUtilities; -import org.jfree.chart.entity.XYAnnotationEntity; -import org.jfree.chart.plot.PlotOrientation; -import org.jfree.ui.RectangleEdge; -import org.jfree.chart.plot.Plot; -import org.jfree.chart.ChartRenderingInfo; -import org.jfree.chart.util.LineUtilities; import org.w3c.dom.Document; @@ -42,207 +27,6 @@ import de.intevation.flys.model.Annotation; -/** - * Custom Annotations class that is drawn only if no collisions with other - * already drawn CustomAnnotations in current plot are found. - * Draws a given text and a line to it from either axis. - */ -class CustomAnnotation extends XYTextAnnotation { - - /** Logger for this class. */ - private static Logger logger = - Logger.getLogger(CustomAnnotation.class); - - /** Simplified view on axes. */ - public static enum SimpleAxis { - X_AXIS, /** Usually "horizontal". */ - Y_AXIS /** Usually "vertical". */ - } - - /** Which axis to stick to. */ - protected SimpleAxis stickyAxis = SimpleAxis.X_AXIS; - - - /** - * Trivial constructor. - * - * @param text Text to display. - * @param x X-position in dataspace (typical horizontal, in km). - * @param y Y-position in dataspace (typical vertical, in m). - */ - public CustomAnnotation(String text, float x, float y) { - super(text, x, y); - } - - - /** - * Sets the "sticky axis" (whether to draw annotations at the - * X- or the Y-Axis. - * - * @param stickyAxis axis to stick to. - */ - public void setStickyAxis(SimpleAxis stickyAxis) { - this.stickyAxis = stickyAxis; - } - - - /** - * Draws a small line at axis where this annotation resides. - * - * @param g2 the graphics device. - * @param dataArea the data area. - * @param domainAxis the domain axis. - * @param rangeAxis the range axis. - * @param domainEdge the domain edge. - * @param rangeEdge the range edge. - * @param orientation the plot orientation. - */ - protected void drawAxisMark( - java.awt.Graphics2D g2, - java.awt.geom.Rectangle2D dataArea, - ValueAxis domainAxis, - ValueAxis rangeAxis, - RectangleEdge domainEdge, - RectangleEdge rangeEdge, - PlotOrientation orientation) { - float j2DX1 = 0.0f; - float j2DX2 = 0.0f; - float j2DY1 = 0.0f; - float j2DY2 = 0.0f; - float x = (float) getX(); - float y = (float) getY(); - /* When dependent on X/Y-Axis and orientation, following - can be used as a base: - if (orientation == PlotOrientation.VERTICAL) { - j2DX1 = (float) domainAxis.valueToJava2D(x, dataArea, - domainEdge); - j2DY1 = (float) rangeAxis.valueToJava2D(y, dataArea, - rangeEdge); - j2DX2 = (float) domainAxis.valueToJava2D(x, dataArea, - domainEdge); - j2DY2 = (float) rangeAxis.valueToJava2D(y, dataArea, - rangeEdge); - } - else if (orientation == PlotOrientation.HORIZONTAL) { - j2DY1 = (float) domainAxis.valueToJava2D(x, dataArea, - domainEdge); - j2DX1 = (float) rangeAxis.valueToJava2D(y, dataArea, - rangeEdge); - j2DY2 = (float) domainAxis.valueToJava2D(x, dataArea, - domainEdge); - j2DX2 = (float) rangeAxis.valueToJava2D(y, dataArea, - rangeEdge); - } - - g2.setPaint(this.paint); - g2.setStroke(this.stroke); - */ - j2DY1 = (float) RectangleEdge.coordinate(dataArea, domainEdge); - j2DY2 = j2DY1 - 0.10f * (float) - (rangeAxis.getRange().getUpperBound() - - rangeAxis.getRange().getLowerBound()); - j2DX1 = (float) domainAxis.valueToJava2D(x, dataArea, domainEdge); - j2DX2 = j2DX1; - - Line2D line = new Line2D.Float(j2DX1, j2DY1, j2DX2, j2DY2); - - // line is clipped to avoid JRE bug 6574155, for more info - // see JFreeChart bug 2221495 - boolean visible = LineUtilities.clipLine(line, dataArea); - if (visible) { - g2.draw(line); - } - } - - - /** - * Draw the Annotiation if it does not collide with other already drawn - * Annotations. - * - * @param g2 the graphics device. - * @param plot the plot. - * @param dataArea the data area. - * @param domainAxis the domain axis. - * @param rangeAxis the range axis. - * @param rendererIndex the render index. - * @param info state information, escpecially collects info about - * already drawn shapes (and thus annotations), used - * for collision detection. - */ - @Override - public void draw( - java.awt.Graphics2D g2, - XYPlot plot, - java.awt.geom.Rectangle2D dataArea, - ValueAxis domainAxis, - ValueAxis rangeAxis, - int rendererIndex, - PlotRenderingInfo info) { - - if (info == null) - return; - - // Calculate the bounding box. - ChartRenderingInfo chartInfo = info.getOwner(); - - PlotOrientation orientation = plot.getOrientation(); - RectangleEdge domainEdge = Plot.resolveDomainAxisLocation( - plot.getDomainAxisLocation(), orientation); - RectangleEdge rangeEdge = Plot.resolveRangeAxisLocation( - plot.getRangeAxisLocation(), orientation); - float anchorX = (float) domainAxis.valueToJava2D( - getX(), dataArea, domainEdge); - float anchorY = (float) rangeAxis.valueToJava2D( - getY(), dataArea, rangeEdge); - if (orientation == PlotOrientation.HORIZONTAL) { - float tempAnchor = anchorX; - anchorX = anchorY; - anchorY = tempAnchor; - } - - // Always draw the small line at axis. - drawAxisMark(g2, dataArea, domainAxis, rangeAxis, domainEdge, - rangeEdge, orientation); - - g2.setFont(getFont()); - Shape hotspot = TextUtilities.calculateRotatedStringBounds( - getText(), g2, anchorX, anchorY, getTextAnchor(), - getRotationAngle(), getRotationAnchor()); - Rectangle2D hotspotBox = hotspot.getBounds2D(); - // Check for collisions with other XYAnnotations. - for (Iterator i = chartInfo.getEntityCollection().iterator(); - i.hasNext(); ) { - Object next = i.next(); - // Collision with other stuff than XYAnnotations are okay. - if (next instanceof XYAnnotationEntity) { - XYAnnotationEntity drawnShape = (XYAnnotationEntity) next; - if (drawnShape.getArea().intersects(hotspotBox)) { - // Found collision, early stop. - return; - } - } - } - - // Actuall drawing. - if (getBackgroundPaint() != null) { - g2.setPaint(getBackgroundPaint()); - g2.fill(hotspot); - } - g2.setPaint(getPaint()); - TextUtilities.drawRotatedString(getText(), g2, anchorX, anchorY, - getTextAnchor(), getRotationAngle(), getRotationAnchor()); - // Draw outline. - if (false) { - g2.setStroke(getOutlineStroke()); - g2.setPaint(getOutlinePaint()); - g2.draw(hotspot); - } - - // Add info that we have drawn this Annotation. - addEntity(info, hotspot, rendererIndex, getToolTipText(), getURL()); - } -} - /** * An OutGenerator that generates discharge curves. @@ -357,12 +141,11 @@ protected void redoAnnotations(XYPlot plot, ValueAxis axis) { plot.clearAnnotations(); // TODO Position calculation could/should be done in - // the CustomAnnotation-Implementation itself. + // the StickyAxisAnnotation-Implementation itself. ValueAxis yAxis = plot.getRangeAxis(); float posY = 140.f; if (yAxis != null) { posY = (float) yAxis.getRange().getLowerBound(); - posYLess = posY; // Add some (2%) space between Text and axis. posY += 0.02f * (yAxis.getRange().getUpperBound() - yAxis.getRange().getLowerBound()); @@ -373,7 +156,7 @@ float posX = (float) a.getRange().getA().doubleValue(); String text = a.getPosition().getValue(); - XYTextAnnotation ta = new CustomAnnotation(text, posX, posY); + StickyAxisAnnotation ta = new StickyAxisAnnotation(text, posX, posY); double rotation = 270.0f * (Math.PI / 180.0f); ta.setRotationAngle(rotation); ta.setRotationAnchor(TextAnchor.CENTER_LEFT); diff -r 75cf1b11c97e -r 4dcc635d6ca6 flys-artifacts/src/main/java/de/intevation/flys/exports/StickyAxisAnnotation.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/StickyAxisAnnotation.java Wed Aug 17 12:53:55 2011 +0000 @@ -0,0 +1,226 @@ +package de.intevation.flys.exports; + +import org.apache.log4j.Logger; + +import java.util.Iterator; + +import java.awt.Shape; +import java.awt.geom.Rectangle2D; +import java.awt.geom.Line2D; + +import org.jfree.chart.annotations.XYTextAnnotation; +import org.jfree.chart.axis.ValueAxis; +import org.jfree.chart.util.LineUtilities; +import org.jfree.text.TextUtilities; +import org.jfree.chart.plot.PlotOrientation; +import org.jfree.chart.plot.XYPlot; +import org.jfree.chart.entity.XYAnnotationEntity; +import org.jfree.chart.plot.PlotRenderingInfo; +import org.jfree.chart.ChartRenderingInfo; +import org.jfree.chart.plot.Plot; + +import org.jfree.ui.RectangleEdge; + + +/** + * Custom Annotations class that is drawn only if no collisions with other + * already drawn CustomAnnotations in current plot are found. + * Draws a given text and a line to it from either axis. + */ +class StickyAxisAnnotation extends XYTextAnnotation { + + /** Logger for this class. */ + private static Logger logger = + Logger.getLogger(StickyAxisAnnotation.class); + + /** Simplified view on axes. */ + public static enum SimpleAxis { + X_AXIS, /** Usually "horizontal". */ + Y_AXIS /** Usually "vertical". */ + } + + /** Which axis to stick to. */ + protected SimpleAxis stickyAxis = SimpleAxis.X_AXIS; + + + /** + * Trivial constructor. + * + * @param text Text to display. + * @param x X-position in dataspace (typical horizontal, in km). + * @param y Y-position in dataspace (typical vertical, in m). + */ + public StickyAxisAnnotation(String text, float x, float y) { + super(text, x, y); + } + + + /** + * Sets the "sticky axis" (whether to draw annotations at the + * X- or the Y-Axis. + * + * @param stickyAxis axis to stick to. + */ + public void setStickyAxis(SimpleAxis stickyAxis) { + this.stickyAxis = stickyAxis; + } + + + /** + * Draws a small line at axis where this annotation resides. + * + * @param g2 the graphics device. + * @param dataArea the data area. + * @param domainAxis the domain axis. + * @param rangeAxis the range axis. + * @param domainEdge the domain edge. + * @param rangeEdge the range edge. + * @param orientation the plot orientation. + */ + protected void drawAxisMark( + java.awt.Graphics2D g2, + java.awt.geom.Rectangle2D dataArea, + ValueAxis domainAxis, + ValueAxis rangeAxis, + RectangleEdge domainEdge, + RectangleEdge rangeEdge, + PlotOrientation orientation) { + float j2DX1 = 0.0f; + float j2DX2 = 0.0f; + float j2DY1 = 0.0f; + float j2DY2 = 0.0f; + float x = (float) getX(); + float y = (float) getY(); + /* When dependent on X/Y-Axis and orientation, following + can be used as a base: + if (orientation == PlotOrientation.VERTICAL) { + j2DX1 = (float) domainAxis.valueToJava2D(x, dataArea, + domainEdge); + j2DY1 = (float) rangeAxis.valueToJava2D(y, dataArea, + rangeEdge); + j2DX2 = (float) domainAxis.valueToJava2D(x, dataArea, + domainEdge); + j2DY2 = (float) rangeAxis.valueToJava2D(y, dataArea, + rangeEdge); + } + else if (orientation == PlotOrientation.HORIZONTAL) { + j2DY1 = (float) domainAxis.valueToJava2D(x, dataArea, + domainEdge); + j2DX1 = (float) rangeAxis.valueToJava2D(y, dataArea, + rangeEdge); + j2DY2 = (float) domainAxis.valueToJava2D(x, dataArea, + domainEdge); + j2DX2 = (float) rangeAxis.valueToJava2D(y, dataArea, + rangeEdge); + } + + g2.setPaint(this.paint); + g2.setStroke(this.stroke); + */ + j2DY1 = (float) RectangleEdge.coordinate(dataArea, domainEdge); + j2DY2 = j2DY1 - 0.10f * (float) + (rangeAxis.getRange().getUpperBound() + - rangeAxis.getRange().getLowerBound()); + j2DX1 = (float) domainAxis.valueToJava2D(x, dataArea, domainEdge); + j2DX2 = j2DX1; + + Line2D line = new Line2D.Float(j2DX1, j2DY1, j2DX2, j2DY2); + + // line is clipped to avoid JRE bug 6574155, for more info + // see JFreeChart bug 2221495 + boolean visible = LineUtilities.clipLine(line, dataArea); + if (visible) { + g2.draw(line); + } + } + + + /** + * Draw the Annotiation if it does not collide with other already drawn + * Annotations. + * + * @param g2 the graphics device. + * @param plot the plot. + * @param dataArea the data area. + * @param domainAxis the domain axis. + * @param rangeAxis the range axis. + * @param rendererIndex the render index. + * @param info state information, escpecially collects info about + * already drawn shapes (and thus annotations), used + * for collision detection. + */ + @Override + public void draw( + java.awt.Graphics2D g2, + XYPlot plot, + java.awt.geom.Rectangle2D dataArea, + ValueAxis domainAxis, + ValueAxis rangeAxis, + int rendererIndex, + PlotRenderingInfo info) { + + if (info == null) + return; + + // Calculate the bounding box. + ChartRenderingInfo chartInfo = info.getOwner(); + + PlotOrientation orientation = plot.getOrientation(); + RectangleEdge domainEdge = Plot.resolveDomainAxisLocation( + plot.getDomainAxisLocation(), orientation); + RectangleEdge rangeEdge = Plot.resolveRangeAxisLocation( + plot.getRangeAxisLocation(), orientation); + float anchorX = (float) domainAxis.valueToJava2D( + getX(), dataArea, domainEdge); + float anchorY = (float) rangeAxis.valueToJava2D( + getY(), dataArea, rangeEdge); + if (orientation == PlotOrientation.HORIZONTAL) { + float tempAnchor = anchorX; + anchorX = anchorY; + anchorY = tempAnchor; + } + + // Always draw the small line at axis. + drawAxisMark(g2, dataArea, domainAxis, rangeAxis, domainEdge, + rangeEdge, orientation); + + g2.setFont(getFont()); + Shape hotspot = TextUtilities.calculateRotatedStringBounds( + getText(), g2, anchorX, anchorY, getTextAnchor(), + getRotationAngle(), getRotationAnchor()); + Rectangle2D hotspotBox = hotspot.getBounds2D(); + // Check for collisions with other XYAnnotations. + for (Iterator i = chartInfo.getEntityCollection().iterator(); + i.hasNext(); ) { + Object next = i.next(); + // Collision with other stuff than XYAnnotations are okay. + if (next instanceof XYAnnotationEntity) { + XYAnnotationEntity drawnShape = (XYAnnotationEntity) next; + if (drawnShape.getArea().intersects(hotspotBox)) { + // Found collision, early stop. + return; + } + } + } + + // Actuall drawing. + if (getBackgroundPaint() != null) { + g2.setPaint(getBackgroundPaint()); + g2.fill(hotspot); + } + g2.setPaint(getPaint()); + TextUtilities.drawRotatedString(getText(), g2, anchorX, anchorY, + getTextAnchor(), getRotationAngle(), getRotationAnchor()); + // Draw outline. + if (false) { + g2.setStroke(getOutlineStroke()); + g2.setPaint(getOutlinePaint()); + g2.draw(hotspot); + } + + // Add info that we have drawn this Annotation. + addEntity(info, hotspot, rendererIndex, getToolTipText(), getURL()); + } +} + +