changeset 8916:5d5d0051723f

Working on outputmodes of tkh calculation
author gernotbelger
date Wed, 28 Feb 2018 18:55:39 +0100
parents d9dbf0b74bc2
children 29442c03c6e3
files artifacts/doc/conf/artifacts/sinfo.xml artifacts/doc/conf/generators/generators.xml artifacts/doc/conf/generators/longitudinal-diagram-defaults.xml artifacts/doc/conf/generators/longitudinal-diagrams.xml artifacts/doc/conf/meta-data.xml artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/AbstractSInfoCalculationResults.java artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/AbstractSInfoProcessor.java artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/SInfoResultFacet.java artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/TkhProcessor.java artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/AbstractSInfoProcessor.java artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculationResults.java artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthFacet.java artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthProcessor.java artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthState.java artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/TkhProcessor.java artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhcalculation/TkhCalculator.java artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/TkhCalculation.java artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/TkhCalculationResults.java artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/TkhState.java artifacts/src/main/resources/messages.properties artifacts/src/main/resources/messages_de.properties artifacts/src/main/resources/messages_de_DE.properties artifacts/src/main/resources/messages_en.properties gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants.java 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 gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants_en.properties
diffstat 27 files changed, 413 insertions(+), 387 deletions(-) [+]
line wrap: on
line diff
--- a/artifacts/doc/conf/artifacts/sinfo.xml	Wed Feb 28 17:27:15 2018 +0100
+++ b/artifacts/doc/conf/artifacts/sinfo.xml	Wed Feb 28 18:55:39 2018 +0100
@@ -120,6 +120,29 @@
 
     <state id="state.sinfo.transport_bodies_heights" description="state.sinfo.transport_bodies_heights" state="org.dive4elements.river.artifacts.sinfo.tkhstate.TkhState" helpText="help.state.sinfo.transport_bodies_heights">
       <outputmodes>
+        <outputmode name="sinfo_tkk" description="output.tkk" mime-type="image/png" type="chart">
+          <facets>
+            <!-- REMARK: id's that ends with 'filtered' are handled differently ' -->
+            <!-- FIXME: should be filtered according to spec -->
+            <facet name="sinfo_flow_depth.tkh" description="Facet for tkh"/>
+
+            <facet name="longitudinal_section.annotations" description="facet.longitudinal_section.annotations"/>
+          </facets>
+        </outputmode>
+      
+        <outputmode name="sinfo_tkh_export" description="output.sinfo_tkh_export" mime-type="text/plain" type="export">
+          <facets>
+            <facet name="csv" description="facet.sinfo_tkh_export.csv"/>
+            <facet name="pdf" description="facet.sinfo_tkh_export.pdf"/>
+          </facets>
+        </outputmode>
+
+        <outputmode name="sinfo_tkh_report" description="output.sinfo_flowdepth_report" mime-type="text/xml" type="report">
+          <facets>
+            <facet name="report" description="facet.sinfo_tkh_report"/>
+          </facets>
+        </outputmode>      
+      
         <!-- <outputmode name="sinfo_flow_depth" description="output.flow_depth" mime-type="image/png" type="chart"> <facets> <facet name="sinfo_flow_depth.filtered" description="Facet for mean flow depth, filtered by current zoom state"/> <facet name="sinfo_flow_depth.tkh.filtered" description="Facet for mean flow depth including tkh, filtered by current zoom state"/> <facet name="sinfo_flow_depth.tkh" description="Facet for tkh"/> <facet name="longitudinal_section.annotations" description="facet.longitudinal_section.annotations"/> 
           </facets> </outputmode> <outputmode name="sinfo_flowdepth_export" description="output.sinfo_flowdepth_export" mime-type="text/plain" type="export"> <facets> <facet name="csv" description="facet.sinfo_flowdepth_export.csv"/> <facet name="pdf" description="facet.sinfo_flowdepth_export.pdf"/> </facets> </outputmode> <outputmode name="sinfo_flowdepth_report" description="output.sinfo_flowdepth_report" mime-type="text/xml" type="report"> <facets> <facet name="report" description="facet.sinfo_flowdepth_report"/> 
           </facets> </outputmode> -->
--- a/artifacts/doc/conf/generators/generators.xml	Wed Feb 28 17:27:15 2018 +0100
+++ b/artifacts/doc/conf/generators/generators.xml	Wed Feb 28 18:55:39 2018 +0100
@@ -60,8 +60,10 @@
     <output-generator names="wsplgen" class="org.dive4elements.river.exports.ShapeExporter"/>
     
     <!-- SINFO -->
+    <output-generator names="sinfo_flowdepth_export" class="org.dive4elements.river.artifacts.sinfo.flowdepth.FlowDepthExporter"/>
     <output-generator names="sinfo_flowdepth_report" class="org.dive4elements.river.exports.ReportGenerator"/>
-    <output-generator names="sinfo_flowdepth_export" class="org.dive4elements.river.artifacts.sinfo.flowdepth.FlowDepthExporter"/>
+    <output-generator names="sinfo_tkh_export" class="org.dive4elements.river.artifacts.sinfo.tkhstate.TkhExporter"/>
+    <output-generator names="sinfo_tkh_report" class="org.dive4elements.river.exports.ReportGenerator"/>
 
 </output-generators>
 
--- a/artifacts/doc/conf/generators/longitudinal-diagram-defaults.xml	Wed Feb 28 17:27:15 2018 +0100
+++ b/artifacts/doc/conf/generators/longitudinal-diagram-defaults.xml	Wed Feb 28 18:55:39 2018 +0100
@@ -46,7 +46,7 @@
 
     <!-- S-INFO -->
     <processor class="org.dive4elements.river.artifacts.sinfo.flowdepth.FlowDepthProcessor" axis="flowdepthAxis"/>
-    <processor class="org.dive4elements.river.artifacts.sinfo.flowdepth.TkhProcessor" axis="tkhAxis"/>
+    <processor class="org.dive4elements.river.artifacts.sinfo.common.TkhProcessor" axis="tkhAxis"/>
     
     <chartextender class="org.dive4elements.river.artifacts.sinfo.flowdepth.FlowDepthChartExtender" />
 </longitudinal-defaults>
\ No newline at end of file
--- a/artifacts/doc/conf/generators/longitudinal-diagrams.xml	Wed Feb 28 17:27:15 2018 +0100
+++ b/artifacts/doc/conf/generators/longitudinal-diagrams.xml	Wed Feb 28 18:55:39 2018 +0100
@@ -103,4 +103,17 @@
             <arg expr="artifact.river"/>
         </subtitle>
     </output-generator>
