# HG changeset patch # User Felix Wolfsteller # Date 1327328333 0 # Node ID 10509796611182e9eb47a60f6d4bcbe98ba420a1 # Parent df70f14af981e8803605e5869a515d88d68217e2 Theoretically allow annotations on second y ais. Practically allow Q MainValues on Q Axis in Duration Curves. flys-artifacts/trunk@3750 c6561f87-3c4e-4783-a992-168aeb5c3f6f diff -r df70f14af981 -r 105097966111 flys-artifacts/ChangeLog --- a/flys-artifacts/ChangeLog Mon Jan 23 11:06:06 2012 +0000 +++ b/flys-artifacts/ChangeLog Mon Jan 23 14:18:53 2012 +0000 @@ -1,3 +1,37 @@ +2012-01-23 Felix Wolfsteller + + Fix flys/issue452 (Annotations at second y-axis). + + * src/main/java/de/intevation/flys/artifacts/model/FacetTypes.java: + Added new type (duration_curve.mainvalues.q). + + * doc/conf/themes.xml: Added theme mapping for new facet type. + + * src/main/java/de/intevation/flys/artifacts/MainValuesArtifact.java: + Create another Facet. + + * doc/conf/artifacts/winfo.xml: Added new facet type to compatibility + list. + + * src/main/java/de/intevation/flys/exports/DurationCurveGenerator.java: + Handle new Facet. + + * src/main/java/de/intevation/flys/jfree/StickyAxisAnnotation.java: + Added field to be able to remember which axis to stick to. + + * src/main/java/de/intevation/flys/artifacts/model/MainValuesQFacet.java: + Tell Annotations to stick to Q axis in the special duration_curve + environment. + + * src/main/java/de/intevation/flys/exports/XYChartGenerator.java: + (AxisDataset): Added plotAxisIndex to now have a + two-way-association. + Tell own axisDatasets to which 'jfreechart'-axis they are assigned. + Evaluate which axis the StickyAxisAnnotations should be sticked to, + and calculate text and line positions accordingly. + Removed junk. + + 2012-01-23 Felix Wolfsteller Fix compilation. diff -r df70f14af981 -r 105097966111 flys-artifacts/doc/conf/artifacts/winfo.xml --- a/flys-artifacts/doc/conf/artifacts/winfo.xml Mon Jan 23 11:06:06 2012 +0000 +++ b/flys-artifacts/doc/conf/artifacts/winfo.xml Mon Jan 23 14:18:53 2012 +0000 @@ -189,7 +189,7 @@ - + diff -r df70f14af981 -r 105097966111 flys-artifacts/doc/conf/themes.xml --- a/flys-artifacts/doc/conf/themes.xml Mon Jan 23 11:06:06 2012 +0000 +++ b/flys-artifacts/doc/conf/themes.xml Mon Jan 23 14:18:53 2012 +0000 @@ -918,6 +918,7 @@ + diff -r df70f14af981 -r 105097966111 flys-artifacts/src/main/java/de/intevation/flys/artifacts/MainValuesArtifact.java --- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/MainValuesArtifact.java Mon Jan 23 11:06:06 2012 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/MainValuesArtifact.java Mon Jan 23 14:18:53 2012 +0000 @@ -78,6 +78,13 @@ logger.debug("MainValuesArtifact.setup"); state = new StaticState(STATIC_STATE_NAME); + Facet qfacet0 = new MainValuesQFacet( + DURATION_MAINVALUES_Q, + Resources.getMsg( + callMeta, + "facet.discharge_curves.mainvalues.q", + "facet.discharge_curves.mainvalues.q"), + false); Facet qfacet1 = new MainValuesQFacet( COMPUTED_DISCHARGE_MAINVALUES_Q, Resources.getMsg( @@ -108,6 +115,7 @@ true); List fs = new ArrayList(); + fs.add(qfacet0); fs.add(qfacet1); fs.add(qfacet2); fs.add(wfacet1); diff -r df70f14af981 -r 105097966111 flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/FacetTypes.java --- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/FacetTypes.java Mon Jan 23 11:06:06 2012 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/FacetTypes.java Mon Jan 23 14:18:53 2012 +0000 @@ -76,6 +76,7 @@ String DURATION_W = "duration_curve.w"; String DURATION_Q = "duration_curve.q"; + String DURATION_MAINVALUES_Q = "duration_curve.mainvalues.q"; String STATIC_WQ = "other.wq"; String STATIC_WQ_ANNOTATIONS = "other.wq.annotations"; diff -r df70f14af981 -r 105097966111 flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/MainValuesQFacet.java --- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/MainValuesQFacet.java Mon Jan 23 11:06:06 2012 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/MainValuesQFacet.java Mon Jan 23 14:18:53 2012 +0000 @@ -13,6 +13,8 @@ import de.intevation.flys.jfree.FLYSAnnotation; import de.intevation.flys.jfree.StickyAxisAnnotation; +import de.intevation.flys.exports.DurationCurveGenerator; + /** * Facet to show Main Q Values. * TODO Join with W implementation. @@ -27,9 +29,9 @@ /** Trivial Constructor. */ public MainValuesQFacet(String name, String description, boolean atGauge) { this.description = description; - this.name = name; - this.index = 0; - this.isAtGauge = atGauge; + this.name = name; + this.index = 0; + this.isAtGauge = atGauge; } @@ -45,14 +47,26 @@ public Object getData(Artifact artifact, CallContext context) { MainValuesArtifact mvArtifact = (MainValuesArtifact) artifact; - List qs = mvArtifact.getMainValuesQ(isAtGauge); + List qs = mvArtifact.getMainValuesQ(isAtGauge); List xy = new ArrayList(); - for (NamedDouble q: qs) { - xy.add(new StickyAxisAnnotation( - q.getName(), - (float) q.getValue(), - StickyAxisAnnotation.SimpleAxis.X_AXIS)); + // Rather specific case, Q-Annotations at a maybe second yaxis. + if (this.name.equals(DURATION_MAINVALUES_Q)) { + for (NamedDouble q: qs) { + xy.add(new StickyAxisAnnotation( + q.getName(), + (float) q.getValue(), + StickyAxisAnnotation.SimpleAxis.Y_AXIS, + DurationCurveGenerator.YAXIS.Q.idx)); + } + } + else { + for (NamedDouble q: qs) { + xy.add(new StickyAxisAnnotation( + q.getName(), + (float) q.getValue(), + StickyAxisAnnotation.SimpleAxis.X_AXIS)); + } } return new FLYSAnnotation(description, xy); diff -r df70f14af981 -r 105097966111 flys-artifacts/src/main/java/de/intevation/flys/exports/DurationCurveGenerator.java --- a/flys-artifacts/src/main/java/de/intevation/flys/exports/DurationCurveGenerator.java Mon Jan 23 11:06:06 2012 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/DurationCurveGenerator.java Mon Jan 23 14:18:53 2012 +0000 @@ -36,7 +36,7 @@ public static enum YAXIS { W(0), Q(1); - protected int idx; + public int idx; private YAXIS(int c) { idx = c; } @@ -182,7 +182,7 @@ else if (name.equals(DURATION_Q)) { doQOut((WQDay) artifactFacet.getData(context), attr, visible); } - else if (name.equals(COMPUTED_DISCHARGE_MAINVALUES_Q) + else if (name.equals(DURATION_MAINVALUES_Q) || name.equals(MAINVALUES_Q) || name.equals(COMPUTED_DISCHARGE_MAINVALUES_W) || name.equals(MAINVALUES_W) diff -r df70f14af981 -r 105097966111 flys-artifacts/src/main/java/de/intevation/flys/exports/XYChartGenerator.java --- a/flys-artifacts/src/main/java/de/intevation/flys/exports/XYChartGenerator.java Mon Jan 23 11:06:06 2012 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/XYChartGenerator.java Mon Jan 23 14:18:53 2012 +0000 @@ -90,6 +90,8 @@ protected List datasets; /** Range to use to include all given datasets. */ protected Range range; + /** Index of axis in plot. */ + protected int plotAxisIndex; /** Create AxisDataset. */ public AxisDataset(int symb) { @@ -136,6 +138,16 @@ public boolean isEmpty() { return this.datasets.isEmpty(); } + + /** Set the 'real' axis index that this axis is mapped to. */ + public void setPlotAxisIndex(int axisIndex) { + this.plotAxisIndex = axisIndex; + } + + /** Get the 'real' axis index that this axis is mapped to. */ + public int getPlotAxisIndex() { + return this.plotAxisIndex; + } } // class AxisDataset @@ -618,6 +630,7 @@ axisDataset.isArea((XYSeriesCollection)dataset)); datasetIndex++; } + axisDataset.setPlotAxisIndex(axisIndex); axisIndex++; } } @@ -626,8 +639,9 @@ /** * Registers an area to be drawn. - * @param lower the lower curve to draw the area from. - * @param upper the upper curve to draw the ara from. + * @param area Area to be drawn. + * @param index 'axis index' + * @param visible Whether or not to be visible (important for range calculations). */ public void addAreaSeries(StyledAreaSeriesCollection area, int index, boolean visible) { if (area == null) { @@ -655,7 +669,7 @@ * Add given series if visible, if not visible adjust ranges (such that * all points in data would be plotted once visible). * @param series the dataseries to include in plot. - * @param index index of the series and of its axis. + * @param index ('symbolic') index of the series and of its axis. * @param visible whether or not the data should be plotted. */ public void addAxisSeries(XYSeries series, int index, boolean visible) { @@ -982,62 +996,6 @@ } - /** - * Get "lowest" X Value for first axis. This value is exactly at the - * border of the plot. - * @return lowest value on first 'x'-axis. - */ - protected double getLowestXValue(XYPlot plot) { - ValueAxis axis = plot.getDomainAxis(); - if (axis == null) { - logger.warn("No X-Axis to find lowest value for."); - } - return axis.getRange().getLowerBound(); - } - - - /** - * Get "lowest" X Value for first axis. This value is exactly at the - * border of the plot. - * @return highest value on first 'x'-axis. - */ - protected double getUppestXValue(XYPlot plot) { - ValueAxis axis = plot.getDomainAxis(); - if (axis == null) { - logger.warn("No first Y-Axis to find uppest value for."); - } - return axis.getRange().getUpperBound(); - } - - - /** - * Get "lowest" Y Value for first axis. This value is exactly at the - * border of the plot. - * @return lowest value on first 'y'-axis. - */ - protected double getLowestYValue(XYPlot plot) { - ValueAxis yaxis = plot.getRangeAxis(0); - if (yaxis == null) { - logger.warn("No first Y-Axis to find lowest value for."); - } - return yaxis.getRange().getLowerBound(); - } - - - /** - * Get "lowest" Y Value for first axis. This value is exactly at the - * border of the plot. - * @return highest value on first 'y'-axis. - */ - protected double getUppestYValue(XYPlot plot) { - ValueAxis yaxis = plot.getRangeAxis(0); - if (yaxis == null) { - logger.warn("No first Y-Axis to find uppest value for."); - } - return yaxis.getRange().getUpperBound(); - } - - /** Get color for hyk zones by their type (which is the name). */ public Paint colorForHYKZone(String zoneName) { if (zoneName.startsWith("R")) { @@ -1081,6 +1039,8 @@ XYLineAnnotation lineAnnotation = null; XYTextAnnotation textAnnotation = null; + int rendererIndex = 0; + if (annotation.atX()) { textAnnotation = new CollisionFreeXYTextAnnotation( annotation.getText(), annotation.getPos(), area.ofGround(TEXT_OFF)); @@ -1091,25 +1051,69 @@ lineAnnotation = new XYLineAnnotation(annotation.getPos(), area.atGround(), annotation.getPos(), area.ofGround(LINE_OFF), new BasicStroke(lineStyle.getWidth()),lineStyle.getColor()); + textAnnotation.setRotationAnchor(TextAnchor.CENTER_LEFT); + textAnnotation.setTextAnchor(TextAnchor.CENTER_LEFT); } else { lineAnnotation = new XYLineAnnotation(annotation.getPos(), area.atGround(), annotation.getPos(), area.ofGround(LINE_OFF)); + textAnnotation.setRotationAnchor(TextAnchor.CENTER_LEFT); + textAnnotation.setTextAnchor(TextAnchor.CENTER_LEFT); } } else { - textAnnotation = new CollisionFreeXYTextAnnotation( - annotation.getText(), area.ofLeft(TEXT_OFF), annotation.getPos()); - // Style the line. - if (lineStyle != null) { - lineAnnotation = new XYLineAnnotation(area.atLeft(), - annotation.getPos(), area.ofLeft(LINE_OFF), - annotation.getPos(), new BasicStroke(lineStyle.getWidth()), - lineStyle.getColor()); + // 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). + AxisDataset dataset = this.datasets.get( + new Integer(annotation.getAxisSymbol())); + if (dataset == null) { + logger.warn("Annotation should stick to unfindable y-axis: " + + annotation.getAxisSymbol()); + rendererIndex = 0; } else { - lineAnnotation = new XYLineAnnotation(area.atLeft(), - annotation.getPos(), area.ofLeft(LINE_OFF), annotation.getPos()); + rendererIndex = dataset.getPlotAxisIndex(); + } + + 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. + Area area2 = new Area(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); + // Style the line. + if (lineStyle != null) { + lineAnnotation = new XYLineAnnotation(area2.ofRight(LINE_OFF), + annotation.getPos(), area2.atRight(), + annotation.getPos(), new BasicStroke(lineStyle.getWidth()), + lineStyle.getColor()); + } + else { + lineAnnotation = new XYLineAnnotation(area2.atRight(), + annotation.getPos(), area2.ofRight(LINE_OFF), annotation.getPos()); + } + } + else { + textAnnotation = new CollisionFreeXYTextAnnotation( + annotation.getText(), area.ofLeft(TEXT_OFF), annotation.getPos()); + textAnnotation.setRotationAnchor(TextAnchor.CENTER_LEFT); + textAnnotation.setTextAnchor(TextAnchor.CENTER_LEFT); + // Style the line. + if (lineStyle != null) { + lineAnnotation = new XYLineAnnotation(area.atLeft(), + annotation.getPos(), area.ofLeft(LINE_OFF), + annotation.getPos(), new BasicStroke(lineStyle.getWidth()), + lineStyle.getColor()); + } + else { + lineAnnotation = new XYLineAnnotation(area.atLeft(), + annotation.getPos(), area.ofLeft(LINE_OFF), annotation.getPos()); + } } } @@ -1119,12 +1123,9 @@ } // Add the Annotations to renderer. - textAnnotation.setRotationAnchor(TextAnchor.CENTER_LEFT); - textAnnotation.setTextAnchor(TextAnchor.CENTER_LEFT); - - plot.getRenderer().addAnnotation(textAnnotation, + plot.getRenderer(rendererIndex).addAnnotation(textAnnotation, org.jfree.ui.Layer.BACKGROUND); - plot.getRenderer().addAnnotation(lineAnnotation, + plot.getRenderer(rendererIndex).addAnnotation(lineAnnotation, org.jfree.ui.Layer.BACKGROUND); } @@ -1635,11 +1636,21 @@ this.yRange = rangeY; } + public Area(ValueAxis axisX, ValueAxis axisY) { + this.xRange = axisX.getRange(); + this.yRange = axisY.getRange(); + } + public double ofLeft(double percent) { return xRange.getLowerBound() + xRange.getLength() * percent; } + public double ofRight(double percent) { + return xRange.getUpperBound() + - xRange.getLength() * percent; + } + public double ofGround(double percent) { return yRange.getLowerBound() + yRange.getLength() * percent; @@ -1653,6 +1664,10 @@ return yRange.getLowerBound(); } + public double atRight() { + return xRange.getUpperBound(); + } + public double atLeft() { return xRange.getLowerBound(); } diff -r df70f14af981 -r 105097966111 flys-artifacts/src/main/java/de/intevation/flys/jfree/StickyAxisAnnotation.java --- a/flys-artifacts/src/main/java/de/intevation/flys/jfree/StickyAxisAnnotation.java Mon Jan 23 11:06:06 2012 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/jfree/StickyAxisAnnotation.java Mon Jan 23 14:18:53 2012 +0000 @@ -21,6 +21,9 @@ Y_AXIS /** Usually "vertical". */ } + /** The "symbolic" integer representing which axis to stick to. */ + protected int axisSymbol; + /** Which axis to stick to. */ protected SimpleAxis stickyAxis = SimpleAxis.X_AXIS; @@ -49,9 +52,16 @@ */ public StickyAxisAnnotation(String text, float pos, SimpleAxis stickAxis ) { + this(text, pos, stickAxis, 0); + } + + public StickyAxisAnnotation(String text, float pos, SimpleAxis stickAxis, + int axisSymbol + ) { setStickyAxis(stickAxis); this.text = text; this.pos = pos; + this.axisSymbol = axisSymbol; } @@ -81,5 +91,9 @@ public String getText() { return this.text; } + + public int getAxisSymbol() { + return this.axisSymbol; + } } // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :