# HG changeset patch # User Tom Gottfried # Date 1412075035 -7200 # Node ID 42b25829406752dc8f02a4d258bb58d773b1c008 # Parent d786b6a852c1cd52d710a593e4bcc96c1d95ffc3 Remove duplication of AnnotationHelper-code in ChartGenerator. diff -r d786b6a852c1 -r 42b258294067 artifacts/src/main/java/org/dive4elements/river/exports/ChartGenerator.java --- a/artifacts/src/main/java/org/dive4elements/river/exports/ChartGenerator.java Tue Sep 30 11:52:17 2014 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/exports/ChartGenerator.java Tue Sep 30 13:03:55 2014 +0200 @@ -151,9 +151,6 @@ } // end of YAxisWalker interface - - - /** * Default constructor that initializes internal data structures. */ @@ -173,312 +170,6 @@ annotations.add(annotation); } - /** - * Add a text and a line annotation. - * @param area convenience to determine positions in plot. - * @param theme (optional) theme document - */ - protected void addStickyAnnotation( - StickyAxisAnnotation annotation, - XYPlot plot, - ChartArea area, - LineStyle lineStyle, - TextStyle textStyle, - ThemeDocument theme - ) { - // OPTIMIZE pre-calculate area-related values - final float TEXT_OFF = 0.03f; - - XYLineAnnotation lineAnnotation = null; - XYTextAnnotation textAnnotation = null; - - int rendererIndex = 0; - - if (annotation.atX()) { - textAnnotation = new CollisionFreeXYTextAnnotation( - annotation.getText(), annotation.getPos(), area.ofGround(TEXT_OFF)); - // OPTIMIZE externalize the calculation involving PI. - //textAnnotation.setRotationAngle(270f*Math.PI/180f); - lineAnnotation = createGroundStickAnnotation( - area, annotation.getPos(), lineStyle); - textAnnotation.setRotationAnchor(TextAnchor.CENTER_LEFT); - textAnnotation.setTextAnchor(TextAnchor.CENTER_LEFT); - } - else { - // Do the more complicated case where we stick to the Y-Axis. - // There is one nasty case (duration curves, where annotations - // might stick to the second y-axis). - // FIXME: Remove dependency to XYChartGenerator here - AxisDataset dataset = getAxisDataset( - new Integer(annotation.getAxisSymbol())); - if (dataset == null) { - log.warn("Annotation should stick to unfindable y-axis: " - + annotation.getAxisSymbol()); - rendererIndex = 0; - } - else { - rendererIndex = dataset.getPlotAxisIndex(); - } - - // Stick to the "right" (opposed to left) Y-Axis. - if (rendererIndex != 0) { - // OPTIMIZE: Pass a different area to this function, - // do the adding to renderer outside (let this - // function return the annotations). - // Note that this path is travelled rarely. - ChartArea area2 = new ChartArea(plot.getDomainAxis(), plot.getRangeAxis(rendererIndex)); - textAnnotation = new CollisionFreeXYTextAnnotation( - annotation.getText(), area2.ofRight(TEXT_OFF), annotation.getPos()); - textAnnotation.setRotationAnchor(TextAnchor.CENTER_RIGHT); - textAnnotation.setTextAnchor(TextAnchor.CENTER_RIGHT); - lineAnnotation = createRightStickAnnotation( - area2, annotation.getPos(), lineStyle); - if (!Float.isNaN(annotation.getHitPoint()) && theme != null) { - // New line annotation to hit curve. - if (theme.parseShowVerticalLine()) { - XYLineAnnotation hitLineAnnotation = - createStickyLineAnnotation( - StickyAxisAnnotation.SimpleAxis.X_AXIS, - annotation.getHitPoint(), annotation.getPos(),// annotation.getHitPoint(), - area2, lineStyle); - plot.getRenderer(rendererIndex).addAnnotation(hitLineAnnotation, - org.jfree.ui.Layer.BACKGROUND); - } - if (theme.parseShowHorizontalLine()) { - XYLineAnnotation lineBackAnnotation = - createStickyLineAnnotation( - StickyAxisAnnotation.SimpleAxis.Y_AXIS2, - annotation.getPos(), annotation.getHitPoint(), - area2, lineStyle); - plot.getRenderer(rendererIndex).addAnnotation(lineBackAnnotation, - org.jfree.ui.Layer.BACKGROUND); - } - } - } - else { // Stick to the left y-axis. - textAnnotation = new CollisionFreeXYTextAnnotation( - annotation.getText(), area.ofLeft(TEXT_OFF), annotation.getPos()); - textAnnotation.setRotationAnchor(TextAnchor.CENTER_LEFT); - textAnnotation.setTextAnchor(TextAnchor.CENTER_LEFT); - lineAnnotation = createLeftStickAnnotation(area, annotation.getPos(), lineStyle); - if (!Float.isNaN(annotation.getHitPoint()) && theme != null) { - // New line annotation to hit curve. - if (theme.parseShowHorizontalLine()) { - XYLineAnnotation hitLineAnnotation = - createStickyLineAnnotation( - StickyAxisAnnotation.SimpleAxis.Y_AXIS, - annotation.getPos(), annotation.getHitPoint(), - area, lineStyle); - plot.getRenderer(rendererIndex).addAnnotation(hitLineAnnotation, - org.jfree.ui.Layer.BACKGROUND); - } - if (theme.parseShowVerticalLine()) { - XYLineAnnotation lineBackAnnotation = - createStickyLineAnnotation( - StickyAxisAnnotation.SimpleAxis.X_AXIS, - annotation.getHitPoint(), annotation.getPos(), - area, lineStyle); - plot.getRenderer(rendererIndex).addAnnotation(lineBackAnnotation, - org.jfree.ui.Layer.BACKGROUND); - } - } - } - } - - // Style the text. - if (textStyle != null) { - textStyle.apply(textAnnotation); - } - - // Add the Annotations to renderer. - plot.getRenderer(rendererIndex).addAnnotation(textAnnotation, - org.jfree.ui.Layer.FOREGROUND); - plot.getRenderer(rendererIndex).addAnnotation(lineAnnotation, - org.jfree.ui.Layer.FOREGROUND); - } - - /** - * Create annotation that sticks to "ground" (X) axis. - * @param area helper to calculate coordinates - * @param pos one-dimensional position (distance from axis) - * @param lineStyle the line style to use for the line. - */ - protected static XYLineAnnotation createGroundStickAnnotation( - ChartArea area, float pos, LineStyle lineStyle - ) { - // Style the line. - if (lineStyle != null) { - return new XYLineAnnotation( - pos, area.atGround(), - pos, area.ofGround(ANNOTATIONS_AXIS_OFFSET), - new BasicStroke(lineStyle.getWidth()),lineStyle.getColor()); - } - else { - return new XYLineAnnotation( - pos, area.atGround(), - pos, area.ofGround(ANNOTATIONS_AXIS_OFFSET)); - } - } - - - /** - * Create annotation that sticks to the second Y axis ("right"). - * @param area helper to calculate coordinates - * @param pos one-dimensional position (distance from axis) - * @param lineStyle the line style to use for the line. - */ - protected static XYLineAnnotation createRightStickAnnotation( - ChartArea area, float pos, LineStyle lineStyle - ) { - // Style the line. - if (lineStyle != null) { - return new XYLineAnnotation( - area.ofRight(ANNOTATIONS_AXIS_OFFSET), pos, - area.atRight(), pos, - new BasicStroke(lineStyle.getWidth()), lineStyle.getColor()); - } - else { - return new XYLineAnnotation( - area.atRight(), pos, - area.ofRight(ANNOTATIONS_AXIS_OFFSET), pos); - } - } - - - /** - * Create annotation that sticks to the first Y axis ("left"). - * @param area helper to calculate coordinates - * @param pos one-dimensional position (distance from axis) - * @param lineStyle the line style to use for the line. - */ - protected static XYLineAnnotation createLeftStickAnnotation( - ChartArea area, float pos, LineStyle lineStyle - ) { - // Style the line. - if (lineStyle != null) { - return new XYLineAnnotation( - area.atLeft(), pos, - area.ofLeft(ANNOTATIONS_AXIS_OFFSET), pos, - new BasicStroke(lineStyle.getWidth()), lineStyle.getColor()); - } - else { - return new XYLineAnnotation( - area.atLeft(), pos, - area.ofLeft(ANNOTATIONS_AXIS_OFFSET), pos); - } - } - - - /** - * Create a line from a axis to a given point. - * @param axis The "simple" axis. - * @param fromD1 from-location in first dimension. - * @param toD2 to-location in second dimension. - * @param area helper to calculate offsets. - * @param lineStyle optional line style. - */ - protected static XYLineAnnotation createStickyLineAnnotation( - StickyAxisAnnotation.SimpleAxis axis, float fromD1, float toD2, - ChartArea area, LineStyle lineStyle - ) { - double anchorX1 = 0d, anchorX2 = 0d, anchorY1 = 0d, anchorY2 = 0d; - switch(axis) { - case X_AXIS: - anchorX1 = fromD1; - anchorX2 = fromD1; - anchorY1 = area.atGround(); - anchorY2 = toD2; - break; - case Y_AXIS: - anchorX1 = area.atLeft(); - anchorX2 = toD2; - anchorY1 = fromD1; - anchorY2 = fromD1; - break; - case Y_AXIS2: - anchorX1 = area.atRight(); - anchorX2 = toD2; - anchorY1 = fromD1; - anchorY2 = fromD1; - break; - } - // Style the line. - if (lineStyle != null) { - return new XYLineAnnotation( - anchorX1, anchorY1, - anchorX2, anchorY2, - new BasicStroke(lineStyle.getWidth()), lineStyle.getColor()); - } - else { - return new XYLineAnnotation( - anchorX1, anchorY1, - anchorX2, anchorY2); - } - } - - /** - * Add the annotations (Sticky, Text and hyk zones) stored - * in the annotations field. - * @param plot Plot to add annotations to. - */ - protected void addAnnotationsToRenderer(XYPlot plot) { - log.debug("addAnnotationsToRenderer"); - - if (annotations == null || annotations.isEmpty()) { - log.debug("addAnnotationsToRenderer: no annotations."); - return; - } - - // OPTMIMIZE: Pre-calculate positions - ChartArea area = new ChartArea( - plot.getDomainAxis(0), - plot.getRangeAxis()); - - // Walk over all Annotation sets. - for (RiverAnnotation fa: annotations) { - - // Access text styling, if any. - ThemeDocument theme = fa.getTheme(); - TextStyle textStyle = null; - LineStyle lineStyle = null; - - // Get Themeing information and add legend item. - if (theme != null) { - textStyle = theme.parseComplexTextStyle(); - lineStyle = theme.parseComplexLineStyle(); - if (fa.getLabel() != null) { - LegendItemCollection lic = new LegendItemCollection(); - LegendItemCollection old = plot.getFixedLegendItems(); - lic.add(createLegendItem(theme, fa.getLabel())); - // (Re-)Add prior legend entries. - if (old != null) { - old.addAll(lic); - } - else { - old = lic; - } - plot.setFixedLegendItems(old); - } - } - - // The 'Sticky' Annotations (at axis, with line and text). - for (StickyAxisAnnotation sta: fa.getAxisTextAnnotations()) { - addStickyAnnotation( - sta, plot, area, lineStyle, textStyle, theme); - } - - // Other Text Annotations (e.g. labels of (manual) points). - for (XYTextAnnotation ta: fa.getTextAnnotations()) { - // Style the text. - if (textStyle != null) { - textStyle.apply(ta); - } - ta.setY(area.above(0.05d, ta.getY())); - plot.getRenderer().addAnnotation(ta, org.jfree.ui.Layer.FOREGROUND); - } - } - } - /** * This method needs to be implemented by concrete subclasses to create new diff -r d786b6a852c1 -r 42b258294067 artifacts/src/main/java/org/dive4elements/river/exports/TimeseriesChartGenerator.java --- a/artifacts/src/main/java/org/dive4elements/river/exports/TimeseriesChartGenerator.java Tue Sep 30 11:52:17 2014 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/exports/TimeseriesChartGenerator.java Tue Sep 30 13:03:55 2014 +0200 @@ -14,6 +14,7 @@ import org.dive4elements.river.jfree.CollisionFreeXYTextAnnotation; import org.dive4elements.river.jfree.DoubleBounds; import org.dive4elements.river.jfree.RiverAnnotation; +import org.dive4elements.river.jfree.AnnotationHelper; import org.dive4elements.river.jfree.StyledTimeSeries; import org.dive4elements.river.jfree.TimeBounds; import org.dive4elements.river.jfree.AxisDataset; @@ -124,7 +125,11 @@ consumeAxisSettings(plot); - addAnnotationsToRenderer(plot); + AnnotationHelper.addAnnotationsToRenderer( + annotations, + plot, + getChartSettings(), + datasets); addLogo(plot); aggregateLegendEntries(plot); return chart;