+
+    <output-generator
+        names="sinfo_tkk,sinfo_tkk_chartinfo"
+        class="org.dive4elements.river.exports.LongitudinalSectionGenerator2"
+        converter="org.dive4elements.river.exports.DiagramAttributes">
+        <title key="sinfo.chart.tkh.section.title" default="Transportkörperhöhen (DEFAULT)"/>
+        &longitudinal-defaults;
+        <processor class="org.dive4elements.river.exports.process.ManualPointsProcessor"
+            axis="FlowDepth"/>
+        <subtitle key="chart.w_differences.subtitle" default="-">
+            <arg expr="artifact.river"/>
+        </subtitle>
+    </output-generator>
 </longitudinal-diagrams>
\ No newline at end of file
--- a/artifacts/doc/conf/meta-data.xml	Wed Feb 28 17:27:15 2018 +0100
+++ b/artifacts/doc/conf/meta-data.xml	Wed Feb 28 18:55:39 2018 +0100
@@ -121,6 +121,9 @@
                   <dc:when test="$out = 'sinfo_flow_depth'">
                     <dc:call-macro name="annotations"/>
                   </dc:when>
+                  <dc:when test="$out = 'sinfo_tkk'">
+                    <dc:call-macro name="annotations"/>
+                  </dc:when>
                 </dc:choose>
               </dc:iterate>
             </dc:when>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/AbstractSInfoCalculationResults.java	Wed Feb 28 18:55:39 2018 +0100
