Mercurial > dive4elements > river
comparison artifacts/src/main/java/org/dive4elements/river/exports/fixings/FixWQCurveGenerator.java @ 7691:fa4fbd66e752
(issue1579) Fix axes syncronisation at Gauges
The SyncNumberAxis was completely broken. It only synced
in one direction and even that did not work correctly when
data was added to the axis (and the syncAxis rescaled but
forgot the old axis) then there were lots of ways to bypass
that scaling. And i also think the trans calculation was wrong.
It has been replaced by a "mostly" simple method to just keep
the W in M and W in CM+Datum axes in sync. I say "Mostly" because
it had to deal with the Bounds interface.
author | Andre Heinecke <aheinecke@intevation.de> |
---|---|
date | Fri, 13 Dec 2013 19:03:00 +0100 |
parents | 4dbbdf0c8b2c |
children | 75ef6963f1c9 |
comparison
equal
deleted
inserted
replaced
7690:4bbd222e6b7f | 7691:fa4fbd66e752 |
---|---|
45 import org.dive4elements.river.artifacts.model.fixings.QWD; | 45 import org.dive4elements.river.artifacts.model.fixings.QWD; |
46 import org.dive4elements.river.artifacts.model.fixings.QWI; | 46 import org.dive4elements.river.artifacts.model.fixings.QWI; |
47 import org.dive4elements.river.artifacts.resources.Resources; | 47 import org.dive4elements.river.artifacts.resources.Resources; |
48 import org.dive4elements.river.exports.ChartGenerator; | 48 import org.dive4elements.river.exports.ChartGenerator; |
49 import org.dive4elements.river.exports.DischargeCurveGenerator; | 49 import org.dive4elements.river.exports.DischargeCurveGenerator; |
50 import org.dive4elements.river.exports.SyncNumberAxis; | |
51 import org.dive4elements.river.exports.StyledSeriesBuilder; | 50 import org.dive4elements.river.exports.StyledSeriesBuilder; |
52 import org.dive4elements.river.jfree.CollisionFreeXYTextAnnotation; | 51 import org.dive4elements.river.jfree.CollisionFreeXYTextAnnotation; |
53 import org.dive4elements.river.jfree.RiverAnnotation; | 52 import org.dive4elements.river.jfree.RiverAnnotation; |
54 import org.dive4elements.river.jfree.JFreeUtil; | 53 import org.dive4elements.river.jfree.JFreeUtil; |
55 import org.dive4elements.river.jfree.StickyAxisAnnotation; | 54 import org.dive4elements.river.jfree.StickyAxisAnnotation; |
58 import org.dive4elements.river.model.River; | 57 import org.dive4elements.river.model.River; |
59 import org.dive4elements.river.themes.ThemeDocument; | 58 import org.dive4elements.river.themes.ThemeDocument; |
60 import org.dive4elements.river.utils.RiverUtils; | 59 import org.dive4elements.river.utils.RiverUtils; |
61 import org.dive4elements.river.java2d.ShapeUtils; | 60 import org.dive4elements.river.java2d.ShapeUtils; |
62 | 61 |
62 import org.dive4elements.river.jfree.Bounds; | |
63 import org.dive4elements.river.jfree.DoubleBounds; | |
64 | |
65 import org.jfree.data.Range; | |
66 | |
63 /** | 67 /** |
64 * Generator for WQ fixing charts. | 68 * Generator for WQ fixing charts. |
65 * @author <a href="mailto:christian.lins@intevation.de">Christian Lins</a> | 69 * @author <a href="mailto:christian.lins@intevation.de">Christian Lins</a> |
66 */ | 70 */ |
67 public class FixWQCurveGenerator | 71 public class FixWQCurveGenerator |
109 | 113 |
110 | 114 |
111 /** Needed to access data to create subtitle. */ | 115 /** Needed to access data to create subtitle. */ |
112 protected D4EArtifact artifact; | 116 protected D4EArtifact artifact; |
113 | 117 |
114 // TODO dupe of ComputedDischargeCurveGenerator | |
115 protected SyncNumberAxis secondYAxis; | |
116 // TODO dupe of ComputedDischargeCurveGenerator | |
117 protected NumberAxis firstYAxis; | |
118 | |
119 | |
120 /** | |
121 * Create Y (range) axis for given index, here with a special axis | |
122 * that depends on other axis (does translation and scaling for | |
123 * special case at gauge in cm). | |
124 */ | |
125 // TODO dupe of ComputedDischargeCurveGenerator | |
126 @Override | |
127 protected NumberAxis createYAxis(int index) { | |
128 logger.debug("createYAxis: " + index); | |
129 if (index == 1) { | |
130 firstYAxis = super.createYAxis(1); | |
131 if (secondYAxis != null) { | |
132 secondYAxis.setProxyAxis(firstYAxis); | |
133 } | |
134 return firstYAxis; | |
135 } | |
136 YAxisWalker walker = getYAxisWalker(); | |
137 | |
138 Font labelFont = new Font( | |
139 DEFAULT_FONT_NAME, | |
140 Font.BOLD, | |
141 getYAxisFontSize(index)); | |
142 | |
143 SyncNumberAxis axis = new SyncNumberAxis( | |
144 walker.getId(index), | |
145 getYAxisLabel(index), | |
146 firstYAxis); | |
147 | |
148 axis.setAutoRangeIncludesZero(false); | |
149 axis.setLabelFont(labelFont); | |
150 axis.setTickLabelFont(labelFont); | |
151 axis.setShift((double)-getCurrentGaugeDatum()); | |
152 | |
153 secondYAxis = axis; | |
154 return axis; | |
155 } | |
156 | |
157 /** Returns value != 0 if the current km is not at a gauge. */ | 118 /** Returns value != 0 if the current km is not at a gauge. */ |
158 public double getCurrentGaugeDatum() { | 119 public double getCurrentGaugeDatum() { |
159 Object ckm = context.getContextValue(CURRENT_KM); | 120 Object ckm = context.getContextValue(CURRENT_KM); |
160 if (ckm != null) { | 121 if (ckm != null) { |
161 return DischargeCurveGenerator.getCurrentGaugeDatum( | 122 return DischargeCurveGenerator.getCurrentGaugeDatum( |
170 protected void adjustAxes(XYPlot plot) { | 131 protected void adjustAxes(XYPlot plot) { |
171 super.adjustAxes(plot); | 132 super.adjustAxes(plot); |
172 if (getCurrentGaugeDatum() != 0d) { | 133 if (getCurrentGaugeDatum() != 0d) { |
173 // Show the W[*m] axis even if there is no data. | 134 // Show the W[*m] axis even if there is no data. |
174 plot.setRangeAxis(1, createYAxis(YAXIS.W.idx)); | 135 plot.setRangeAxis(1, createYAxis(YAXIS.W.idx)); |
175 } | 136 syncWAxisRanges(); |
137 } | |
138 } | |
139 | |
140 // XXX This is a copy of DischargeCurveGenerator syncWAxisRanges | |
141 // even without fancy Q Symetry this class should inherit | |
142 // from there.. | |
143 protected void syncWAxisRanges() { | |
144 // Syncronizes the ranges of both W Axes to make sure | |
145 // that the Data matches for both axes. | |
146 Bounds boundsInMGauge = getYBounds(YAXIS.W.idx); | |
147 Bounds boundsInCM = getYBounds(YAXIS.WCm.idx); | |
148 | |
149 // XXX Q-Symetry: I am assuming here that there can only | |
150 // be a fixed Range for WinM as this is currently the only | |
151 // thing that is configureable. | |
152 Range fixedWinMRange = getRangeForAxisFromSettings( | |
153 getYAxisWalker().getId(YAXIS.W.idx)); | |
154 | |
155 // The combination of Range and Bounds is crazy.. | |
156 if (fixedWinMRange != null) { | |
157 boundsInMGauge = new DoubleBounds(fixedWinMRange.getLowerBound(), | |
158 fixedWinMRange.getUpperBound()); | |
159 } | |
160 | |
161 logger.debug("Syncing Axis Bounds. Bounds W: " + boundsInMGauge.toString() + | |
162 " Bounds Wcm: " + boundsInCM.toString()); | |
163 | |
164 double datum = getCurrentGaugeDatum(); | |
165 | |
166 // Convert boundsInMGauge to Datum+cm | |
167 double convertedLower = ((Double)boundsInMGauge.getLower() - datum) * 100; | |
168 double convertedUpper = ((Double)boundsInMGauge.getUpper() - datum) * 100; | |
169 Bounds convertedBounds = new DoubleBounds(convertedLower, convertedUpper); | |
170 | |
171 // Now combine both Ranges | |
172 boundsInCM = boundsInCM.combine(convertedBounds); | |
173 | |
174 // Recalculate absolute bounds | |
175 boundsInMGauge = new DoubleBounds((Double)boundsInCM.getLower() / 100d + datum, | |
176 (Double)boundsInCM.getUpper() / 100d + datum); | |
177 | |
178 // Set the new combined bounds | |
179 setYBounds(YAXIS.W.idx, boundsInMGauge); | |
180 setYBounds(YAXIS.WCm.idx, boundsInCM); | |
181 logger.debug("Synced Bounds W: " + boundsInMGauge.toString() + | |
182 " Bounds Wcm: " + boundsInCM.toString()); | |
176 } | 183 } |
177 | 184 |
178 @Override | 185 @Override |
179 public void doOut(ArtifactAndFacet aaf, ThemeDocument doc, boolean visible) { | 186 public void doOut(ArtifactAndFacet aaf, ThemeDocument doc, boolean visible) { |
180 logger.debug("doOut: " + aaf.getFacetName()); | 187 logger.debug("doOut: " + aaf.getFacetName()); |