changeset 9316:72b3270e1568

U-Info salix line with regional and supraregional scenario calculation and chart display
author mschaefer
date Thu, 26 Jul 2018 17:28:32 +0200
parents 2ff46d921917
children 61b5de0b673b
files artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/UINFOArtifact.java artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/commons/UInfoResultType.java artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculation.java artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculationHistoricalResult.java artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculationNoScenarioResult.java artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculationRegionalResult.java artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculationSupraRegionalResult.java artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculator.java artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineProcessor.java artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineState.java artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixMnwMwResultFacet.java artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixScenarioResultFacet.java artifacts/src/main/resources/messages.properties artifacts/src/main/resources/messages_de.properties gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants.properties gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants_de.properties
diffstat 16 files changed, 276 insertions(+), 69 deletions(-) [+]
line wrap: on
line diff
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/UINFOArtifact.java	Thu Jul 26 17:23:49 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/UINFOArtifact.java	Thu Jul 26 17:28:32 2018 +0200
@@ -14,6 +14,7 @@
 import org.dive4elements.artifactdatabase.state.FacetActivity;
 import org.dive4elements.artifacts.Artifact;
 import org.dive4elements.river.artifacts.D4EArtifact;
+import org.dive4elements.river.artifacts.uinfo.salix.SalixLineProcessor;
 
 /**
  * The default UINFO artifact.
@@ -41,11 +42,17 @@
 
     static {
         // Active/deactivate facets.
-        // BEWARE: we can only define one activity for "sinfo", so we use the artifact
+        // BEWARE: we can only define one activity for "uinfo", so we use the artifact
         // as place for this
         FacetActivity.Registry.getInstance().register(ARTIFACT_NAME, new FacetActivity() {
             @Override
             public Boolean isInitialActive(final Artifact artifact, final Facet facet, final String output) {
+
+                final String name = facet.getName();
+
+                if (SalixLineProcessor.FACET_SALIX_SCENARIO.equals(name))
+                    return Boolean.FALSE;
+
                 return null;
             }
         });
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/commons/UInfoResultType.java	Thu Jul 26 17:23:49 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/commons/UInfoResultType.java	Thu Jul 26 17:28:32 2018 +0200
@@ -76,7 +76,7 @@
 
         @Override
         public String exportValue(final CallContext context, final Object value) {
-            final String valueStr = String.valueOf(value);
+            final String valueStr = ((int) value == 0) ? "" : String.valueOf(value);
             return exportStringValue(valueStr);
         }
 
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculation.java	Thu Jul 26 17:23:49 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculation.java	Thu Jul 26 17:28:32 2018 +0200
@@ -10,13 +10,10 @@
 package org.dive4elements.river.artifacts.uinfo.salix;
 
 import java.util.ArrayList;
-import java.util.Iterator;
 import java.util.List;
-import java.util.Map;
 import java.util.NavigableMap;
 import java.util.TreeMap;
 
-import org.apache.commons.lang.math.DoubleRange;
 import org.dive4elements.artifacts.CallContext;
 import org.dive4elements.river.artifacts.access.RangeAccess;
 import org.dive4elements.river.artifacts.model.Calculation;
@@ -74,7 +71,7 @@
         final SalixLineCalculator calculator = new SalixLineCalculator(this.context, riverInfoProvider);
         final NavigableMap<Double, List<Double>> rangeScenarios = buildRangeScenarios(accessSalix);
 
-        calculator.execute(problems, uinfo, rangeScenarios, accessSalix.getScenario(), results);
+        calculator.execute(problems, uinfo, rangeScenarios, accessSalix.getScenario(), buildScenarioLabels(accessSalix), results);
 
         // final Collection<ResultRow> rows = new ArrayList<>();
         // SalixLineCalculationNoScenarioResult result = null; // verzweigung etwas ungünstig. möglicherweise auch die
@@ -153,6 +150,17 @@
         return new CalculationResult(results, problems);
     }
 
+    // private SalixScenario findScenarioByKm(final double km, final Map<DoubleRange, SalixScenario> rangeScenarioMap) {
+    // final Iterator<DoubleRange> rangeIterator = rangeScenarioMap.keySet().iterator();
+    // while (rangeIterator.hasNext()) {
+    // final DoubleRange range = rangeIterator.next();
+    // if (range.containsDouble(km + 0.0001)) {
+    // return rangeScenarioMap.get(range);
+    // }
+    // }
+    // return null;
+    // }
+
     /**
      * Build a map of delta-Ws by km-range for the selected scenario
      */
@@ -208,14 +216,17 @@
         }
     }
 
