teichmann@5863: /* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde teichmann@5863: * Software engineering by Intevation GmbH teichmann@5863: * teichmann@5994: * This file is Free Software under the GNU AGPL (>=v3) teichmann@5863: * and comes with ABSOLUTELY NO WARRANTY! Check out the teichmann@5994: * documentation coming with Dive4Elements River for details. teichmann@5863: */ teichmann@5863: teichmann@5831: package org.dive4elements.river.exports; ingo@359: teichmann@5831: import org.dive4elements.artifactdatabase.state.ArtifactAndFacet; teichmann@5831: import org.dive4elements.artifactdatabase.state.Facet; teichmann@5867: import org.dive4elements.river.artifacts.D4EArtifact; teichmann@5831: import org.dive4elements.river.artifacts.geom.Lines; teichmann@5831: import org.dive4elements.river.artifacts.model.AreaFacet; teichmann@5831: import org.dive4elements.river.artifacts.model.FacetTypes; teichmann@5831: import org.dive4elements.river.artifacts.model.WKms; teichmann@5831: import org.dive4elements.river.artifacts.model.WQKms; felix@6689: felix@6689: import org.dive4elements.river.exports.process.Processor; felix@6689: import org.dive4elements.river.exports.process.BedDiffHeightYearProcessor; felix@6689: import org.dive4elements.river.exports.process.BedDiffYearProcessor; felix@6689: import org.dive4elements.river.exports.process.BedheightProcessor; teichmann@5831: import org.dive4elements.river.exports.process.WOutProcessor; felix@6689: teichmann@5864: import org.dive4elements.river.jfree.RiverAnnotation; teichmann@5831: import org.dive4elements.river.jfree.StyledAreaSeriesCollection; teichmann@5831: import org.dive4elements.river.jfree.StyledXYSeries; teichmann@6905: import org.dive4elements.river.themes.ThemeDocument; teichmann@5831: import org.dive4elements.river.utils.DataUtil; teichmann@5865: import org.dive4elements.river.utils.RiverUtils; christian@3409: import org.apache.log4j.Logger; christian@3409: import org.jfree.chart.axis.NumberAxis; christian@3409: import org.jfree.chart.axis.ValueAxis; christian@3409: import org.jfree.chart.plot.XYPlot; christian@3409: import org.jfree.data.xy.XYSeries; felix@2664: felix@1035: felix@1035: /** felix@2206: * An OutGenerator that generates longitudinal section curves. ingo@359: * ingo@359: * @author Ingo Weinzierl ingo@359: */ ingo@696: public class LongitudinalSectionGenerator ingo@696: extends XYChartGenerator ingo@696: implements FacetTypes ingo@696: { felix@1953: public enum YAXIS { felix@1931: W(0), felix@3176: D(1), felix@3176: Q(2); felix@1931: protected int idx; felix@1931: private YAXIS(int c) { felix@3176: idx = c; felix@1931: } felix@1931: } felix@1931: felix@1037: /** The logger that is used in this generator. */ ingo@359: private static Logger logger = ingo@359: Logger.getLogger(LongitudinalSectionGenerator.class); ingo@359: felix@1700: /** Key to look up internationalized String for annotations label. */ felix@1041: public static final String I18N_ANNOTATIONS_LABEL = felix@1041: "chart.longitudinal.annotations.label"; felix@1041: felix@1701: /** felix@1701: * Key to look up internationalized String for LongitudinalSection diagrams felix@1701: * titles. felix@1701: */ felix@1701: public static final String I18N_CHART_TITLE = felix@1701: "chart.longitudinal.section.title"; felix@1701: felix@1701: /** felix@1701: * Key to look up internationalized String for LongitudinalSection diagrams felix@1701: * subtitles. felix@1701: */ felix@1701: public static final String I18N_CHART_SUBTITLE = felix@1701: "chart.longitudinal.section.subtitle"; felix@1701: raimund@2159: /** raimund@2159: * Key to look up internationalized String for LongitudinalSection diagrams raimund@2159: * short subtitles. raimund@2159: */ raimund@2159: public static final String I18N_CHART_SHORT_SUBTITLE = raimund@2159: "chart.longitudinal.section.shortsubtitle"; raimund@2159: felix@1701: public static final String I18N_XAXIS_LABEL = felix@1701: "chart.longitudinal.section.xaxis.label"; felix@1701: felix@1701: public static final String I18N_YAXIS_LABEL = felix@1701: "chart.longitudinal.section.yaxis.label"; felix@1701: felix@1701: public static final String I18N_2YAXIS_LABEL = felix@1701: "chart.longitudinal.section.yaxis.second.label"; felix@1701: felix@1701: public static final String I18N_CHART_TITLE_DEFAULT = "W-L\u00e4ngsschnitt"; felix@1701: public static final String I18N_XAXIS_LABEL_DEFAULT = "km"; felix@1701: public static final String I18N_YAXIS_LABEL_DEFAULT = "W [NN + m]"; felix@1701: public static final String I18N_2YAXIS_LABEL_DEFAULT = "Q [m\u00b3/s]"; felix@1701: felix@1953: public final static String I18N_WDIFF_YAXIS_LABEL = felix@1953: "chart.w_differences.yaxis.label"; felix@1953: felix@1953: public final static String I18N_WDIFF_YAXIS_LABEL_DEFAULT = "m"; felix@1953: ingo@359: public LongitudinalSectionGenerator() { ingo@359: super(); ingo@369: } ingo@369: ingo@369: ingo@2000: @Override ingo@2000: protected YAxisWalker getYAxisWalker() { ingo@2000: return new YAxisWalker() { ingo@2000: @Override ingo@2000: public int length() { ingo@2000: return YAXIS.values().length; ingo@2000: } ingo@2000: ingo@2000: @Override ingo@2000: public String getId(int idx) { ingo@2000: YAXIS[] yaxes = YAXIS.values(); ingo@2000: return yaxes[idx].toString(); ingo@2000: } ingo@2000: }; ingo@2000: } ingo@2000: ingo@2000: felix@3621: /** felix@3621: * Return left most data points x value (on first axis). felix@3621: * Overridden because axis could be inverted. felix@3621: */ felix@3621: @Override felix@3621: protected double getLeftX() { felix@3621: if (isInverted()) { felix@3621: return (Double)getXBounds(0).getUpper(); felix@3621: } felix@3621: return (Double)getXBounds(0).getLower(); felix@3621: } felix@3621: felix@3621: felix@3621: /** felix@3621: * Return right most data points x value (on first axis). felix@3621: * Overridden because axis could be inverted. felix@3621: */ felix@3621: @Override felix@3621: protected double getRightX() { felix@3621: if (isInverted()) { felix@3621: return (Double)getXBounds(0).getLower(); felix@3621: } felix@3621: return (Double)getXBounds(0).getUpper(); felix@3621: } felix@3621: felix@1700: felix@1700: /** ingo@2048: * Returns the default title for this chart. ingo@2047: * ingo@2048: * @return the default title for this chart. felix@1700: */ ingo@2047: @Override ingo@2048: public String getDefaultChartTitle() { felix@1701: return msg(I18N_CHART_TITLE, I18N_CHART_TITLE_DEFAULT); felix@1700: } felix@1700: felix@1700: ingo@2047: /** ingo@2048: * Returns the default subtitle for this chart. ingo@2047: * ingo@2048: * @return the default subtitle for this chart. ingo@2047: */ ingo@1989: @Override ingo@2048: protected String getDefaultChartSubtitle() { ingo@1989: double[] dist = getRange(); ingo@1989: raimund@2154: Object[] args = null; raimund@2154: if (dist == null) { raimund@2154: args = new Object[] {getRiverName()}; raimund@2159: return msg(getChartShortSubtitleKey(), "", args); raimund@2154: } raimund@2159: args = new Object[] { raimund@2159: getRiverName(), raimund@2159: dist[0], raimund@2159: dist[1] raimund@2159: }; ingo@1989: return msg(getChartSubtitleKey(), "", args); ingo@1989: } ingo@1989: ingo@1989: felix@1700: /** felix@1700: * Gets key to look up internationalized String for the charts subtitle. felix@1700: * @return key to look up translated subtitle. felix@1700: */ felix@1700: protected String getChartSubtitleKey() { felix@1701: return I18N_CHART_SUBTITLE; felix@1700: } felix@1700: felix@1700: felix@1700: /** sascha@3076: * Gets key to look up internationalized String for the charts short raimund@2159: * subtitle. raimund@2159: * @return key to look up translated subtitle. raimund@2159: */ raimund@2159: protected String getChartShortSubtitleKey() { raimund@2159: return I18N_CHART_SHORT_SUBTITLE; raimund@2159: } raimund@2159: raimund@2159: raimund@2159: /** felix@1700: * Get internationalized label for the x axis. felix@1700: */ ingo@2051: @Override ingo@2051: protected String getDefaultXAxisLabel() { teichmann@5867: D4EArtifact flys = (D4EArtifact) master; ingo@1667: ingo@1667: return msg( felix@1701: I18N_XAXIS_LABEL, felix@1701: I18N_XAXIS_LABEL_DEFAULT, teichmann@5865: new Object[] { RiverUtils.getRiver(flys).getName() }); ingo@369: } ingo@369: ingo@369: felix@1953: @Override ingo@2051: protected String getDefaultYAxisLabel(int index) { ingo@2051: String label = "default"; ingo@2051: ingo@2051: if (index == YAXIS.W.idx) { ingo@2051: label = getWAxisLabel(); ingo@2051: } ingo@2051: else if (index == YAXIS.Q.idx) { ingo@2051: label = msg(getQAxisLabelKey(), getQAxisDefaultLabel()); ingo@2051: } ingo@2051: else if (index == YAXIS.D.idx) { ingo@2051: label = msg(I18N_WDIFF_YAXIS_LABEL, I18N_WDIFF_YAXIS_LABEL_DEFAULT); ingo@2051: } ingo@2051: ingo@2051: return label; felix@1953: } felix@1953: ingo@2051: felix@1700: /** felix@1700: * Get internationalized label for the y axis. felix@1700: */ felix@1953: protected String getWAxisLabel() { teichmann@5867: D4EArtifact flys = (D4EArtifact) master; ingo@1667: teichmann@5865: String unit = RiverUtils.getRiver(flys).getWstUnit().getName(); ingo@1667: ingo@1667: return msg( felix@1701: I18N_YAXIS_LABEL, felix@1701: I18N_YAXIS_LABEL_DEFAULT, ingo@1667: new Object[] { unit }); ingo@369: } ingo@369: ingo@369: felix@1700: /** felix@1931: * Create Axis for given index. felix@1931: * @return axis with according internationalized label. felix@1931: */ felix@1931: @Override felix@1931: protected NumberAxis createYAxis(int index) { ingo@2053: NumberAxis axis = super.createYAxis(index); ingo@1991: felix@1941: // "Q" Axis shall include 0. felix@1941: if (index == YAXIS.Q.idx) { felix@1941: axis.setAutoRangeIncludesZero(true); felix@1941: } felix@1941: else { felix@1941: axis.setAutoRangeIncludesZero(false); felix@1941: } ingo@2053: felix@1931: return axis; felix@1931: } felix@1931: ingo@1991: felix@1931: /** felix@1700: * Get default value for the second Y-Axis' label (if no translation was felix@1700: * found). felix@1700: */ felix@1953: protected String getQAxisDefaultLabel() { felix@1701: return I18N_2YAXIS_LABEL_DEFAULT; felix@1700: } felix@1700: felix@1700: felix@1700: /** felix@1700: * Get key for internationalization of the second Y-Axis' label. felix@1700: */ felix@1953: protected String getQAxisLabelKey() { felix@1701: return I18N_2YAXIS_LABEL; felix@1700: } felix@1700: felix@1700: felix@1700: /** felix@1931: * Trigger inversion. felix@1700: */ felix@1700: @Override ingo@375: protected void adjustAxes(XYPlot plot) { ingo@375: super.adjustAxes(plot); ingo@422: invertXAxis(plot.getDomainAxis()); ingo@422: } ingo@422: ingo@422: ingo@422: /** ingo@422: * This method inverts the x-axis based on the kilometer information of the ingo@422: * selected river. If the head of the river is at kilometer 0, the axis is ingo@422: * not inverted, otherwise it is. ingo@422: * ingo@422: * @param xaxis The domain axis. ingo@422: */ ingo@422: protected void invertXAxis(ValueAxis xaxis) { bjoern@4445: if (isInverted()) { ingo@1692: logger.debug("X-Axis.setInverted(true)"); ingo@422: xaxis.setInverted(true); ingo@422: } ingo@359: } ingo@359: ingo@359: felix@1769: /** felix@1769: * Produce output. felix@3269: * @param artifactAndFacet current facet and artifact. felix@1769: * @param attr theme for facet felix@1769: */ christian@3409: @Override ingo@1684: public void doOut( felix@1944: ArtifactAndFacet artifactAndFacet, teichmann@6905: ThemeDocument attr, felix@1944: boolean visible ingo@1684: ) { felix@1944: String name = artifactAndFacet.getFacetName(); ingo@359: ingo@695: logger.debug("LongitudinalSectionGenerator.doOut: " + name); ingo@695: ingo@695: if (name == null) { ingo@369: logger.error("No facet name for doOut(). No output generated!"); ingo@369: return; ingo@369: } ingo@369: felix@1944: Facet facet = artifactAndFacet.getFacet(); ingo@696: felix@1944: if (facet == null) { ingo@696: return; ingo@369: } ingo@696: felix@6689: WOutProcessor wProcessor = new WOutProcessor(); felix@6689: Processor bedp = new BedheightProcessor(); felix@6689: Processor bdyProcessor = new BedDiffYearProcessor(); felix@6689: Processor bdhyProcessor = new BedDiffHeightYearProcessor(); felix@6689: felix@6689: if (wProcessor.canHandle(name)) { felix@6689: wProcessor.doOut(this, artifactAndFacet, attr, visible, YAXIS.W.idx); felix@6689: } felix@6689: else if (bedp.canHandle(name)) { felix@6689: bedp.doOut(this, artifactAndFacet, attr, visible, YAXIS.W.idx); felix@6689: } felix@6689: else if (bdyProcessor.canHandle(name)) { felix@6689: bdyProcessor.doOut(this, artifactAndFacet, attr, visible, YAXIS.W.idx); felix@6689: } felix@6689: else if (bdhyProcessor.canHandle(name)) { felix@6689: bdhyProcessor.doOut(this, artifactAndFacet, attr, visible, YAXIS.W.idx); ingo@696: } ingo@696: else if (name.equals(LONGITUDINAL_Q)) { ingo@2325: doQOut( ingo@2325: (WQKms) artifactAndFacet.getData(context), ingo@2325: artifactAndFacet, ingo@2325: attr, ingo@2325: visible); ingo@369: } felix@1028: else if (name.equals(LONGITUDINAL_ANNOTATION)) { ingo@2325: doAnnotations( teichmann@5864: (RiverAnnotation) artifactAndFacet.getData(context), ingo@2325: artifactAndFacet, ingo@2325: attr, ingo@2325: visible); felix@1028: } felix@2104: else if (name.equals(STATIC_WQKMS_Q)) { ingo@2325: doQOut( ingo@2325: (WQKms) artifactAndFacet.getData(context), ingo@2325: artifactAndFacet, ingo@2325: attr, ingo@2325: visible); felix@2104: } felix@1769: else if (name.equals(W_DIFFERENCES)) { felix@1769: doWDifferencesOut( felix@1944: (WKms) artifactAndFacet.getData(context), ingo@2325: artifactAndFacet, felix@1769: attr, felix@1769: visible); felix@1769: } felix@2029: else if (FacetTypes.IS.AREA(name)) { ingo@2325: doArea( ingo@2325: artifactAndFacet.getData(context), ingo@2325: artifactAndFacet, felix@2029: attr, felix@2029: visible); felix@2029: } felix@2206: else if (FacetTypes.IS.MANUALPOINTS(name)) { ingo@2325: doPoints( ingo@2325: artifactAndFacet.getData(context), ingo@2325: artifactAndFacet, ingo@2325: attr, ingo@2325: visible, ingo@2325: YAXIS.W.idx); felix@2175: } ingo@369: else { ingo@695: logger.warn("Unknown facet name: " + name); ingo@369: return; ingo@369: } ingo@369: } ingo@369: felix@1769: /** felix@1769: * Add items to dataseries which describes the differences. felix@1769: */ felix@1769: protected void doWDifferencesOut( felix@1769: WKms wkms, ingo@2325: ArtifactAndFacet aandf, teichmann@6905: ThemeDocument theme, felix@1769: boolean visible felix@1769: ) { felix@1769: logger.debug("WDifferencesCurveGenerator.doWDifferencesOut"); felix@1769: if (wkms == null) { felix@1769: logger.warn("No data to add to WDifferencesChart."); felix@1769: return; felix@1769: } felix@1769: ingo@2325: XYSeries series = new StyledXYSeries(aandf.getFacetDescription(), theme); felix@1769: felix@1769: if (logger.isDebugEnabled()) { felix@1769: if (wkms.size() > 0) { felix@1769: logger.debug("Generate series: " + series.getKey()); felix@1769: logger.debug("Start km: " + wkms.getKm(0)); felix@1791: logger.debug("End km: " + wkms.getKm(wkms.size() - 1)); felix@1791: logger.debug("Values : " + wkms.size()); felix@1769: } felix@1769: } felix@1769: felix@1791: StyledSeriesBuilder.addPoints(series, wkms); felix@1769: felix@1931: addAxisSeries(series, YAXIS.D.idx, visible); felix@1769: if (DataUtil.guessWaterIncreasing(wkms.allWs())) { sascha@745: setInverted(true); sascha@745: } ingo@369: } ingo@369: ingo@369: ingo@369: /** ingo@369: * Process the output for Q facets in a longitudinal section curve. ingo@369: * ingo@369: * @param wqkms An array of WQKms values. felix@3269: * @param aandf The facet and artifact. This facet does NOT support any data objects. Use teichmann@5867: * D4EArtifact.getNativeFacet() instead to retrieve a Facet which supports ingo@1712: * data. ingo@924: * @param theme The theme that contains styling information. ingo@1712: * @param visible The visibility of the curve. ingo@369: */ ingo@1712: protected void doQOut( ingo@1712: WQKms wqkms, ingo@2325: ArtifactAndFacet aandf, teichmann@6905: ThemeDocument theme, ingo@1712: boolean visible ingo@1712: ) { ingo@369: logger.debug("LongitudinalSectionGenerator.doQOut"); ingo@369: ingo@2325: XYSeries series = new StyledXYSeries(aandf.getFacetDescription(), theme); ingo@369: felix@3176: StyledSeriesBuilder.addStepPointsKmQ(series, wqkms); ingo@696: felix@1931: addAxisSeries(series, YAXIS.Q.idx, visible); sascha@745: ingo@1692: if (needInvertAxis(wqkms)) { ingo@1692: setInverted(true); ingo@1692: } ingo@1692: } ingo@1692: ingo@1692: /** ingo@1692: * This method determines - taking JFreeCharts auto x value ordering into ingo@1692: * account - if the x axis need to be inverted. Waterlines in these charts ingo@1692: * should decrease. ingo@1692: * felix@3270: * @param wkms The data object that stores the x and y values used for this ingo@1692: * chart. ingo@1692: */ felix@2420: public boolean needInvertAxis(WKms wkms) { felix@2420: boolean wsUp = wkms.guessWaterIncreasing(); felix@2420: boolean kmUp = DataUtil.guessWaterIncreasing(wkms.allKms()); ingo@1692: boolean inv = (wsUp && kmUp) || (!wsUp && !kmUp); ingo@1692: felix@2420: int size = wkms.size(); ingo@1692: ingo@1692: if (logger.isDebugEnabled()) { felix@2420: logger.debug("(Wkms)Values : " + size); ingo@1692: if (size > 0) { felix@2420: logger.debug("Start km: " + wkms.getKm(0)); felix@2420: logger.debug("End km: " + wkms.getKm(size-1)); ingo@1692: } ingo@1692: logger.debug("wsUp: " + wsUp); ingo@1692: logger.debug("kmUp: " + kmUp); ingo@1692: logger.debug("inv: " + inv); ingo@1692: } ingo@1692: ingo@1692: return inv; ingo@369: } ingo@369: ingo@369: felix@1041: /** felix@1041: * Get name of series (displayed in legend). felix@1041: * @return name of the series. felix@1041: */ ingo@448: protected String getSeriesName(WQKms wqkms, String mode) { ingo@448: String name = wqkms.getName(); ingo@448: String prefix = name != null && name.indexOf(mode) >= 0 ? null : mode; ingo@448: ingo@448: return prefix != null && prefix.length() > 0 ingo@448: ? prefix + "(" + name +")" ingo@448: : name; ingo@359: } felix@2029: felix@2029: felix@2104: /** Look up the axis identifier for a given facet type. */ felix@2104: public int axisIdxForFacet(String facetName) { felix@2104: if (FacetTypes.IS.W(facetName)) { felix@2104: return YAXIS.W.idx; felix@2104: } felix@2104: else if (FacetTypes.IS.Q(facetName)) { felix@2104: return YAXIS.Q.idx; felix@2104: } felix@2104: else { felix@2104: logger.warn("Could not find axis for facet " + facetName); felix@2104: return YAXIS.W.idx; felix@2104: } felix@2104: } felix@2104: felix@2175: felix@2029: /** felix@2029: * Do Area out. felix@2420: * @param theme styling information. felix@2420: * @param visible whether or not visible. felix@2029: */ felix@2029: protected void doArea( felix@2029: Object o, ingo@2325: ArtifactAndFacet aandf, teichmann@6905: ThemeDocument theme, felix@2029: boolean visible felix@2029: ) { felix@2029: logger.debug("LongitudinalSectionGenerator.doArea"); felix@2029: StyledAreaSeriesCollection area = new StyledAreaSeriesCollection(theme); felix@2029: ingo@2325: String seriesName = aandf.getFacetDescription(); ingo@2325: felix@2104: AreaFacet.Data data = (AreaFacet.Data) o; felix@2104: felix@2029: XYSeries up = null; felix@2029: XYSeries down = null; felix@2029: felix@2104: if (data.getUpperData() != null) { felix@2029: up = new StyledXYSeries(seriesName, false, theme); felix@2104: if (data.getUpperData() instanceof WQKms) { felix@2104: if (FacetTypes.IS.Q(data.getRootFacetName())) { felix@2104: StyledSeriesBuilder.addPointsKmQ(up, (WQKms) data.getUpperData()); felix@2104: } felix@2104: else { felix@2104: StyledSeriesBuilder.addPoints(up, (WKms) data.getUpperData()); felix@2104: } felix@2029: } felix@2104: else if (data.getUpperData() instanceof double[][]) { felix@2685: StyledSeriesBuilder.addPoints(up, (double [][]) data.getUpperData(), false); felix@2029: } felix@2567: else if (data.getUpperData() instanceof WKms) { felix@2567: StyledSeriesBuilder.addPoints(up, (WKms) data.getUpperData()); felix@2567: } felix@2664: else if (data.getUpperData() instanceof Lines.LineData) { felix@2685: StyledSeriesBuilder.addPoints(up, ((Lines.LineData) data.getUpperData()).points, false); felix@2664: } felix@2029: else { felix@2029: logger.error("Do not know how to deal with (up) area info from: " felix@2104: + data.getUpperData()); felix@2029: } felix@2029: } felix@2029: felix@2420: // TODO Depending on style, the area (e.g. 20m^2) should be added as annotation. felix@2420: felix@2104: if (data.getLowerData() != null) { felix@2029: // TODO: Sort this out: when the two series have the same name, felix@2029: // the renderer (or anything in between) will not work correctly. felix@2029: down = new StyledXYSeries(seriesName + " ", false, theme); felix@2104: if (data.getLowerData() instanceof WQKms) { felix@2104: if (FacetTypes.IS.Q(data.getRootFacetName())) { felix@2104: StyledSeriesBuilder.addPointsKmQ(down, (WQKms) data.getLowerData()); felix@2104: } felix@2104: else { felix@2104: StyledSeriesBuilder.addPoints(down, (WQKms) data.getLowerData()); felix@2104: } felix@2029: } felix@2104: else if (data.getLowerData() instanceof double[][]) { felix@2685: StyledSeriesBuilder.addPoints(down, (double[][]) data.getLowerData(), false); felix@2029: } felix@2567: else if (data.getLowerData() instanceof WKms) { felix@2567: StyledSeriesBuilder.addPoints(down, (WKms) data.getLowerData()); felix@2567: } felix@2664: else if (data.getLowerData() instanceof Lines.LineData) { felix@2685: StyledSeriesBuilder.addPoints(down, ((Lines.LineData) data.getLowerData()).points, false); felix@2664: } felix@2029: else { felix@2029: logger.error("Do not know how to deal with (down) area info from: " felix@2104: + data.getLowerData()); felix@2029: } felix@2029: } felix@2029: felix@2029: if (up == null && down != null) { felix@2029: area.setMode(StyledAreaSeriesCollection.FILL_MODE.ABOVE); felix@2029: down.setKey(seriesName); felix@2029: area.addSeries(down); felix@2601: area.addSeries(StyledSeriesBuilder.createGroundAtInfinity(down)); felix@2029: } felix@2029: else if (up != null && down == null) { felix@2029: area.setMode(StyledAreaSeriesCollection.FILL_MODE.UNDER); felix@2029: area.addSeries(up); felix@2601: area.addSeries(StyledSeriesBuilder.createGroundAtInfinity(up)); felix@2029: } felix@2029: else if (up != null && down != null) { felix@2104: if (data.doPaintBetween()) { felix@2104: area.setMode(StyledAreaSeriesCollection.FILL_MODE.BETWEEN); felix@2104: } felix@2104: else { felix@2104: area.setMode(StyledAreaSeriesCollection.FILL_MODE.ABOVE); felix@2104: } felix@2029: area.addSeries(up); felix@2029: area.addSeries(down); felix@2029: } felix@2104: // Add area to the respective axis. felix@2104: addAreaSeries(area, axisIdxForFacet(data.getRootFacetName()), visible); felix@2029: } ingo@359: } ingo@359: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :