Mercurial > dive4elements > river
view artifacts/src/main/java/org/dive4elements/river/jfree/AnnotationHelper.java @ 7088:41567bf1e131 generator-refactoring
Removed obsolete imports.
author | Sascha L. Teichmann <teichmann@intevation.de> |
---|---|
date | Sun, 22 Sep 2013 21:29:35 +0200 |
parents | 35aabc86566d |
children | 432addd00687 |
line wrap: on
line source
/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde * Software engineering by Intevation GmbH * * This file is Free Software under the GNU AGPL (>=v3) * and comes with ABSOLUTELY NO WARRANTY! Check out the * documentation coming with Dive4Elements River for details. */ package org.dive4elements.river.jfree; import org.dive4elements.river.themes.ThemeDocument; import java.util.List; import java.util.Map; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Font; import org.jfree.ui.TextAnchor; import org.jfree.chart.plot.XYPlot; import org.jfree.chart.LegendItem; import org.jfree.chart.LegendItemCollection; import org.jfree.chart.annotations.XYTextAnnotation; import org.jfree.chart.annotations.XYLineAnnotation; import org.dive4elements.river.themes.LineStyle; import org.dive4elements.river.themes.TextStyle; import org.dive4elements.river.exports.ChartSettings; import org.dive4elements.river.exports.LegendSection; import org.dive4elements.river.exports.ChartArea; import org.apache.log4j.Logger; /** Annotation helper class, handles plotting of annotations. */ public class AnnotationHelper { private static final Logger logger = Logger.getLogger(AnnotationHelper.class); protected static float ANNOTATIONS_AXIS_OFFSET = 0.02f; /* arr this would be better in chartsettings */ public static final int DEFAULT_FONT_SIZE = 12; public static final String DEFAULT_FONT_NAME = "Tahoma"; /** * Add annotations (Sticky, Text and hyk zones) to a plot. * @param annotations Annotations to add * @param plot Plot to add annotations to. * @param settings ChartSettings object for settings. */ public static void addAnnotationsToRenderer(List<RiverAnnotation> annotations, XYPlot plot, ChartSettings settings, Map<Integer, AxisDataset> datasets) { logger.debug("addAnnotationsToRenderer"); if (annotations == null || annotations.isEmpty()) { logger.debug("addAnnotationsToRenderer: no annotations."); return; } // OPTMIMIZE: Pre-calculate positions ChartArea area = new ChartArea( plot.getDomainAxis(0).getRange(), plot.getRangeAxis().getRange()); // 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) { // Legend handling, maybe misplaced? LegendItemCollection lic = new LegendItemCollection(); LegendItemCollection old = plot.getFixedLegendItems(); Color color = theme.parseLineColorField(); if (color == null) { color = Color.BLACK; } LegendItem newItem = new LegendItem(fa.getLabel(), color); LegendSection ls = (settings != null ? settings.getLegendSection() : null); newItem.setLabelFont (new Font( DEFAULT_FONT_NAME, Font.PLAIN, ls != null ? ls.getFontSize() : null) ); lic.add(newItem); // (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, datasets.get(new Integer(sta.getAxisSymbol()))); } // 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); } } } /** * Add a text and a line annotation. * @param area convenience to determine positions in plot. * @param theme (optional) theme document */ public static void addStickyAnnotation( StickyAxisAnnotation annotation, XYPlot plot, ChartArea area, LineStyle lineStyle, TextStyle textStyle, ThemeDocument theme, AxisDataset dataset ) { // 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). if (dataset == null) { logger.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. */ public 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. */ public 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. */ public 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. */ public 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); } } };