-    private SalixScenario findScenarioByKm(final double km, final Map<DoubleRange, SalixScenario> rangeScenarioMap) {
-        final Iterator<DoubleRange> rangeIterator = rangeScenarioMap.keySet().iterator();
-        while (rangeIterator.hasNext()) {
-            final DoubleRange range = rangeIterator.next();
-            if (range.containsDouble(km + 0.0001)) {
-                return rangeScenarioMap.get(range);
-            }
+    /**
+     * Build the list of delta-w labels for the scenario type
+     */
+    private String[] buildScenarioLabels(final SalixLineAccess access) {
+        final List<String> labels = new ArrayList<>();
+        if (access.getScenario() == ScenarioType.REGIONAL) {
+            final int[] deltaws = access.getRegionalScenarioIntegers();
+            for (int i = 0; i <= deltaws.length - 1; i++)
+                if (deltaws[i] != 0)
+                    labels.add(Integer.toString(deltaws[i]) + " cm");
         }
-        return null;
+        return labels.toArray(new String[labels.size()]);
     }
 }
\ No newline at end of file
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculationHistoricalResult.java	Thu Jul 26 17:23:49 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculationHistoricalResult.java	Thu Jul 26 17:28:32 2018 +0200
@@ -16,7 +16,6 @@
 import org.dive4elements.river.artifacts.common.IExportContext;
 import org.dive4elements.river.artifacts.common.ResultRow;
 import org.dive4elements.river.artifacts.sinfo.util.RiverInfo;
-import org.dive4elements.river.artifacts.sinfo.util.WstInfo;
 import org.dive4elements.river.artifacts.uinfo.commons.UInfoResultType;
 
 /**
@@ -26,9 +25,8 @@
 
     private static final long serialVersionUID = 1L;
 
-    public SalixLineCalculationHistoricalResult(final String label, final WstInfo wst, final Collection<ResultRow> rows) {
-        super(label, wst, rows);
-
+    public SalixLineCalculationHistoricalResult(final String label, final Collection<ResultRow> rows) {
+        super(label, rows);
     }
 
     @Override
@@ -50,12 +48,7 @@
     }
 
     @Override
-    protected String[] formatCSVRow(final ExportContextCSV exportContextCSV, final ResultRow row) {
-
-        return formatRow(exportContextCSV, row);
-    }
-
-    private String[] formatRow(final IExportContext context, final ResultRow row) {
+    protected String[] formatRow(final IExportContext context, final ResultRow row) {
 
         final Collection<String> lines = super.getNoScenarioFormat(row, context);
 
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculationNoScenarioResult.java	Thu Jul 26 17:23:49 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculationNoScenarioResult.java	Thu Jul 26 17:28:32 2018 +0200
@@ -20,7 +20,6 @@
 import org.dive4elements.river.artifacts.common.MetaAndTableJRDataSource;
 import org.dive4elements.river.artifacts.common.ResultRow;
 import org.dive4elements.river.artifacts.sinfo.util.RiverInfo;
-import org.dive4elements.river.artifacts.sinfo.util.WstInfo;
 import org.dive4elements.river.artifacts.uinfo.commons.UInfoResultType;
 
 /**
@@ -31,7 +30,7 @@
     private static final long serialVersionUID = 1L;
     private static final String JASPER_FILE = "/jasper/templates/uinfo.salixline.jrxml";
 
-    public SalixLineCalculationNoScenarioResult(final String label, final WstInfo wst, final Collection<ResultRow> rows) {
+    public SalixLineCalculationNoScenarioResult(final String label, final Collection<ResultRow> rows) {
         super(label, rows);
     }
 
@@ -78,7 +77,7 @@
 
     }
 
-    private String[] formatRow(final IExportContext context, final ResultRow row) {
+    protected String[] formatRow(final IExportContext context, final ResultRow row) {
 
         final Collection<String> lines = getNoScenarioFormat(row, context);
 
@@ -92,13 +91,13 @@
     }
 
     protected final Collection<String> getNoScenarioFormat(final ResultRow row, final IExportContext context) {
+
         final Collection<String> lines = new ArrayList<>();
         lines.add(context.formatRowValue(row, GeneralResultType.station));
         lines.add(context.formatRowValue(row, UInfoResultType.salixline));
         lines.add(context.formatRowValue(row, UInfoResultType.salix_delta_mw));
 
         return lines;
-
     }
 
     protected final void writeRegionalCommonCSVMeta(final ExportContextCSV exportContextCSV) {
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculationRegionalResult.java	Thu Jul 26 17:23:49 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculationRegionalResult.java	Thu Jul 26 17:28:32 2018 +0200
@@ -14,12 +14,14 @@
 import java.util.List;
 
 import org.dive4elements.river.artifacts.common.ExportContextCSV;
+import org.dive4elements.river.artifacts.common.GeneralResultType;
 import org.dive4elements.river.artifacts.common.IExportContext;
 import org.dive4elements.river.artifacts.common.ResultRow;
 import org.dive4elements.river.artifacts.sinfo.util.RiverInfo;
-import org.dive4elements.river.artifacts.sinfo.util.WstInfo;
 import org.dive4elements.river.artifacts.uinfo.commons.UInfoResultType;
 
+import gnu.trove.TDoubleArrayList;
+
 /**
  * @author Domenico Nardi Tironi
  */
@@ -27,8 +29,22 @@
 
     private static final long serialVersionUID = 1L;
 
-    public SalixLineCalculationRegionalResult(final String label, final WstInfo wst, final Collection<ResultRow> rows) {
-        super(label, wst, rows);
+    private final String[] scenarioLabels;
+
+    public SalixLineCalculationRegionalResult(final String label, final String[] scenarioLabels, final Collection<ResultRow> rows) {
+        super(label, rows);
+        this.scenarioLabels = scenarioLabels;
+    }
+
+    public final int getScenarioCount() {
+        return (this.scenarioLabels != null) ? this.scenarioLabels.length : 0;
+    }
+
+    public String getScenarioLabel(final int i) {
+        if ((this.scenarioLabels != null) && (i < this.scenarioLabels.length))
+            return this.scenarioLabels[i];
+        else
+            return "";
     }
 
     @Override
@@ -36,9 +52,10 @@
 
         final Collection<String> header = super.writeNoScenarioHeader(exportContextCSV);
 
-        header.add(exportContextCSV.msg(SalixScenario.getScenarioValueHeader()));
-        header.add(exportContextCSV.msg(SalixScenario.getDwsplHeader()));
-
+        for (int i = 1; i <= getScenarioCount(); i++) {
+            header.add(exportContextCSV.msg(SalixScenario.getScenarioValueHeader()));
+            header.add(exportContextCSV.msg(SalixScenario.getDwsplHeader()));
+        }
         exportContextCSV.writeCSVLine(header.toArray(new String[header.size()]));
     }
 
@@ -50,12 +67,7 @@
     }
 
     @Override