@@ -0,0 +1,67 @@
+/** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
+ * Software engineering by
+ *  Björnsen Beratende Ingenieure GmbH
+ *  Dr. Schumacher Ingenieurbüro für Wasser und Umwelt
+ *
+ * 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.sinfo.common;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.commons.lang.math.DoubleRange;
+import org.dive4elements.river.artifacts.sinfo.util.RiverInfo;
+
+/**
+ * @author Gernot Belger
+ */
+public abstract class AbstractSInfoCalculationResults<ROW extends AbstractSInfoResultRow, RESULT extends AbstractSInfoCalculationResult<ROW>> implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private final List<RESULT> results = new ArrayList<>();
+
+    private final String calcModeLabel;
+
+    private final String user;
+
+    private final RiverInfo river;
+
+    private final DoubleRange calcRange;
+
+    public AbstractSInfoCalculationResults(final String calcModeLabel, final String user, final RiverInfo river, final DoubleRange calcRange) {
+        this.calcModeLabel = calcModeLabel;
+        this.user = user;
+        this.river = river;
+        this.calcRange = calcRange;
+    }
+
+    public final String getCalcModeLabel() {
+        return this.calcModeLabel;
+    }
+
+    public final String getUser() {
+        return this.user;
+    }
+
+    public final RiverInfo getRiver() {
+        return this.river;
+    }
+
+    public final DoubleRange getCalcRange() {
+        return this.calcRange;
+    }
+
+    public final void addResult(final RESULT result) {
+        this.results.add(result);
+    }
+
+    public final List<RESULT> getResults() {
+        return Collections.unmodifiableList(this.results);
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/AbstractSInfoProcessor.java	Wed Feb 28 18:55:39 2018 +0100
@@ -0,0 +1,74 @@
+/* Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
+ * Software engineering by
+ *  Björnsen Beratende Ingenieure GmbH
+ *  Dr. Schumacher Ingenieurbüro für Wasser und Umwelt
+ *
+ * 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.sinfo.common;
+
+import java.util.Set;
+
+import org.apache.log4j.Logger;
+import org.dive4elements.artifactdatabase.state.ArtifactAndFacet;
+import org.dive4elements.river.exports.DiagramGenerator;
+import org.dive4elements.river.exports.process.DefaultProcessor;
+import org.dive4elements.river.themes.ThemeDocument;
+
+/**
+ * Abstraction for some processor implementation within S-INFO. Probably this abstraction could also be used for other
+ * cases as well.
+ *
+ * @author Gernot Belger
+ *
+ */
+public abstract class AbstractSInfoProcessor extends DefaultProcessor {
+
+    private final static Logger log = Logger.getLogger(AbstractSInfoProcessor.class);
+
+    private String yAxisLabel;
+
+    private final Set<String> handled_facet_types;
+
+    private final String i18n_axis_label;
+
+    public AbstractSInfoProcessor(final String i18n_axis_label, final Set<String> handled_facet_types) {
+        this.i18n_axis_label = i18n_axis_label;
+        this.handled_facet_types = handled_facet_types;
+    }
+
+    @Override
+    public final void doOut(final DiagramGenerator generator, final ArtifactAndFacet bundle, final ThemeDocument theme, final boolean visible) {
+        try {
+            this.yAxisLabel = generateSeries(generator, bundle, theme, visible);
+        }
+        catch (final Exception e) {
+            log.error(e.getMessage(), e);
+        }
+    }
+
+    /**
+     * @return The axis label
+     */
+    protected abstract String generateSeries(final DiagramGenerator generator, final ArtifactAndFacet bundle, final ThemeDocument theme, final boolean visible);
+
+    @Override
+    public final boolean canHandle(final String facettype) {
+        return this.handled_facet_types.contains(facettype);
+    }
+
+    @Override
+    public final String getAxisLabel(final DiagramGenerator generator) {
+        if (this.yAxisLabel != null && !this.yAxisLabel.isEmpty()) {
+            // REMARK/UNINTENDED: yAxisLabel may also be a resolved message (side-effect of StyledXYSeries#putMetadata),
+            // and cannot be resolved, so we need to give the resolved value as default
+            // FIXME: In other implementations (i.e. FlowVelocityProcessor), an explicit (German) default label is given here,
+            // probably the English version will also show German (CHECK)
+            return generator.msg(this.yAxisLabel, this.yAxisLabel);
+        }
+        return generator.msg(this.i18n_axis_label, "MISSING");
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/SInfoResultFacet.java	Wed Feb 28 18:55:39 2018 +0100
@@ -0,0 +1,65 @@
+/* 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.sinfo.common;
+
+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.model.CalculationResult;
+import org.dive4elements.river.artifacts.model.DataFacet;
+import org.dive4elements.river.artifacts.states.DefaultState.ComputeType;
+
+/**
+ * Facet of a FlowDepth curve.
+ */
+public final class SInfoResultFacet extends DataFacet {
+
+    private static final long serialVersionUID = 1L;
+
+    private static Logger log = Logger.getLogger(SInfoResultFacet.class);
+
+    public SInfoResultFacet() {
+        // required for clone operation deepCopy()
+    }
+
+    public SInfoResultFacet(final int idx, final String name, final String description, final String yAxisLabelKey, final ComputeType type, final String stateId,
+            final String hash) {
+        super(idx, name, description, type, hash, stateId);
+        this.metaData.put("X", "sinfo.chart.km.xaxis.label");
+        this.metaData.put("Y", yAxisLabelKey);
+    }
+
+    @Override
+    public Object getData(final Artifact artifact, final CallContext context) {
+        log.debug("Get data for result at index: " + this.index);
+
+        final D4EArtifact flys = (D4EArtifact) artifact;
+
+        final CalculationResult res = (CalculationResult) flys.compute(context, this.hash, this.stateId, this.type, false);
+
+        final AbstractSInfoCalculationResults<?, ?> data = (AbstractSInfoCalculationResults<?, ?>) res.getData();
+
+        return data.getResults().get(this.index);
+    }
+
+    /** Copy deeply. */
+    @Override
+    public Facet deepCopy() {
+        // FIXME: why not simply use the full constructor instead?
+        final SInfoResultFacet copy = new SInfoResultFacet();
+        // 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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/TkhProcessor.java	Wed Feb 28 18:55:39 2018 +0100
@@ -0,0 +1,87 @@
+/* Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
+ * Software engineering by
+ *  Björnsen Beratende Ingenieure GmbH
+ *  Dr. Schumacher Ingenieurbüro für Wasser und Umwelt
+ *
+ * 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.sinfo.common;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.dive4elements.artifactdatabase.state.ArtifactAndFacet;
+import org.dive4elements.artifactdatabase.state.Facet;
+import org.dive4elements.artifacts.CallContext;
+import org.dive4elements.river.artifacts.resources.Resources;
+import org.dive4elements.river.artifacts.states.DefaultState.ComputeType;
+import org.dive4elements.river.exports.DiagramGenerator;
+import org.dive4elements.river.exports.StyledSeriesBuilder;
+import org.dive4elements.river.jfree.StyledAreaSeriesCollection;
+import org.dive4elements.river.jfree.StyledXYSeries;
+import org.dive4elements.river.themes.ThemeDocument;
+
+public final class TkhProcessor extends AbstractSInfoProcessor {
+
+    public static String FACET_TKH = "sinfo_flow_depth.tkh";
+
+    public static final String I18N_FACET_TKH_DESCRIPTION = "sinfo.facet.tkh.description";
+
+    public static final String SINFO_CHART_TKX_YAXIS_LABEL = "sinfo.chart.tkh.yaxis.label";
+
+    private static final Set<String> HANDLED_FACET_TYPES = new HashSet<>();
+
+    static {
+        HANDLED_FACET_TYPES.add(FACET_TKH);
+    }
+
+    private static final String I18N_AXIS_LABEL = "sinfo.chart.tkh.section.yaxis.label";
+
+    public TkhProcessor() {
+        super(I18N_AXIS_LABEL, HANDLED_FACET_TYPES);
+    }
+
+    @Override
+    protected String generateSeries(final DiagramGenerator generator, final ArtifactAndFacet bundle, final ThemeDocument theme, final boolean visible) {
+        final CallContext context = generator.getCallContext();
+
+        final String facetName = bundle.getFacetName();
+        final AbstractSInfoCalculationResult<?> data = (AbstractSInfoCalculationResult<?>) bundle.getData(context);
+        if (data == null) {
+            // Check has been here before so we keep it for security reasons
+            // this should never happen though.
+            throw new IllegalStateException("Data is null for facet: " + facetName);
+        }
+
+        final StyledXYSeries seriesUp = new StyledXYSeries(bundle.getFacetDescription(), theme);
+        final double[][] pointsUp = data.getTkhUpPoints();
+        StyledSeriesBuilder.addPoints(seriesUp, pointsUp, true);
+
+        // REMARK: we add " " because the description is misused as id, which must be unique.
+        final StyledXYSeries seriesDown = new StyledXYSeries(bundle.getFacetDescription() + " ", theme);
+        final double[][] pointsDown = data.getTkhDownPoints();
+        StyledSeriesBuilder.addPoints(seriesDown, pointsDown, true);
+
+        final StyledAreaSeriesCollection area = new StyledAreaSeriesCollection(theme);
+        area.setMode(StyledAreaSeriesCollection.FILL_MODE.BETWEEN);
+        area.addSeries(seriesUp);
+        area.addSeries(seriesDown);
+
+        generator.addAreaSeries(area, getAxisName(), visible);
+
+        return null;
+    }
+
+    public static Facet createTkhFacet(final CallContext context, final String hash, final String id, final AbstractSInfoCalculationResult<?> result,
+            final int index) {
+
+        final String facetTkhDescription = Resources.getMsg(context.getMeta(), I18N_FACET_TKH_DESCRIPTION, I18N_FACET_TKH_DESCRIPTION,
+                result.getLabel());
+        // FIXME: doe not work yet...
+        return new SInfoResultFacet(index, TkhProcessor.FACET_TKH, facetTkhDescription, TkhProcessor.SINFO_CHART_TKX_YAXIS_LABEL, ComputeType.ADVANCE, id,
+                hash);
+    }
+}
\ No newline at end of file
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/AbstractSInfoProcessor.java	Wed Feb 28 17:27:15 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,74 +0,0 @@
-/* Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
- * Software engineering by
- *  Björnsen Beratende Ingenieure GmbH
- *  Dr. Schumacher Ingenieurbüro für Wasser und Umwelt
- *
- * 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.sinfo.flowdepth;
-
-import java.util.Set;
-
-import org.apache.log4j.Logger;
-import org.dive4elements.artifactdatabase.state.ArtifactAndFacet;
-import org.dive4elements.river.exports.DiagramGenerator;
-import org.dive4elements.river.exports.process.DefaultProcessor;
-import org.dive4elements.river.themes.ThemeDocument;
-
-/**
- * Abstraction for some processor implementation within S-INFO. Probably this abstraction could also be used for other
- * cases as well.
- *
- * @author Gernot Belger
- *
- */
-abstract class AbstractSInfoProcessor extends DefaultProcessor {
-
-    private final static Logger log = Logger.getLogger(AbstractSInfoProcessor.class);
-
-    private String yAxisLabel;
-
-    private final Set<String> handled_facet_types;
-
-    private final String i18n_axis_label;
-
-    public AbstractSInfoProcessor(final String i18n_axis_label, final Set<String> handled_facet_types) {
-        this.i18n_axis_label = i18n_axis_label;
-        this.handled_facet_types = handled_facet_types;
-    }
-
-    @Override
-    public final void doOut(final DiagramGenerator generator, final ArtifactAndFacet bundle, final ThemeDocument theme, final boolean visible) {
-        try {
-            this.yAxisLabel = generateSeries(generator, bundle, theme, visible);
-        }
-        catch (final Exception e) {
-            log.error(e.getMessage(), e);
-        }
-    }
-
-    /**
-     * @return The axis label
-     */
-    protected abstract String generateSeries(final DiagramGenerator generator, final ArtifactAndFacet bundle, final ThemeDocument theme, final boolean visible);
-
-    @Override
-    public final boolean canHandle(final String facettype) {
-        return this.handled_facet_types.contains(facettype);
-    }
-
-    @Override
-    public final String getAxisLabel(final DiagramGenerator generator) {
-        if (this.yAxisLabel != null && !this.yAxisLabel.isEmpty()) {
-            // REMARK/UNINTENDED: yAxisLabel may also be a resolved message (side-effect of StyledXYSeries#putMetadata),
-            // and cannot be resolved, so we need to give the resolved value as default
-            // FIXME: In other implementations (i.e. FlowVelocityProcessor), an explicit (German) default label is given here,
-            // probably the English version will also show German (CHECK)
-            return generator.msg(this.yAxisLabel, this.yAxisLabel);
-        }
-        return generator.msg(this.i18n_axis_label, "MISSING");
-    }
-}
\ No newline at end of file
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculationResults.java	Wed Feb 28 17:27:15 2018 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculationResults.java	Wed Feb 28 18:55:39 2018 +0100
@@ -9,66 +9,27 @@
  */
 package org.dive4elements.river.artifacts.sinfo.flowdepth;
 
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
 import org.apache.commons.lang.math.DoubleRange;
+import org.dive4elements.river.artifacts.sinfo.common.AbstractSInfoCalculationResults;
 import org.dive4elements.river.artifacts.sinfo.util.RiverInfo;
 
 /**
  * @author Gernot Belger
  */
-final class FlowDepthCalculationResults implements Serializable {
+final class FlowDepthCalculationResults extends AbstractSInfoCalculationResults<FlowDepthRow, FlowDepthCalculationResult> {
+
     private static final long serialVersionUID = 1L;
 
-    private final List<FlowDepthCalculationResult> results = new ArrayList<>();
-
-    private final String calcModeLabel;
-
-    private final String user;
-
-    private final RiverInfo river;
-
     private final boolean useTkh;
 
-    private final DoubleRange calcRange;
-
     public FlowDepthCalculationResults(final String calcModeLabel, final String user, final RiverInfo river, final DoubleRange calcRange,
             final boolean useTkh) {
-        this.calcModeLabel = calcModeLabel;
-        this.user = user;
-        this.river = river;
-        this.calcRange = calcRange;
-        this.useTkh = useTkh;
-    }
+        super(calcModeLabel, user, river, calcRange);
 
-    public String getCalcModeLabel() {
-        return this.calcModeLabel;
-    }
-
-    public String getUser() {
-        return this.user;
-    }
-
-    public RiverInfo getRiver() {
-        return this.river;
-    }
-
-    public DoubleRange getCalcRange() {
-        return this.calcRange;
+        this.useTkh = useTkh;
     }
 
     public boolean isUseTkh() {
         return this.useTkh;
     }
-
-    void addResult(final FlowDepthCalculationResult result) {
-        this.results.add(result);
-    }
-
-    public List<FlowDepthCalculationResult> getResults() {
-        return Collections.unmodifiableList(this.results);
-    }
 }
\ No newline at end of file
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthFacet.java	Wed Feb 28 17:27:15 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
-/* 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.sinfo.flowdepth;
-
-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.model.CalculationResult;
-import org.dive4elements.river.artifacts.model.DataFacet;
-import org.dive4elements.river.artifacts.states.DefaultState.ComputeType;
-
-/**
- * Facet of a FlowDepth curve.
- */
-public class FlowDepthFacet extends DataFacet {
-
-    private static final long serialVersionUID = 1L;
-
-    private static Logger log = Logger.getLogger(FlowDepthFacet.class);
-
-    public FlowDepthFacet() {
-        // required for clone operation deepCopy()
-    }
-
-    public FlowDepthFacet(final int idx, final String name, final String description, final String yAxisLabelKey, final ComputeType type, final String stateId,
-            final String hash) {
-        super(idx, name, description, type, hash, stateId);
-        this.metaData.put("X", "sinfo.chart.flow_depth.xaxis.label");
-        this.metaData.put("Y", yAxisLabelKey);
-    }
-
-    @Override
-    public Object getData(final Artifact artifact, final CallContext context) {
-        log.debug("Get data for flow velocity at index: " + this.index);
-
-        final D4EArtifact flys = (D4EArtifact) artifact;
-
-        final CalculationResult res = (CalculationResult) flys.compute(context, this.hash, this.stateId, this.type, false);
-
-        final FlowDepthCalculationResults data = (FlowDepthCalculationResults) res.getData();
-
-        return data.getResults().get(this.index);
-    }
-
-    /** Copy deeply. */
-    @Override
-    public Facet deepCopy() {
-        // FIXME: why not simply use the full constructor instead?
-        final FlowDepthFacet copy = new FlowDepthFacet();
-        // 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/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthProcessor.java	Wed Feb 28 17:27:15 2018 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthProcessor.java	Wed Feb 28 18:55:39 2018 +0100
@@ -22,6 +22,7 @@
 import org.dive4elements.river.artifacts.context.RiverContext;
 import org.dive4elements.river.artifacts.math.MovingAverage;
 import org.dive4elements.river.artifacts.model.ZoomScale;
+import org.dive4elements.river.artifacts.sinfo.common.AbstractSInfoProcessor;
 import org.dive4elements.river.exports.DiagramGenerator;
 import org.dive4elements.river.exports.StyledSeriesBuilder;
 import org.dive4elements.river.jfree.StyledXYSeries;
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthState.java	Wed Feb 28 17:27:15 2018 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthState.java	Wed Feb 28 18:55:39 2018 +0100
@@ -22,6 +22,8 @@
 import org.dive4elements.river.artifacts.model.ReportFacet;
 import org.dive4elements.river.artifacts.resources.Resources;
 import org.dive4elements.river.artifacts.sinfo.SINFOArtifact;
+import org.dive4elements.river.artifacts.sinfo.common.SInfoResultFacet;
+import org.dive4elements.river.artifacts.sinfo.common.TkhProcessor;
 import org.dive4elements.river.artifacts.states.DefaultState;
 
 /** State in which a waterlevel has been calculated. */
@@ -36,12 +38,9 @@
 
     private static final String I18N_FACET_FLOW_DEPTH_TKH_FILTERED_DESCRIPTION = "sinfo.facet.flow_depth.tkh.filtered.description";
 
-    private static final String I18N_FACET_TKH_DESCRIPTION = "sinfo.facet.tkh.description";
 
     private static final String SINFO_CHART_FLOW_DEPTH_YAXIS_LABEL = "sinfo.chart.flow_depth.yaxis.label";
 
-    private static final String SINFO_CHART_TKX_YAXIS_LABEL = "sinfo.chart.tkh.yaxis.label";
-
     /**
      * From this state can only be continued trivially.
      */
@@ -94,29 +93,18 @@
             /* filtered (zoom dependent mean) flow depth */
             final String facetFlowDepthFilteredDescription = Resources.getMsg(context.getMeta(), I18N_FACET_FLOW_DEPTH_FILTERED_DESCRIPTION,
                     I18N_FACET_FLOW_DEPTH_FILTERED_DESCRIPTION, result.getLabel());
-            facets.add(new FlowDepthFacet(index, FlowDepthProcessor.FACET_FLOW_DEPTH_FILTERED, facetFlowDepthFilteredDescription,
+            facets.add(new SInfoResultFacet(index, FlowDepthProcessor.FACET_FLOW_DEPTH_FILTERED, facetFlowDepthFilteredDescription,
                     SINFO_CHART_FLOW_DEPTH_YAXIS_LABEL, ComputeType.ADVANCE, this.id, hash));
 
             if (results.isUseTkh()) {
                 /* filtered (zoom dependent mean) flow depth including tkh */
                 final String facetFlowDepthTkhFilteredDescription = Resources.getMsg(context.getMeta(), I18N_FACET_FLOW_DEPTH_TKH_FILTERED_DESCRIPTION,
                         I18N_FACET_FLOW_DEPTH_TKH_FILTERED_DESCRIPTION, result.getLabel());
-                facets.add(new FlowDepthFacet(index, FlowDepthProcessor.FACET_FLOW_DEPTH_TKH_FILTERED, facetFlowDepthTkhFilteredDescription,
+                facets.add(new SInfoResultFacet(index, FlowDepthProcessor.FACET_FLOW_DEPTH_TKH_FILTERED, facetFlowDepthTkhFilteredDescription,
                         SINFO_CHART_FLOW_DEPTH_YAXIS_LABEL, ComputeType.ADVANCE, this.id, hash));
 
-                // FIXME: add other themes
-                // - Streckenfavoriten
-
-                // FIXME:
-                // - Gemittelte Linie der Fließtiefe mitsamt TKH
-                // - Transportkörperhöhen (oben/unten/schraffur)
-                final String facetTkhDescription = Resources.getMsg(context.getMeta(), I18N_FACET_TKH_DESCRIPTION, I18N_FACET_TKH_DESCRIPTION,
-                        result.getLabel());
-                facets.add(new FlowDepthFacet(index, TkhProcessor.FACET_TKH, facetTkhDescription, SINFO_CHART_TKX_YAXIS_LABEL, ComputeType.ADVANCE, this.id,
-                        hash));
+                facets.add(TkhProcessor.createTkhFacet(context, hash, this.id, result, index));
             }
-
-            // FIXME: Datenkorbkonfiguration
         }
 
         if (!resultList.isEmpty()) {
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/TkhProcessor.java	Wed Feb 28 17:27:15 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-/* Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
- * Software engineering by
- *  Björnsen Beratende Ingenieure GmbH
- *  Dr. Schumacher Ingenieurbüro für Wasser und Umwelt
- *
- * 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.sinfo.flowdepth;
-
-import java.util.HashSet;
-import java.util.Set;
-
-import org.dive4elements.artifactdatabase.state.ArtifactAndFacet;
-import org.dive4elements.artifacts.CallContext;
-import org.dive4elements.river.exports.DiagramGenerator;
-import org.dive4elements.river.exports.StyledSeriesBuilder;
-import org.dive4elements.river.jfree.StyledAreaSeriesCollection;
-import org.dive4elements.river.jfree.StyledXYSeries;
-import org.dive4elements.river.themes.ThemeDocument;
-
-public final class TkhProcessor extends AbstractSInfoProcessor {
-
-    static String FACET_TKH = "sinfo_flow_depth.tkh";
-
-    private static final Set<String> HANDLED_FACET_TYPES = new HashSet<>();
-
-    static {
-        HANDLED_FACET_TYPES.add(FACET_TKH);
-    }
-
-    private static final String I18N_AXIS_LABEL = "sinfo.chart.tkh.section.yaxis.label";
-
-    public TkhProcessor() {
-        super(I18N_AXIS_LABEL, HANDLED_FACET_TYPES);
-    }
-
-    @Override
-    protected String generateSeries(final DiagramGenerator generator, final ArtifactAndFacet bundle, final ThemeDocument theme, final boolean visible) {
-        final CallContext context = generator.getCallContext();
-
-        final String facetName = bundle.getFacetName();
-        final FlowDepthCalculationResult data = (FlowDepthCalculationResult) bundle.getData(context);
-        if (data == null) {
-            // Check has been here before so we keep it for security reasons
-            // this should never happen though.
-            throw new IllegalStateException("Data is null for facet: " + facetName);
-        }
-
-        final StyledXYSeries seriesUp = new StyledXYSeries(bundle.getFacetDescription(), theme);
-        final double[][] pointsUp = data.getTkhUpPoints();
-        StyledSeriesBuilder.addPoints(seriesUp, pointsUp, true);
-
-        // REMARK: we add " " because the description is misused as id, which must be unique.
-        final StyledXYSeries seriesDown = new StyledXYSeries(bundle.getFacetDescription() + " ", theme);
-        final double[][] pointsDown = data.getTkhDownPoints();
-        StyledSeriesBuilder.addPoints(seriesDown, pointsDown, true);
-
-        final StyledAreaSeriesCollection area = new StyledAreaSeriesCollection(theme);
-        area.setMode(StyledAreaSeriesCollection.FILL_MODE.BETWEEN);
-        area.addSeries(seriesUp);
-        area.addSeries(seriesDown);
-
-        generator.addAreaSeries(area, getAxisName(), visible);
-
-        return null;
-    }
-}
\ No newline at end of file
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhcalculation/TkhCalculator.java	Wed Feb 28 17:27:15 2018 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhcalculation/TkhCalculator.java	Wed Feb 28 18:55:39 2018 +0100
@@ -169,8 +169,7 @@
         if (Double.isNaN(tkh) || (tkh < 0)) {
             // TODO: ggf. station in Fehlermeldung?
 
-            // FIXME: Fehlermeldung nicht korrekt, passiert mit Wasserspiegel 'MHQ' und 'QP-1993': alle Daten (auch Abfluss)
-            // vorhanden, aber tkh negativ...
+            // FIXME: Fehlermeldung nicht korrekt, passiert mit Wasserspiegel 'MHQ' und 'QP-1993
             final String message = Resources.getMsg(this.context.getMeta(), "sinfo_calc_flow_depth.warning.missingQ", null, this.problemLabel);
             this.problems.addProblem(km, message);
 
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/TkhCalculation.java	Wed Feb 28 17:27:15 2018 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/TkhCalculation.java	Wed Feb 28 18:55:39 2018 +0100
@@ -11,6 +11,7 @@
 
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.List;
 
 import org.apache.commons.lang.math.DoubleRange;
 import org.dive4elements.artifacts.CallContext;
@@ -87,8 +88,11 @@
 
         /* copy all problems */
         final Calculation winfoProblems = waterlevelData.getReport();
-        for (final Problem problem : winfoProblems.getProblems()) {
-            problems.addProblem(problem);
+        final List<Problem> problems2 = winfoProblems.getProblems();
+        if (problems2 != null) {
+            for (final Problem problem : problems2) {
+                problems.addProblem(problem);
+            }
         }
 
         return (WQKms[]) waterlevelData.getData();
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/TkhCalculationResults.java	Wed Feb 28 17:27:15 2018 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/TkhCalculationResults.java	Wed Feb 28 18:55:39 2018 +0100
@@ -9,58 +9,18 @@
  */
 package org.dive4elements.river.artifacts.sinfo.tkhstate;
 
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
 import org.apache.commons.lang.math.DoubleRange;
+import org.dive4elements.river.artifacts.sinfo.common.AbstractSInfoCalculationResults;
 import org.dive4elements.river.artifacts.sinfo.util.RiverInfo;
 
 /**
  * @author Gernot Belger
  */
-final class TkhCalculationResults implements Serializable {
-    private static final long serialVersionUID = 1L;
-
-    private final List<TkhCalculationResult> results = new ArrayList<>();
+final class TkhCalculationResults extends AbstractSInfoCalculationResults<TkhResultRow, TkhCalculationResult> {
 
-    private final String calcModeLabel;
-
-    private final String user;
-
-    private final RiverInfo river;
-
-    private final DoubleRange calcRange;
+    private static final long serialVersionUID = 1L;
 
     public TkhCalculationResults(final String calcModeLabel, final String user, final RiverInfo river, final DoubleRange calcRange) {
-        this.calcModeLabel = calcModeLabel;
-        this.user = user;
-        this.river = river;
-        this.calcRange = calcRange;
-    }
-
-    public String getCalcModeLabel() {
-        return this.calcModeLabel;
-    }
-
-    public String getUser() {
-        return this.user;
-    }
-
-    public RiverInfo getRiver() {
-        return this.river;
-    }
-
-    public DoubleRange getCalcRange() {
-        return this.calcRange;
-    }
-
-    void addResult(final TkhCalculationResult result) {
-        this.results.add(result);
-    }
-
-    public List<TkhCalculationResult> getResults() {
-        return Collections.unmodifiableList(this.results);
+        super(calcModeLabel, user, river, calcRange);
     }
 }
\ No newline at end of file
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/TkhState.java	Wed Feb 28 17:27:15 2018 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/TkhState.java	Wed Feb 28 18:55:39 2018 +0100
@@ -14,9 +14,12 @@
 import org.dive4elements.artifacts.CallContext;
 import org.dive4elements.river.artifacts.ChartArtifact;
 import org.dive4elements.river.artifacts.D4EArtifact;
+import org.dive4elements.river.artifacts.model.Calculation;
 import org.dive4elements.river.artifacts.model.CalculationResult;
 import org.dive4elements.river.artifacts.model.EmptyFacet;
+import org.dive4elements.river.artifacts.model.ReportFacet;
 import org.dive4elements.river.artifacts.sinfo.SINFOArtifact;
+import org.dive4elements.river.artifacts.sinfo.common.TkhProcessor;
 import org.dive4elements.river.artifacts.states.DefaultState;
 
 /** State in which a waterlevel has been calculated. */
@@ -27,15 +30,6 @@
 
     private static final long serialVersionUID = 1L;
 
-    private static final String I18N_FACET_FLOW_DEPTH_FILTERED_DESCRIPTION = "sinfo.facet.flow_depth.filtered.description";
-
-    private static final String I18N_FACET_FLOW_DEPTH_TKH_FILTERED_DESCRIPTION = "sinfo.facet.flow_depth.tkh.filtered.description";
-
-    private static final String I18N_FACET_TKH_DESCRIPTION = "sinfo.facet.tkh.description";
-
-    private static final String SINFO_CHART_FLOW_DEPTH_YAXIS_LABEL = "sinfo.chart.flow_depth.yaxis.label";
-
-    private static final String SINFO_CHART_TKX_YAXIS_LABEL = "sinfo.chart.tkh.yaxis.label";
 
     /**
      * From this state can only be continued trivially.
@@ -78,47 +72,17 @@
         if (facets == null)
             return res;
 
-        // final FlowDepthCalculationResults results = (FlowDepthCalculationResults) res.getData();
-        //
-        // /* add themes for chart, for each result */
-        // final List<FlowDepthCalculationResult> resultList = results.getResults();
-        // for (int index = 0; index < resultList.size(); index++) {
-        //
-        // final FlowDepthCalculationResult result = resultList.get(index);
-        //
-        // /* filtered (zoom dependent mean) flow depth */
-        // final String facetFlowDepthFilteredDescription = Resources.getMsg(context.getMeta(),
-        // I18N_FACET_FLOW_DEPTH_FILTERED_DESCRIPTION,
-        // I18N_FACET_FLOW_DEPTH_FILTERED_DESCRIPTION, result.getLabel());
-        // facets.add(new FlowDepthFacet(index, FlowDepthProcessor.FACET_FLOW_DEPTH_FILTERED, facetFlowDepthFilteredDescription,
-        // SINFO_CHART_FLOW_DEPTH_YAXIS_LABEL, ComputeType.ADVANCE, this.id, hash));
-        //
-        // if (results.isUseTkh()) {
-        // /* filtered (zoom dependent mean) flow depth including tkh */
-        // final String facetFlowDepthTkhFilteredDescription = Resources.getMsg(context.getMeta(),
-        // I18N_FACET_FLOW_DEPTH_TKH_FILTERED_DESCRIPTION,
-        // I18N_FACET_FLOW_DEPTH_TKH_FILTERED_DESCRIPTION, result.getLabel());
-        // facets.add(new FlowDepthFacet(index, FlowDepthProcessor.FACET_FLOW_DEPTH_TKH_FILTERED,
-        // facetFlowDepthTkhFilteredDescription,
-        // SINFO_CHART_FLOW_DEPTH_YAXIS_LABEL, ComputeType.ADVANCE, this.id, hash));
-        //
-        // // FIXME: add other themes
-        // // - Streckenfavoriten
-        //
-        // // FIXME:
-        // // - Gemittelte Linie der Fließtiefe mitsamt TKH
-        // // - Transportkörperhöhen (oben/unten/schraffur)
-        // final String facetTkhDescription = Resources.getMsg(context.getMeta(), I18N_FACET_TKH_DESCRIPTION,
-        // I18N_FACET_TKH_DESCRIPTION,
-        // result.getLabel());
-        // facets.add(new FlowDepthFacet(index, TkhProcessor.FACET_TKH, facetTkhDescription, SINFO_CHART_TKX_YAXIS_LABEL,
-        // ComputeType.ADVANCE, this.id,
-        // hash));
-        // }
-        //
-        // // FIXME: Datenkorbkonfiguration
-        // }
-        //
+        final TkhCalculationResults results = (TkhCalculationResults) res.getData();
+
+        /* add themes for chart, for each result */
+        final List<TkhCalculationResult> resultList = results.getResults();
+        for (int index = 0; index < resultList.size(); index++) {
+
+            final TkhCalculationResult result = resultList.get(index);
+
+            facets.add(TkhProcessor.createTkhFacet(context, hash, this.id, result, index));
+        }
+
         // if (!resultList.isEmpty()) {
         // 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);
@@ -126,15 +90,13 @@
         // facets.add(csv);
         // facets.add(pdf);
         // }
-        //
-        // final Calculation report = res.getReport();
-        //
-        // if (report.hasProblems()) {
-        // facets.add(new ReportFacet(ComputeType.ADVANCE, hash, this.id));
-        // }
-        //
-        // return res;
-        return null;
+
+        final Calculation report = res.getReport();
+
+        if (report.hasProblems())
+            facets.add(new ReportFacet(ComputeType.ADVANCE, hash, this.id));
+
+        return res;
     }
 
     private CalculationResult doCompute(final SINFOArtifact sinfo, final CallContext context, final Object old) {
--- a/artifacts/src/main/resources/messages.properties	Wed Feb 28 17:27:15 2018 +0100
+++ b/artifacts/src/main/resources/messages.properties	Wed Feb 28 18:55:39 2018 +0100
@@ -793,6 +793,7 @@
 state.sinfo.distance = Choose the range
 help.state.sinfo.distance = ${help.url}/OnlineHilfe/help.state.sinfo.distance
 
+state.sinfo.wq = Input for W/Q data
 help.state.sinfo.wq=${help.url}/OnlineHilfe/SINFO#help.state.sinfo.wq
 
 state.sinfo.transport_bodies_heights=Transportk\u00f6rperh\u00f6hen
@@ -852,13 +853,14 @@
 
 sinfo.chart.flow_depth.section.title=h-L\u00e4ngsschnitt
 
-sinfo.chart.flow_depth.xaxis.label = {0}-km
+sinfo.chart.km.xaxis.label = {0}-km
 sinfo.chart.flow_depth.yaxis.label = Flie\u00dftiefe [m]
 
 sinfo.chart.flow_depth.section.yaxis.label=Flie\u00dftiefe [m]
 sinfo.facet.flow_depth.filtered.description = h ({0})
 sinfo.facet.flow_depth.tkh.filtered.description = h + \u0394d ({0})
-	
+
+sinfo.chart.tkh.section.title=Transportk\u00f6rperh\u00f6hen
 sinfo.chart.tkh.section.yaxis.label = Transportk\u00f6rperh\u00f6hen [cm]
 sinfo.chart.tkh.yaxis.label = Transportk\u00f6rperh\u00f6hen [cm]
 sinfo.facet.tkh.description = \u0394d ({0})
\ No newline at end of file
--- a/artifacts/src/main/resources/messages_de.properties	Wed Feb 28 17:27:15 2018 +0100
+++ b/artifacts/src/main/resources/messages_de.properties	Wed Feb 28 18:55:39 2018 +0100
@@ -799,6 +799,7 @@
 state.sinfo.distance = Wahl der Berechnungsstrecke
 help.state.sinfo.distance = ${help.url}/OnlineHilfe/help.state.sinfo.distance
 
+state.sinfo.wq = Eingabe f\u00fcr W/Q Daten
 help.state.sinfo.wq=${help.url}/OnlineHilfe/SINFO#help.state.sinfo.wq
 
 state.sinfo.transport_bodies_heights=Transportk\u00f6rperh\u00f6hen
@@ -860,13 +861,14 @@
 
 sinfo.chart.flow_depth.section.title=h-L\u00e4ngsschnitt
 
-sinfo.chart.flow_depth.xaxis.label = {0}-km
+sinfo.chart.km.xaxis.label = {0}-km
 sinfo.chart.flow_depth.yaxis.label = Flie\u00dftiefe [m]
 
 sinfo.chart.flow_depth.section.yaxis.label=Flie\u00dftiefe [m]
 sinfo.facet.flow_depth.filtered.description = h ({0})
 sinfo.facet.flow_depth.tkh.filtered.description = h + \u0394d ({0})
 	
+sinfo.chart.tkh.section.title=Transportk\u00f6rperh\u00f6hen
 sinfo.chart.tkh.section.yaxis.label = Transportk\u00f6rperh\u00f6hen [cm]
 sinfo.chart.tkh.yaxis.label = Transportk\u00f6rperh\u00f6hen [cm]
 sinfo.facet.tkh.description = \u0394d ({0})
\ No newline at end of file
--- a/artifacts/src/main/resources/messages_de_DE.properties	Wed Feb 28 17:27:15 2018 +0100
+++ b/artifacts/src/main/resources/messages_de_DE.properties	Wed Feb 28 18:55:39 2018 +0100
@@ -797,6 +797,7 @@
 state.sinfo.distance = Wahl der Berechnungsstrecke
 help.state.sinfo.distance = ${help.url}/OnlineHilfe/help.state.sinfo.distance
 
+state.sinfo.wq = Eingabe f\u00fcr W/Q Daten
 help.state.sinfo.wq=${help.url}/OnlineHilfe/SINFO#help.state.sinfo.wq
 
 state.sinfo.transport_bodies_heights=Transportk\u00f6rperh\u00f6hen
@@ -856,13 +857,14 @@
 
 sinfo.chart.flow_depth.section.title=h-L\u00e4ngsschnitt
 
-sinfo.chart.flow_depth.xaxis.label = {0}-km
+sinfo.chart.km.xaxis.label = {0}-km
 sinfo.chart.flow_depth.yaxis.label = Flie\u00dftiefe [m]
 
 sinfo.chart.flow_depth.section.yaxis.label=Flie\u00dftiefe [m]
 sinfo.facet.flow_depth.filtered.description = h ({0})
 sinfo.facet.flow_depth.tkh.filtered.description = h + \u0394d ({0})
 	
+sinfo.chart.tkh.section.title=Transportk\u00f6rperh\u00f6hen
 sinfo.chart.tkh.section.yaxis.label = Transportk\u00f6rperh\u00f6hen [cm]
 sinfo.chart.tkh.yaxis.label = Transportk\u00f6rperh\u00f6hen [cm]
 sinfo.facet.tkh.description = \u0394d ({0})
\ No newline at end of file
--- a/artifacts/src/main/resources/messages_en.properties	Wed Feb 28 17:27:15 2018 +0100
+++ b/artifacts/src/main/resources/messages_en.properties	Wed Feb 28 18:55:39 2018 +0100
@@ -794,6 +794,7 @@
 state.sinfo.distance = Choose the range
 help.state.sinfo.distance = ${help.url}/OnlineHilfe/help.state.sinfo.distance
 
+state.sinfo.wq = Input for W/Q data
 help.state.sinfo.wq=${help.url}/OnlineHilfe/SINFO#help.state.sinfo.wq
 
 state.sinfo.transport_bodies_heights=Transportk\u00f6rperh\u00f6hen
@@ -853,13 +854,14 @@
 
 sinfo.chart.flow_depth.section.title=h-L\u00e4ngsschnitt
 
-sinfo.chart.flow_depth.xaxis.label = {0}-km
+sinfo.chart.km.xaxis.label = {0}-km
 sinfo.chart.flow_depth.yaxis.label = Flie\u00dftiefe [m]
 
 sinfo.chart.flow_depth.section.yaxis.label=Flie\u00dftiefe [m]
 sinfo.facet.flow_depth.filtered.description = h ({0})
 sinfo.facet.flow_depth.tkh.filtered.description = h + \u0394d ({0})
 	
+sinfo.chart.tkh.section.title=Transportk\u00f6rperh\u00f6hen
 sinfo.chart.tkh.section.yaxis.label = Transportk\u00f6rperh\u00f6hen [cm]
 sinfo.chart.tkh.yaxis.label = Transportk\u00f6rperh\u00f6hen [cm]
 sinfo.facet.tkh.description = \u0394d ({0})
\ No newline at end of file
--- a/gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants.java	Wed Feb 28 17:27:15 2018 +0100
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants.java	Wed Feb 28 18:55:39 2018 +0100
@@ -1436,6 +1436,12 @@
 
     String sinfo_flow_depths();
 
+    String sinfo_tkh_export();
+
+    String sinfo_tkh_report();
+
     String sinfo_tkhs();
+
+    String sinfo_tkk();
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
\ No newline at end of file
--- a/gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants.properties	Wed Feb 28 17:27:15 2018 +0100
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants.properties	Wed Feb 28 18:55:39 2018 +0100
@@ -764,4 +764,8 @@
 sinfo_flow_depth = Flie\u00dftiefen
 sinfo_flowdepth_twinpanel_no_pair_selected = Error - at least one input pair must be selected
 sinfo_flow_depths = Flie\u00dftiefen
-sinfo_tkhs = Transportk\u00f6rperh\u00f6hen
\ No newline at end of file
+
+sinfo_tkh_export = Transportk\u00f6rperh\u00f6hen Export
+sinfo_tkh_report = Transportk\u00f6rperh\u00f6hen Bericht
+sinfo_tkhs = Transportk\u00f6rperh\u00f6hen
+sinfo_tkk = Transportk\u00f6rperh\u00f6hen
\ No newline at end of file
--- a/gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants_de.properties	Wed Feb 28 17:27:15 2018 +0100
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants_de.properties	Wed Feb 28 18:55:39 2018 +0100
@@ -756,4 +756,8 @@
 sinfo_flow_depth = Flie\u00dftiefen
 sinfo_flowdepth_twinpanel_no_pair_selected = Fehler - kein Paar zur Differenzenbildung gew\u00e4hlt.
 sinfo_flow_depths = Flie\u00dftiefen
-sinfo_tkhs = Transportk\u00f6rperh\u00f6hen
\ No newline at end of file
+
+sinfo_tkh_export = Transportk\u00f6rperh\u00f6hen Export
+sinfo_tkh_report = Transportk\u00f6rperh\u00f6hen Bericht
+sinfo_tkhs = Transportk\u00f6rperh\u00f6hen
+sinfo_tkk = Transportk\u00f6rperh\u00f6hen
\ No newline at end of file
--- a/gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants_en.properties	Wed Feb 28 17:27:15 2018 +0100
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants_en.properties	Wed Feb 28 18:55:39 2018 +0100
@@ -793,4 +793,8 @@
 sinfo_flow_depth = Flie\u00dftiefen
 sinfo_flowdepth_twinpanel_no_pair_selected = Error - at least one input pair must be selected
 sinfo_flow_depths = Flie\u00dftiefen
-sinfo_tkhs = Transportk\u00f6rperh\u00f6hen
\ No newline at end of file
+
+sinfo_tkh_export = Transportk\u00f6rperh\u00f6hen Export
+sinfo_tkh_report = Transportk\u00f6rperh\u00f6hen Bericht
+sinfo_tkhs = Transportk\u00f6rperh\u00f6hen
+sinfo_tkk = Transportk\u00f6rperh\u00f6hen
\ No newline at end of file

http://dive4elements.wald.intevation.org