-    protected String[] formatCSVRow(final ExportContextCSV exportContextCSV, final ResultRow row) {
-
-        return formatRow(exportContextCSV, row);
-    }
-
-    private String[] formatRow(final IExportContext context, final ResultRow row) {
+    protected String[] formatRow(final IExportContext context, final ResultRow row) {
 
         final Collection<String> lines = super.getNoScenarioFormat(row, context);
 
@@ -79,6 +91,31 @@
         writeRegionalCommonCSVMeta(exportContextCSV);
     }
 
+    /**
+     * Gets a longitudinal section of W, Q, or flood duration of one of the waterlevels
+     */
+    public final double[][] getScenarioPoints(final int dataIndex) {
+
+        final Collection<ResultRow> rows = getRows();
+
+        final TDoubleArrayList xPoints = new TDoubleArrayList(rows.size());
+        final TDoubleArrayList yPoints = new TDoubleArrayList(rows.size());
+
+        for (final ResultRow row : rows) {
+
+            final double station = row.getDoubleValue(GeneralResultType.station);
+
+            final List<SalixScenario> scenarios = (List<SalixScenario>) row.getValue(UInfoResultType.customMultiRowColSalixRegionalValue_Dwspl);
+            if (dataIndex <= scenarios.size() - 1) {
+                final double value = scenarios.get(dataIndex).getSalixValue();
+                xPoints.add(station);
+                yPoints.add(value);
+            }
+        }
+
+        return new double[][] { xPoints.toNativeArray(), yPoints.toNativeArray() };
+    }
+
     // TODO: move to SupraRegionalEffectsResult-Class; remove here
     // private void writeExtendedRegionalEffectsCSVMetadata(final ExportContextCSV exportContextCSV) {
     // final String main = "uinfo.export.csv.meta.header.salix.regionalextended";
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculationSupraRegionalResult.java	Thu Jul 26 17:23:49 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculationSupraRegionalResult.java	Thu Jul 26 17:28:32 2018 +0200
@@ -16,7 +16,6 @@
 import org.dive4elements.river.artifacts.common.IExportContext;
 import org.dive4elements.river.artifacts.common.ResultRow;
 import org.dive4elements.river.artifacts.sinfo.util.RiverInfo;
-import org.dive4elements.river.artifacts.sinfo.util.WstInfo;
 import org.dive4elements.river.artifacts.uinfo.commons.UInfoResultType;
 
 /**
@@ -26,9 +25,8 @@
 
     private static final long serialVersionUID = 1L;
 
-    public SalixLineCalculationSupraRegionalResult(final String label, final WstInfo wst, final Collection<ResultRow> rows) {
-        super(label, wst, rows);
-
+    public SalixLineCalculationSupraRegionalResult(final String label, final Collection<ResultRow> rows) {
+        super(label, rows);
     }
 
     @Override
@@ -50,12 +48,7 @@
     }
 
     @Override
-    protected String[] formatCSVRow(final ExportContextCSV exportContextCSV, final ResultRow row) {
-
-        return formatRow(exportContextCSV, row);
-    }
-
-    private String[] formatRow(final IExportContext context, final ResultRow row) {
+    protected String[] formatRow(final IExportContext context, final ResultRow row) {
 
         final Collection<String> lines = super.getNoScenarioFormat(row, context);
 
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculator.java	Thu Jul 26 17:23:49 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculator.java	Thu Jul 26 17:28:32 2018 +0200
@@ -13,6 +13,7 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
 import java.util.NavigableMap;
 
 import org.dive4elements.artifacts.CallContext;
@@ -56,6 +57,9 @@
 
     private WstValueTable wst;
 
+    /**
+     * List of delta-w (may be 0) mapped by km range
+     */
     private NavigableMap<Double, List<Double>> rangeScenarios;
 
 
@@ -72,7 +76,7 @@
      * Calculate the salix line result rows
      */
     public void execute(final Calculation problems, final UINFOArtifact uinfo, final NavigableMap<Double, List<Double>> rangeScenarios,
-            final ScenarioType scenarioType, final SalixLineCalculationResults results) {
+            final ScenarioType scenarioType, final String[] scenarioLabels, final SalixLineCalculationResults results) {
 
         this.problems = problems;
         this.wst = WstValueTableFactory.getTable(this.riverInfoProvider.getRiver());
@@ -87,13 +91,13 @@
             this.rows.add(createRow(station));
         }
         if (scenarioType == ScenarioType.REGIONAL)
-            results.addResult(new SalixLineCalculationRegionalResult("Salix", null, this.rows), problems);
+            results.addResult(new SalixLineCalculationRegionalResult("Salix", scenarioLabels, this.rows), problems);
         else if (scenarioType == ScenarioType.SUPRAREGIONAL)
-            results.addResult(new SalixLineCalculationSupraRegionalResult("Salix", null, this.rows), problems);
+            results.addResult(new SalixLineCalculationSupraRegionalResult("Salix", this.rows), problems);
         else if (scenarioType == ScenarioType.HISTORICAL)
-            results.addResult(new SalixLineCalculationHistoricalResult("Salix", null, this.rows), problems);
+            results.addResult(new SalixLineCalculationHistoricalResult("Salix", this.rows), problems);
         else
-            results.addResult(new SalixLineCalculationNoScenarioResult("Salix", null, this.rows), problems);
+            results.addResult(new SalixLineCalculationNoScenarioResult("Salix", this.rows), problems);
     }
 
     /**
@@ -128,16 +132,35 @@
     private ResultRow createRow(final double station) {
 
         final ResultRow row = ResultRow.create();
+        // Find station's gauge
         final Gauge gauge = this.riverInfoProvider.getGauge(station, true);
         row.putValue(GeneralResultType.station, station);
+        // Interpolate mnw, mw, and mhw
         final double mnw = interpolateW(station, this.gaugeMnwPos.get(gauge));
         final double mw = interpolateW(station, this.gaugeMwPos.get(gauge));
         final double mhw = interpolateW(station, this.gaugeMhwPos.get(gauge));
         row.putValue(SInfoResultType.waterlevel, mnw);
         row.putValue(SInfoResultType.waterlevel1, mw);
         row.putValue(SInfoResultType.waterlevel2, mhw);
+        // Calc salix-line and mw-mnw
         row.putValue(UInfoResultType.salixline, calcSalix(mhw, mw));
         row.putValue(UInfoResultType.salix_delta_mw, calcMwmnw(mw, mnw));
+        // Calc scenario values (always all scenario types set, Result variant extracts the fields needed)
+        final List<SalixScenario> scenarios = new ArrayList<>();
+        final double[] deltaws = getDeltaWs(station);
+        for (int i = 0; i <= deltaws.length - 1; i++) {
+            if (Math.abs(deltaws[i]) < 0.0001) {
+                row.putValue(UInfoResultType.salix_line_scenario, Double.NaN);
+                row.putValue(UInfoResultType.salix_line_scenario_dwspl, 0); // TODO NaN when changed from int to double
+            }
+            else {
+                final double salix = calcSalix(mhw, mw + deltaws[i]);
+                row.putValue(UInfoResultType.salix_line_scenario, salix);
+                row.putValue(UInfoResultType.salix_line_scenario_dwspl, (int) (deltaws[i] * 100));
+                scenarios.add(new SalixScenario((int) (deltaws[i] * 100), salix));
+            }
+        }
+        row.putValue(UInfoResultType.customMultiRowColSalixRegionalValue_Dwspl, scenarios);
         return row;
     }
 
@@ -164,4 +187,19 @@
     private double calcMwmnw(final double mw, final double mnw) {
         return mnw - mw;
     }
+
+    /**
+     * Gets the station-specific list of delta-ws of the active scenario, at least with one 0 item in any case
+     */
+    private double[] getDeltaWs(final double station) {
+        final Entry<Double, List<Double>> stationScenarios = this.rangeScenarios.floorEntry(station);
+        if (stationScenarios == null)
+            return new double[] { 0.0 };
+        else {
+            final double[] deltaws = new double[stationScenarios.getValue().size()];
+            for (int i = 0; i <= stationScenarios.getValue().size() - 1; i++)
+                deltaws[i] = stationScenarios.getValue().get(i);
+            return deltaws;
+        }
+    }
 }
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineProcessor.java	Thu Jul 26 17:23:49 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineProcessor.java	Thu Jul 26 17:28:32 2018 +0200
@@ -18,6 +18,7 @@
 import org.dive4elements.artifacts.CallContext;
 import org.dive4elements.river.artifacts.D4EArtifact;
 import org.dive4elements.river.artifacts.common.AbstractCalculationResult;
+import org.dive4elements.river.artifacts.resources.Resources;
 import org.dive4elements.river.artifacts.uinfo.commons.UInfoResultType;
 import org.dive4elements.river.exports.DiagramGenerator;
 import org.dive4elements.river.exports.StyledSeriesBuilder;
@@ -36,29 +37,47 @@
  */
 public final class SalixLineProcessor extends DefaultProcessor {
 
-    private static final String FACET_SALIX_LINE = "uinfo_facet_salix";
+    private static final String FACET_SALIX_LINE = "uinfo_facet_salix_line";
 
-    private static final String FACET_SALIX_MNWMW = "uinfo_facet_mnwmw";
+    private static final String FACET_SALIX_LINE_DESCRIPTION = "uinfo_facet_salix_line.description";
+
+    private static final String FACET_SALIX_MNWMW = "uinfo_facet_salix_mnwmw";
+
+    private static final String FACET_SALIX_MNWMW_DESCRIPTION = "uinfo_facet_salix_mnwmw.description";
+
+    public static final String FACET_SALIX_SCENARIO = "uinfo_facet_salix_scenario";
+
+    private static final String FACET_SALIX_SCENARIO_DESCRIPTION = "uinfo_facet_salix_scenario.description";
 
     private static final Set<String> HANDLED_FACET_TYPES = new HashSet<>();
 
     static {
         HANDLED_FACET_TYPES.add(FACET_SALIX_LINE);
         HANDLED_FACET_TYPES.add(FACET_SALIX_MNWMW);
+        HANDLED_FACET_TYPES.add(FACET_SALIX_SCENARIO);
     }
 
     public static Facet createSalixLineFacet(final CallContext context, final String hash, final String id, final AbstractCalculationResult result,
-            final int facetIndex, final int resultIndex, final String description) {
+            final int facetIndex, final int resultIndex) {
 
+        final String description = Resources.getMsg(context.getMeta(), FACET_SALIX_LINE_DESCRIPTION, FACET_SALIX_LINE_DESCRIPTION);
         return new SalixLineResultFacet(FACET_SALIX_LINE, description);
     }
 
     public static Facet createSalixMnwMwFacet(final CallContext context, final String hash, final String id, final AbstractCalculationResult result,
-            final int facetIndex, final int resultIndex, final String description) {
+            final int facetIndex, final int resultIndex) {
 
+        final String description = Resources.getMsg(context.getMeta(), FACET_SALIX_MNWMW_DESCRIPTION, FACET_SALIX_MNWMW_DESCRIPTION);
         return new SalixMnwMwResultFacet(FACET_SALIX_MNWMW, description);
     }
 
+    public static Facet createSalixScenarioFacet(final CallContext context, final String hash, final String id, final AbstractCalculationResult result,
+            final int facetIndex, final int resultIndex, final String subLabel) {
+
+        final String description = Resources.getMsg(context.getMeta(), FACET_SALIX_SCENARIO_DESCRIPTION, FACET_SALIX_SCENARIO_DESCRIPTION, subLabel);
+        return new SalixScenarioResultFacet(FACET_SALIX_SCENARIO, description, facetIndex, hash, id);
+    }
+
     @Override
     public final String getAxisLabel(final DiagramGenerator generator) {
 
@@ -80,15 +99,26 @@
         final Object data = bundle.getData(context);
 
         final XYSeries series = new StyledXYSeries(bundle.getFacetDescription(), theme);
+        final SalixLineCalculationNoScenarioResult result = (SalixLineCalculationNoScenarioResult) data;
 
         if (bundle.getFacetName().equals(FACET_SALIX_LINE)) {
-            StyledSeriesBuilder.addPoints(series, ((SalixLineCalculationNoScenarioResult) data).getStationPoints(UInfoResultType.salixline), true);
+            StyledSeriesBuilder.addPoints(series, result.getStationPoints(UInfoResultType.salixline), true);
             generator.addAxisSeries(series, this.axisName, visible);
             return;
         }
 
         if (bundle.getFacetName().equals(FACET_SALIX_MNWMW)) {
-            StyledSeriesBuilder.addPoints(series, ((SalixLineCalculationNoScenarioResult) data).getStationPoints(UInfoResultType.salix_delta_mw), true);
+            StyledSeriesBuilder.addPoints(series, result.getStationPoints(UInfoResultType.salix_delta_mw), true);
+            generator.addAxisSeries(series, this.axisName, visible);
+            return;
+        }
+
+        if (bundle.getFacetName().equals(FACET_SALIX_SCENARIO)) {
+            // TODO Differenzieren, Scenario 1 bis max. 5 bei Regional
+            if (data instanceof SalixLineCalculationRegionalResult)
+                StyledSeriesBuilder.addPoints(series, ((SalixLineCalculationRegionalResult) data).getScenarioPoints(bundle.getFacet().getIndex()), true);
+            else
+                StyledSeriesBuilder.addPoints(series, result.getStationPoints(UInfoResultType.salix_line_scenario), false);
             generator.addAxisSeries(series, this.axisName, visible);
             return;
         }
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineState.java	Thu Jul 26 17:23:49 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineState.java	Thu Jul 26 17:28:32 2018 +0200
@@ -21,6 +21,7 @@
 import org.dive4elements.river.artifacts.model.EmptyFacet;
 import org.dive4elements.river.artifacts.model.FacetTypes;
 import org.dive4elements.river.artifacts.model.ReportFacet;
+import org.dive4elements.river.artifacts.resources.Resources;
 import org.dive4elements.river.artifacts.states.DefaultState;
 import org.dive4elements.river.artifacts.uinfo.UINFOArtifact;
 
@@ -68,9 +69,9 @@
      * @param old
      *            Object that was cached.
      */
-    private Object compute(final UINFOArtifact sinfo, final CallContext context, final String hash, final List<Facet> facets, final Object old) {
+    private Object compute(final UINFOArtifact uinfo, final CallContext context, final String hash, final List<Facet> facets, final Object old) {
 
-        final CalculationResult res = doCompute(sinfo, context, old);
+        final CalculationResult res = doCompute(uinfo, context, old);
 
         if (facets == null)
             return res;
@@ -80,8 +81,25 @@
         final List<SalixLineCalculationNoScenarioResult> resultList = results.getResults();
 
         if (!resultList.isEmpty()) {
-            facets.add(SalixLineProcessor.createSalixLineFacet(context, hash, this.id, resultList.get(0), 0, 0, "Salix-Linie"));
-            facets.add(SalixLineProcessor.createSalixMnwMwFacet(context, hash, this.id, resultList.get(0), 0, 0, "MNW-MW"));
+            facets.add(SalixLineProcessor.createSalixLineFacet(context, hash, this.id, resultList.get(0), 0, 0));
+            facets.add(SalixLineProcessor.createSalixMnwMwFacet(context, hash, this.id, resultList.get(0), 0, 0));
+            if (resultList.get(0) instanceof SalixLineCalculationRegionalResult) {
+                final SalixLineCalculationRegionalResult result = (SalixLineCalculationRegionalResult) resultList.get(0);
+                for (int i = 0; i <= result.getScenarioCount() - 1; i++) {
+                    final String sublabel = Resources.getMsg(context.getMeta(), "uinfo_salix_scenario_deltaw", "uinfo_salix_scenario_deltaw",
+                            result.getScenarioLabel(i));
+                    facets.add(SalixLineProcessor.createSalixScenarioFacet(context, hash, this.id, result, i, 0, sublabel));
+                }
+            }
+            else if (resultList.get(0) instanceof SalixLineCalculationSupraRegionalResult) {
+                final String sublabel = Resources.getMsg(context.getMeta(), "uinfo_salix_scenario_supraregional");
+                facets.add(SalixLineProcessor.createSalixScenarioFacet(context, hash, this.id, resultList.get(0), 0, 0, sublabel));
+            }
+
+            else if (resultList.get(0) instanceof SalixLineCalculationHistoricalResult) {
+                final String sublabel = Resources.getMsg(context.getMeta(), "uinfo_salix_scenario_historical");
+                facets.add(SalixLineProcessor.createSalixScenarioFacet(context, hash, this.id, resultList.get(0), 0, 0, sublabel));
+            }
 
             final Facet csv = new DataFacet(FacetTypes.CSV, "CSV data", ComputeType.ADVANCE, hash, this.id);
             final Facet pdf = new DataFacet(FacetTypes.PDF, "PDF data", ComputeType.ADVANCE, hash, this.id);
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixMnwMwResultFacet.java	Thu Jul 26 17:23:49 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixMnwMwResultFacet.java	Thu Jul 26 17:28:32 2018 +0200
@@ -19,7 +19,7 @@
 import org.dive4elements.river.artifacts.model.DataFacet;
 
 /**
- * Facet of the U-Info salix line curve.
+ * Facet of the U-Info salix mnw-mw curve.
  */
 public class SalixMnwMwResultFacet extends DataFacet {
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixScenarioResultFacet.java	Thu Jul 26 17:28:32 2018 +0200
@@ -0,0 +1,67 @@
+/* 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.artifacts.uinfo.salix;
+
+import org.apache.log4j.Logger;
+import org.dive4elements.artifactdatabase.state.Facet;
+import org.dive4elements.artifacts.Artifact;
+import org.dive4elements.artifacts.CallContext;
+import org.dive4elements.river.artifacts.D4EArtifact;
+import org.dive4elements.river.artifacts.common.AbstractCalculationResult;
+import org.dive4elements.river.artifacts.common.AbstractCalculationResults;
+import org.dive4elements.river.artifacts.model.CalculationResult;
+import org.dive4elements.river.artifacts.model.DataFacet;
+import org.dive4elements.river.artifacts.states.DefaultState.ComputeType;
+
+/**
+ * Facet of the U-Info salix scenario curve.
+ */
+public class SalixScenarioResultFacet extends DataFacet {
+
+    private static final long serialVersionUID = 1L;
+
+    private static Logger log = Logger.getLogger(SalixScenarioResultFacet.class);
+
+    private int resultIndex;
+
+    public SalixScenarioResultFacet() {
+        // required for clone operation deepCopy()
+    }
+
+    public SalixScenarioResultFacet(final String name, final String description, final int facetIndex, final String hash, final String id) {
+        super(facetIndex, name, description, ComputeType.ADVANCE, hash, id);
+    }
+
+    @Override
+    public final Object getData(final Artifact artifact, final CallContext context) {
+
+        log.debug("Get data for result at index: " + this.resultIndex);
+
+        final D4EArtifact flys = (D4EArtifact) artifact;
+
+        final CalculationResult res = (CalculationResult) flys.compute(context, this.hash, this.stateId, this.type, false);
+
+        final AbstractCalculationResults<AbstractCalculationResult> data = (AbstractCalculationResults<AbstractCalculationResult>) res.getData();
+
+        return data.getResults().get(this.resultIndex);
+    }
+
+    /** Copy deeply. */
+    @Override
+    public Facet deepCopy() {
+        // FIXME: why not simply use the full constructor instead?
+        final SalixScenarioResultFacet copy = new SalixScenarioResultFacet();
+        // FIXME: why does DataFacet does not override set? Bad access to variables of parent!
+        copy.set(this);
+        copy.type = this.type;
+        copy.hash = this.hash;
+        copy.stateId = this.stateId;
+        return copy;
+    }
+}
\ No newline at end of file
--- a/artifacts/src/main/resources/messages.properties	Thu Jul 26 17:23:49 2018 +0200
+++ b/artifacts/src/main/resources/messages.properties	Thu Jul 26 17:28:32 2018 +0200
@@ -1083,6 +1083,7 @@
 mainvalue.duration = \u00dcberflutungsdauer
 mainvalue.duration.description = \u00dcberflutungsdauer ({0})
 state.uinfo.salix.historical.km_range_part = Ausgewertete Strecke
+
 uinfo.salix.sounding= Peilung
 uinfo.salix.soundings= Soundings
 uinfo.export.salix_line.csv.header.scenario_dwspl = \u0394MW [cm]
@@ -1109,10 +1110,16 @@
 uinfo.export.url.inundationduration.vegetation = Vegetationszonen ({0})
 uinfo.export.url.inundationduration.vegetation_scenario= Vegetationszonen Szenario ({0}, {1}cm)
 uinfo.export.url.inundationduration.scenario = \u00dcberflutungsdauer Szenario ({0}, {1}cm)
+uinfo.chart.salix_line.section.title = Salix-Linie (Fluss/Aue-Konnektivit\u00e4t) - L\u00e4ngsschnitt
 uinfo_facet_salix_line = Salix-Linie
 uinfo_facet_salix_line.description = Salix-Linie
 uinfo_facet_salix_mnwmw = (MW-MNW)x(-1)
 uinfo_facet_salix_mnwmw.description = (MW-MNW)x(-1)
+uinfo_facet_salix_scenario = Salix-Linie Szenario, {0}
+uinfo_facet_salix_scenario.description = Salix-Linie Szenario, {0}
+uinfo_salix_scenario_deltaw = \u0394MW={0}
+uinfo_salix_scenario_supraregional = \u00fcberregional
+uinfo_salix_scenario_historical = historisch
 
 predefineddepthevol.total.title = Gesamt: {0}
 predefineddepthevol.peryear.title = J\u00e4hrlich: {0}
--- a/artifacts/src/main/resources/messages_de.properties	Thu Jul 26 17:23:49 2018 +0200
+++ b/artifacts/src/main/resources/messages_de.properties	Thu Jul 26 17:28:32 2018 +0200
@@ -1082,6 +1082,7 @@
 mainvalue.w.description = Wasserstand/Wasserspiegellage ({0})
 mainvalue.duration = \u00dcberflutungsdauer
 mainvalue.duration.description = \u00dcberflutungsdauer ({0})
+
 state.uinfo.salix.historical.km_range_part = Ausgewertete Strecke
 uinfo.salix.sounding= Peilung
 uinfo.salix.soundings= Peilungen
@@ -1108,11 +1109,17 @@
 uinfo.export.url.inundationduration.inundationduration = \u00dcberflutungsdauer ({0})
 uinfo.export.url.inundationduration.vegetation = Vegetationszonen ({0})
 uinfo.export.url.inundationduration.vegetation_scenario= Vegetationszonen Szenario ({0}, {1}cm)
-uinfo.export.url.inundationduration.scenario = \u00dcberflutungsdauer Szenario ({0}, {1}cm) 
+uinfo.export.url.inundationduration.scenario = \u00dcberflutungsdauer Szenario ({0}, {1}cm)
+uinfo.chart.salix_line.section.title = Salix-Linie (Fluss/Aue-Konnektivit\u00e4t) - L\u00e4ngsschnitt
 uinfo_facet_salix_line = Salix-Linie
 uinfo_facet_salix_line.description = Salix-Linie
 uinfo_facet_salix_mnwmw = (MW-MNW)x(-1)
 uinfo_facet_salix_mnwmw.description = (MW-MNW)x(-1)
+uinfo_facet_salix_scenario = Salix-Linie Szenario, {0}
+uinfo_facet_salix_scenario.description = Salix-Linie Szenario, {0}
+uinfo_salix_scenario_deltaw = \u0394MW={0}
+uinfo_salix_scenario_supraregional = \u00fcberregional
+uinfo_salix_scenario_historical = historisch
 
 predefineddepthevol.total.title = Gesamt: {0}
 predefineddepthevol.peryear.title = J\u00e4hrlich: {0}
--- a/gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants.properties	Thu Jul 26 17:23:49 2018 +0200
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants.properties	Thu Jul 26 17:28:32 2018 +0200
@@ -845,7 +845,7 @@
 uinfo_salix_km_has_gaps = Der Km-Bereich ist nicht vollst. belegt.
 uinfo_salix_km_anschluss = Der eingegebene Bereich schlie\u00dft nicht an den letzten Wert an.
 uinfo_salix_input_complete = Die gesamte Strecke ist bereits mit Werten belegt.
-uinfo_salix_line = Salix-Linie (Fluss/Aue-Konnektivit\u00e4t) - L\u00e4ngsschnitt
+uinfo_salix_line = Salix-Linie - L\u00e4ngsschnitt
 
 bundu = Betrieb und Unterhaltung 
 bundu_bezugswst_fix_choice_title= Fixierungsauswahl
--- a/gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants_de.properties	Thu Jul 26 17:23:49 2018 +0200
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants_de.properties	Thu Jul 26 17:28:32 2018 +0200
@@ -845,7 +845,7 @@
 uinfo_salix_km_has_gaps = Der Km-Bereich ist nicht vollst. belegt.
 uinfo_salix_km_anschluss = Der eingegebene Bereich schlie\u00dft nicht an den letzten Wert an.
 uinfo_salix_input_complete = Die gesamte Strecke ist bereits mit Werten belegt.
-uinfo_salix_line = Salix-Linie (Fluss/Aue-Konnektivit\u00e4t) - L\u00e4ngsschnitt
+uinfo_salix_line = Salix-Linie - L\u00e4ngsschnitt
 
 bundu = Betrieb und Unterhaltung
 bundu_bezugswst_fix_choice_title= Fixierungsauswahl

http://dive4elements.wald.intevation.org