changeset 9200:6393e05a9610

refactoring on processors
author gernotbelger
date Fri, 29 Jun 2018 16:29:23 +0200
parents d177121fc95d
children 491e1a434457
files artifacts/src/main/java/org/dive4elements/river/artifacts/common/AbstractCommonExporter.java artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/collision/CollisionFacet.java artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/AbstractSInfoLineProcessor.java artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/AbstractSInfoProcessor.java artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/CollisionCalcProcessor.java artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/CollisionCountProcessor.java artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/D50Processor.java artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/InfrastructureHeightProcessor.java artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/PredefinedChannelDepthProcessor.java artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/PredefinedChannelWidthProcessor.java artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/PredefinedDepthEvolPerYearProcessor.java artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/PredefinedDepthEvolProcessor.java artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/PredefinedFlowDepthProcessor.java artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/PredefinedTkhProcessor.java artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/TkhProcessor.java
diffstat 15 files changed, 152 insertions(+), 285 deletions(-) [+]
line wrap: on
line diff
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/common/AbstractCommonExporter.java	Fri Jun 29 16:15:43 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/common/AbstractCommonExporter.java	Fri Jun 29 16:29:23 2018 +0200
@@ -93,15 +93,6 @@
 
     protected abstract void writeCSVGlobalMetadata(final ExportContextCSV exportContext, final RESULTS results);
 
-    /**
-     * Formats header with unit and label: msg [unit] (label)
-     */
-    // TODO: REMOVE, because it has moved to ExportContextCSV
-    protected final String msgUnitLabel(final String key, final String unit, final String label) {
-        final String msg = msg(key);
-        return String.format("%s [%s] (%s)", msg, unit, label);
-    }
-
     @Override
     protected final void writePDF(final OutputStream out) {
         doWritePdf(out, this.results);
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/collision/CollisionFacet.java	Fri Jun 29 16:15:43 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/collision/CollisionFacet.java	Fri Jun 29 16:29:23 2018 +0200
@@ -17,6 +17,7 @@
 import org.dive4elements.artifacts.Artifact;
 import org.dive4elements.artifacts.CallContext;
 import org.dive4elements.river.artifacts.D4EArtifact;
+import org.dive4elements.river.artifacts.common.DefaultCalculationResult;
 import org.dive4elements.river.artifacts.common.GeneralResultType;
 import org.dive4elements.river.artifacts.common.ResultRow;
 import org.dive4elements.river.artifacts.model.BlackboardDataFacet;
@@ -63,7 +64,7 @@
             rows.add(ResultRow.create().putValue(GeneralResultType.station, value.getStation()) //
                     .putValue(SInfoResultType.collisionCount, value.getCount()).putValue(SInfoResultType.collisionGaugeW, value.getGaugeW()));
         }
-        return new CollisionCalcOverviewResult(series.getFilename(), rows);
+        return new DefaultCalculationResult(series.getFilename(), rows);
     }
 
     /**
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/AbstractSInfoLineProcessor.java	Fri Jun 29 16:15:43 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/AbstractSInfoLineProcessor.java	Fri Jun 29 16:29:23 2018 +0200
@@ -30,6 +30,15 @@
 import org.dive4elements.river.jfree.StyledXYSeries;
 import org.dive4elements.river.themes.ThemeDocument;
 
+/**
+ *
+ * @author Domenico Nardi Tironi
+ *
+ * @deprecated Use
+ *             {@link AbstractSInfoProcessor#buildSeriesForType(DiagramGenerator, ArtifactAndFacet, ThemeDocument, boolean, org.dive4elements.river.artifacts.common.IResultType, Double)}
+ *             instead
+ */
+@Deprecated
 abstract class AbstractSInfoLineProcessor<RESULT extends AbstractCalculationResult> extends AbstractSInfoProcessor {
 
     private static final double GAP_DISTANCE = 0.101;
@@ -38,6 +47,7 @@
         super(i18nAxisLabel, handledFacetType);
     }
 
+    // FIXME:
     @Override
     protected final String generateSeries(final DiagramGenerator generator, final ArtifactAndFacet bundle, final ThemeDocument theme, final boolean visible) {
 
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/AbstractSInfoProcessor.java	Fri Jun 29 16:15:43 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/AbstractSInfoProcessor.java	Fri Jun 29 16:29:23 2018 +0200
@@ -10,12 +10,25 @@
 
 package org.dive4elements.river.artifacts.sinfo.common;
 
+import java.util.Map;
 import java.util.Set;
 
 import org.apache.log4j.Logger;
 import org.dive4elements.artifactdatabase.state.ArtifactAndFacet;
+import org.dive4elements.artifacts.Artifact;
+import org.dive4elements.artifacts.CallContext;
+import org.dive4elements.river.artifacts.D4EArtifact;
+import org.dive4elements.river.artifacts.access.RiverAccess;
+import org.dive4elements.river.artifacts.common.AbstractCalculationResult;
+import org.dive4elements.river.artifacts.common.IResultType;
+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.exports.DiagramGenerator;
+import org.dive4elements.river.exports.StyledSeriesBuilder;
 import org.dive4elements.river.exports.process.DefaultProcessor;
+import org.dive4elements.river.jfree.StyledAreaSeriesCollection;
+import org.dive4elements.river.jfree.StyledXYSeries;
 import org.dive4elements.river.themes.ThemeDocument;
 
 /**
@@ -27,6 +40,8 @@
  */
 public abstract class AbstractSInfoProcessor extends DefaultProcessor {
 
+    protected static final double GAP_DISTANCE = 0.101;
+
     private final static Logger log = Logger.getLogger(AbstractSInfoProcessor.class);
 
     private String yAxisLabel;
@@ -55,6 +70,103 @@
      */
     protected abstract String generateSeries(final DiagramGenerator generator, final ArtifactAndFacet bundle, final ThemeDocument theme, final boolean visible);
 
+    protected final String buildSeriesForType(final DiagramGenerator generator, final ArtifactAndFacet bundle, final ThemeDocument theme, final boolean visible,
+            final IResultType resultType, final Double gapDistance) {
+        final CallContext context = generator.getContext();
+        final Map<String, String> metaData = bundle.getFacet().getMetaData();
+
+        final Artifact artifact = bundle.getArtifact();
+
+        final StyledXYSeries series = new StyledXYSeries(bundle.getFacetDescription(), theme);
+        series.putMetaData(metaData, artifact, context);
+
+        final String facetName = bundle.getFacetName();
+
+        final AbstractCalculationResult data = (AbstractCalculationResult) 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 double[][] points = generatePoints(context, artifact, data, facetName, resultType);
+
+        if (gapDistance == null)
+            StyledSeriesBuilder.addPoints(series, points, true);
+        else
+            StyledSeriesBuilder.addPoints(series, points, true, gapDistance);
+
+        generator.addAxisSeries(series, getAxisName(), visible);
+
+        return metaData.get("Y");
+    }
+
+    protected final String buildSeriesForTkh(final DiagramGenerator generator, final ArtifactAndFacet bundle, final ThemeDocument theme,
+            final boolean visible) {
+        final CallContext context = generator.getContext();
+
+        final String facetName = bundle.getFacetName();
+        final AbstractTkhCalculationResult data = (AbstractTkhCalculationResult) 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;
+    }
+
+    private Double findRadius(final CallContext context, final Artifact artifact) {
+        final Double start = (Double) context.getContextValue("startkm");
+        final Double end = (Double) context.getContextValue("endkm");
+
+        if (start == null || end == null)
+            return null;
+
+        final RiverContext fc = (RiverContext) context.globalContext();
+        final ZoomScale scales = (ZoomScale) fc.get("zoomscale");
+        final RiverAccess access = new RiverAccess((D4EArtifact) artifact);
+        final String river = access.getRiverName();
+
+        return scales.getRadius(river, start, end);
+    }
+
+    private double[][] generatePoints(final CallContext context, final Artifact artifact, final AbstractCalculationResult data, final String facetName,
+            final IResultType resultType) {
+
+        final double[][] points = data.getStationPoints(resultType);
+        if (facetName.endsWith(".filtered")) {
+            final Double radius = findRadius(context, artifact);
+            return movingAverage(radius, points);
+        }
+
+        return points;
+    }
+
+    private double[][] movingAverage(final Double radius, final double[][] points) {
+
+        if (radius == null)
+            return points;
+
+        return MovingAverage.weighted(points, radius);
+    }
+
     @Override
     public final boolean canHandle(final String facettype) {
         return this.handled_facet_types.contains(facettype);
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/CollisionCalcProcessor.java	Fri Jun 29 16:15:43 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/CollisionCalcProcessor.java	Fri Jun 29 16:29:23 2018 +0200
@@ -11,21 +11,16 @@
 package org.dive4elements.river.artifacts.sinfo.common;
 
 import java.util.HashSet;
-import java.util.Map;
 import java.util.Set;
 
 import org.dive4elements.artifactdatabase.state.ArtifactAndFacet;
 import org.dive4elements.artifactdatabase.state.Facet;
-import org.dive4elements.artifacts.Artifact;
 import org.dive4elements.artifacts.CallContext;
 import org.dive4elements.river.artifacts.common.AbstractCalculationResult;
-import org.dive4elements.river.artifacts.common.IResultType;
 import org.dive4elements.river.artifacts.resources.Resources;
 import org.dive4elements.river.artifacts.sinfo.collision.CollisionCalcFacet;
 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.StyledXYSeries;
 import org.dive4elements.river.themes.ThemeDocument;
 
 /**
@@ -55,35 +50,7 @@
     @Override
     protected String generateSeries(final DiagramGenerator generator, final ArtifactAndFacet bundle, final ThemeDocument theme, final boolean visible) {
 
-        return buildSeriesForType(generator, bundle, theme, visible, SInfoResultType.collisionCount);
-    }
-
-    // FIXME: move to super classs and use in many implementations
-    protected final String buildSeriesForType(final DiagramGenerator generator, final ArtifactAndFacet bundle, final ThemeDocument theme, final boolean visible,
-            final IResultType resultType) {
-        final CallContext context = generator.getContext();
-        final Map<String, String> metaData = bundle.getFacet().getMetaData();
-
-        final Artifact artifact = bundle.getArtifact();
-
-        final StyledXYSeries series = new StyledXYSeries(bundle.getFacetDescription(), theme);
-        series.putMetaData(metaData, artifact, context);
-
-        final String facetName = bundle.getFacetName();
-
-        final AbstractCalculationResult data = (AbstractCalculationResult) 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 double[][] points = data.getStationPoints(resultType);
-
-        StyledSeriesBuilder.addPoints(series, points, true);
-        generator.addAxisSeries(series, getAxisName(), visible);
-
-        return metaData.get("Y");
+        return buildSeriesForType(generator, bundle, theme, visible, SInfoResultType.collisionCount, null);
     }
 
     public static final Facet createFacet(final CallContext context, final String hash, final String id, final AbstractCalculationResult result,
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/CollisionCountProcessor.java	Fri Jun 29 16:15:43 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/CollisionCountProcessor.java	Fri Jun 29 16:29:23 2018 +0200
@@ -11,20 +11,14 @@
 package org.dive4elements.river.artifacts.sinfo.common;
 
 import java.util.HashSet;
-import java.util.Map;
 import java.util.Set;
 
 import org.dive4elements.artifactdatabase.state.ArtifactAndFacet;
 import org.dive4elements.artifactdatabase.state.Facet;
-import org.dive4elements.artifacts.Artifact;
-import org.dive4elements.artifacts.CallContext;
 import org.dive4elements.artifacts.CallMeta;
 import org.dive4elements.river.artifacts.resources.Resources;
-import org.dive4elements.river.artifacts.sinfo.collision.CollisionCalcOverviewResult;
 import org.dive4elements.river.artifacts.sinfo.collision.CollisionFacet;
 import org.dive4elements.river.exports.DiagramGenerator;
-import org.dive4elements.river.exports.StyledSeriesBuilder;
-import org.dive4elements.river.jfree.StyledXYSeries;
 import org.dive4elements.river.themes.ThemeDocument;
 
 /**
@@ -53,37 +47,15 @@
         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.getContext();
-        final Map<String, String> metaData = bundle.getFacet().getMetaData();
-
-        final Artifact artifact = bundle.getArtifact();
-
-        final StyledXYSeries series = new StyledXYSeries(bundle.getFacetDescription(), theme);
-        series.putMetaData(metaData, artifact, context);
-
-        final String facetName = bundle.getFacetName();
-
-        final CollisionCalcOverviewResult data = (CollisionCalcOverviewResult) 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 double[][] points = data.getStationPoints(SInfoResultType.collisionCount);
-
-        StyledSeriesBuilder.addPoints(series, points, true);
-        generator.addAxisSeries(series, getAxisName(), visible);
-
-        return metaData.get("Y");
-    }
-
     public static Facet createFacet(final CallMeta callMeta, final String seriesName) {
         return new CollisionFacet(FACET_COLLISION_COUNT, Resources.getMsg(callMeta, I18N_SERIES_NAME_PATTERN, I18N_SERIES_NAME_PATTERN, seriesName),
                 I18N_AXIS_LABEL);
     }
 
+    @Override
+    protected String generateSeries(final DiagramGenerator generator, final ArtifactAndFacet bundle, final ThemeDocument theme, final boolean visible) {
+
+        return buildSeriesForType(generator, bundle, theme, visible, SInfoResultType.collisionCount, null);
+    }
+
 }
\ No newline at end of file
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/D50Processor.java	Fri Jun 29 16:15:43 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/D50Processor.java	Fri Jun 29 16:29:23 2018 +0200
@@ -13,11 +13,14 @@
 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.common.AbstractCalculationResult;
+import org.dive4elements.river.exports.DiagramGenerator;
+import org.dive4elements.river.themes.ThemeDocument;
 
-public final class D50Processor extends AbstractSInfoLineProcessor<AbstractTkhCalculationResult> {
+public final class D50Processor extends AbstractSInfoProcessor {
 
     public static final String FACET_TKH_D50_FILTERED = "sinfo_facet_d50";
 
@@ -38,10 +41,11 @@
     }
 
     @Override
-    protected double[][] doGetPoints(final AbstractTkhCalculationResult data, final String facetName) {
+    protected String generateSeries(final DiagramGenerator generator, final ArtifactAndFacet bundle, final ThemeDocument theme, final boolean visible) {
 
+        final String facetName = bundle.getFacetName();
         if (FACET_TKH_D50_FILTERED.contentEquals(facetName))
-            return data.getStationPoints(SInfoResultType.d50);
+            return buildSeriesForType(generator, bundle, theme, visible, SInfoResultType.d50, GAP_DISTANCE);
 
         final String error = String.format("Unknown facet name: %s", facetName);
         throw new UnsupportedOperationException(error);
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/InfrastructureHeightProcessor.java	Fri Jun 29 16:15:43 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/InfrastructureHeightProcessor.java	Fri Jun 29 16:29:23 2018 +0200
@@ -11,20 +11,14 @@
 package org.dive4elements.river.artifacts.sinfo.common;
 
 import java.util.HashSet;
-import java.util.Map;
 import java.util.Set;
 
 import org.dive4elements.artifactdatabase.state.ArtifactAndFacet;
 import org.dive4elements.artifactdatabase.state.Facet;
-import org.dive4elements.artifacts.Artifact;
-import org.dive4elements.artifacts.CallContext;
 import org.dive4elements.artifacts.CallMeta;
-import org.dive4elements.river.artifacts.common.AbstractCalculationResult;
 import org.dive4elements.river.artifacts.resources.Resources;
 import org.dive4elements.river.artifacts.sinfo.flood_duration.InfrastructureFacet;
 import org.dive4elements.river.exports.DiagramGenerator;
-import org.dive4elements.river.exports.StyledSeriesBuilder;
-import org.dive4elements.river.jfree.StyledXYSeries;
 import org.dive4elements.river.themes.ThemeDocument;
 
 /**
@@ -56,28 +50,7 @@
     @Override
     protected String generateSeries(final DiagramGenerator generator, final ArtifactAndFacet bundle, final ThemeDocument theme, final boolean visible) {
 
-        final CallContext context = generator.getContext();
-        final Map<String, String> metaData = bundle.getFacet().getMetaData();
-
-        final Artifact artifact = bundle.getArtifact();
-
-        final StyledXYSeries series = new StyledXYSeries(bundle.getFacetDescription(), theme);
-        series.putMetaData(metaData, artifact, context);
-
-        final String facetName = bundle.getFacetName();
-        final AbstractCalculationResult data = (AbstractCalculationResult) 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 double[][] points = data.getStationPoints(SInfoResultType.infrastructureHeight);
-
-        StyledSeriesBuilder.addPoints(series, points, true);
-        generator.addAxisSeries(series, getAxisName(), visible);
-
-        return metaData.get("Y");
+        return buildSeriesForType(generator, bundle, theme, visible, SInfoResultType.infrastructureHeight, null);
     }
 
     public static Facet createFacet(final CallMeta callMeta, final String seriesName) {
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/PredefinedChannelDepthProcessor.java	Fri Jun 29 16:15:43 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/PredefinedChannelDepthProcessor.java	Fri Jun 29 16:29:23 2018 +0200
@@ -11,20 +11,14 @@
 package org.dive4elements.river.artifacts.sinfo.common;
 
 import java.util.HashSet;
-import java.util.Map;
 import java.util.Set;
 
 import org.dive4elements.artifactdatabase.state.ArtifactAndFacet;
 import org.dive4elements.artifactdatabase.state.Facet;
-import org.dive4elements.artifacts.Artifact;
-import org.dive4elements.artifacts.CallContext;
 import org.dive4elements.artifacts.CallMeta;
-import org.dive4elements.river.artifacts.common.AbstractCalculationResult;
 import org.dive4elements.river.artifacts.resources.Resources;
 import org.dive4elements.river.artifacts.sinfo.predefinedchannel.PredefinedChannelFacet;
 import org.dive4elements.river.exports.DiagramGenerator;
-import org.dive4elements.river.exports.StyledSeriesBuilder;
-import org.dive4elements.river.jfree.StyledXYSeries;
 import org.dive4elements.river.themes.ThemeDocument;
 
 /**
@@ -53,35 +47,14 @@
         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.getContext();
-        final Map<String, String> metaData = bundle.getFacet().getMetaData();
-
-        final Artifact artifact = bundle.getArtifact();
-
-        final StyledXYSeries series = new StyledXYSeries(bundle.getFacetDescription(), theme);
-        series.putMetaData(metaData, artifact, context);
-
-        final String facetName = bundle.getFacetName();
-        final AbstractCalculationResult data = (AbstractCalculationResult) 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 double[][] points = data.getStationPoints(SInfoResultType.channelDepth);
-
-        StyledSeriesBuilder.addPoints(series, points, true);
-        generator.addAxisSeries(series, getAxisName(), visible);
-
-        return metaData.get("Y");
-    }
-
     public static Facet createFacet(final CallMeta callMeta, final String seriesName) {
         return new PredefinedChannelFacet(FACET_PREDEFINED_CHANNEL_DEPTH,
                 Resources.getMsg(callMeta, I18N_SERIES_NAME_PATTERN, I18N_SERIES_NAME_PATTERN, seriesName), I18N_AXIS_LABEL);
     }
+
+    @Override
+    protected String generateSeries(final DiagramGenerator generator, final ArtifactAndFacet bundle, final ThemeDocument theme, final boolean visible) {
+
+        return buildSeriesForType(generator, bundle, theme, visible, SInfoResultType.collisionCount, null);
+    }
 }
\ No newline at end of file
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/PredefinedChannelWidthProcessor.java	Fri Jun 29 16:15:43 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/PredefinedChannelWidthProcessor.java	Fri Jun 29 16:29:23 2018 +0200
@@ -11,20 +11,14 @@
 package org.dive4elements.river.artifacts.sinfo.common;
 
 import java.util.HashSet;
-import java.util.Map;
 import java.util.Set;
 
 import org.dive4elements.artifactdatabase.state.ArtifactAndFacet;
 import org.dive4elements.artifactdatabase.state.Facet;
-import org.dive4elements.artifacts.Artifact;
-import org.dive4elements.artifacts.CallContext;
 import org.dive4elements.artifacts.CallMeta;
-import org.dive4elements.river.artifacts.common.AbstractCalculationResult;
 import org.dive4elements.river.artifacts.resources.Resources;
 import org.dive4elements.river.artifacts.sinfo.predefinedchannel.PredefinedChannelFacet;
 import org.dive4elements.river.exports.DiagramGenerator;
-import org.dive4elements.river.exports.StyledSeriesBuilder;
-import org.dive4elements.river.jfree.StyledXYSeries;
 import org.dive4elements.river.themes.ThemeDocument;
 
 /**
@@ -56,32 +50,12 @@
     @Override
     protected String generateSeries(final DiagramGenerator generator, final ArtifactAndFacet bundle, final ThemeDocument theme, final boolean visible) {
 
-        final CallContext context = generator.getContext();
-        final Map<String, String> metaData = bundle.getFacet().getMetaData();
-
-        final Artifact artifact = bundle.getArtifact();
-
-        final StyledXYSeries series = new StyledXYSeries(bundle.getFacetDescription(), theme);
-        series.putMetaData(metaData, artifact, context);
-
-        final String facetName = bundle.getFacetName();
-        final AbstractCalculationResult data = (AbstractCalculationResult) 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 double[][] points = data.getStationPoints(SInfoResultType.channelWidth);
-
-        StyledSeriesBuilder.addPoints(series, points, true);
-        generator.addAxisSeries(series, getAxisName(), visible);
-
-        return metaData.get("Y");
+        return buildSeriesForType(generator, bundle, theme, visible, SInfoResultType.channelWidth, null);
     }
 
     public static Facet createFacet(final CallMeta callMeta, final String seriesName) {
         return new PredefinedChannelFacet(FACET_PREDEFINED_CHANNEL_WIDTH,
                 Resources.getMsg(callMeta, I18N_SERIES_NAME_PATTERN, I18N_SERIES_NAME_PATTERN, seriesName), I18N_AXIS_LABEL);
     }
+
 }
\ No newline at end of file
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/PredefinedDepthEvolPerYearProcessor.java	Fri Jun 29 16:15:43 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/PredefinedDepthEvolPerYearProcessor.java	Fri Jun 29 16:29:23 2018 +0200
@@ -11,20 +11,14 @@
 package org.dive4elements.river.artifacts.sinfo.common;
 
 import java.util.HashSet;
-import java.util.Map;
 import java.util.Set;
 
 import org.dive4elements.artifactdatabase.state.ArtifactAndFacet;
 import org.dive4elements.artifactdatabase.state.Facet;
-import org.dive4elements.artifacts.Artifact;
-import org.dive4elements.artifacts.CallContext;
 import org.dive4elements.artifacts.CallMeta;
-import org.dive4elements.river.artifacts.common.AbstractCalculationResult;
 import org.dive4elements.river.artifacts.resources.Resources;
 import org.dive4elements.river.artifacts.sinfo.predefineddepthevol.PredefinedDepthEvolFacet;
 import org.dive4elements.river.exports.DiagramGenerator;
-import org.dive4elements.river.exports.StyledSeriesBuilder;
-import org.dive4elements.river.jfree.StyledXYSeries;
 import org.dive4elements.river.themes.ThemeDocument;
 
 /**
@@ -56,28 +50,7 @@
     @Override
     protected String generateSeries(final DiagramGenerator generator, final ArtifactAndFacet bundle, final ThemeDocument theme, final boolean visible) {
 
-        final CallContext context = generator.getContext();
-        final Map<String, String> metaData = bundle.getFacet().getMetaData();
-
-        final Artifact artifact = bundle.getArtifact();
-
-        final StyledXYSeries series = new StyledXYSeries(bundle.getFacetDescription(), theme);
-        series.putMetaData(metaData, artifact, context);
-
-        final String facetName = bundle.getFacetName();
-        final AbstractCalculationResult data = (AbstractCalculationResult) 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 double[][] points = data.getStationPoints(SInfoResultType.flowdepthDevelopmentPerYear);
-
-        StyledSeriesBuilder.addPoints(series, points, true);
-        generator.addAxisSeries(series, getAxisName(), visible);
-
-        return metaData.get("Y");
+        return buildSeriesForType(generator, bundle, theme, visible, SInfoResultType.flowdepthDevelopmentPerYear, null);
     }
 
     public static Facet createFacet(final CallMeta callMeta, final String seriesName) {
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/PredefinedDepthEvolProcessor.java	Fri Jun 29 16:15:43 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/PredefinedDepthEvolProcessor.java	Fri Jun 29 16:29:23 2018 +0200
@@ -11,20 +11,14 @@
 package org.dive4elements.river.artifacts.sinfo.common;
 
 import java.util.HashSet;
-import java.util.Map;
 import java.util.Set;
 
 import org.dive4elements.artifactdatabase.state.ArtifactAndFacet;
 import org.dive4elements.artifactdatabase.state.Facet;
-import org.dive4elements.artifacts.Artifact;
-import org.dive4elements.artifacts.CallContext;
 import org.dive4elements.artifacts.CallMeta;
-import org.dive4elements.river.artifacts.common.AbstractCalculationResult;
 import org.dive4elements.river.artifacts.resources.Resources;
 import org.dive4elements.river.artifacts.sinfo.predefineddepthevol.PredefinedDepthEvolFacet;
 import org.dive4elements.river.exports.DiagramGenerator;
-import org.dive4elements.river.exports.StyledSeriesBuilder;
-import org.dive4elements.river.jfree.StyledXYSeries;
 import org.dive4elements.river.themes.ThemeDocument;
 
 /**
@@ -56,28 +50,7 @@
     @Override
     protected String generateSeries(final DiagramGenerator generator, final ArtifactAndFacet bundle, final ThemeDocument theme, final boolean visible) {
 
-        final CallContext context = generator.getContext();
-        final Map<String, String> metaData = bundle.getFacet().getMetaData();
-
-        final Artifact artifact = bundle.getArtifact();
-
-        final StyledXYSeries series = new StyledXYSeries(bundle.getFacetDescription(), theme);
-        series.putMetaData(metaData, artifact, context);
-
-        final String facetName = bundle.getFacetName();
-        final AbstractCalculationResult data = (AbstractCalculationResult) 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 double[][] points = data.getStationPoints(SInfoResultType.flowdepthDevelopment);
-
-        StyledSeriesBuilder.addPoints(series, points, true);
-        generator.addAxisSeries(series, getAxisName(), visible);
-
-        return metaData.get("Y");
+        return buildSeriesForType(generator, bundle, theme, visible, SInfoResultType.flowdepthDevelopment, null);
     }
 
     public static Facet createFacet(final CallMeta callMeta, final String seriesName) {
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/PredefinedFlowDepthProcessor.java	Fri Jun 29 16:15:43 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/PredefinedFlowDepthProcessor.java	Fri Jun 29 16:29:23 2018 +0200
@@ -47,7 +47,7 @@
 
     @Override
     protected String generateSeries(final DiagramGenerator generator, final ArtifactAndFacet bundle, final ThemeDocument theme, final boolean visible) {
-
+        // TOO MANY DIFFERENCES TO super.buildSeriesForTkh(generator, bundle, theme, visible);
         final CallContext context = generator.getContext();
         final Map<String, String> metaData = bundle.getFacet().getMetaData();
 
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/PredefinedTkhProcessor.java	Fri Jun 29 16:15:43 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/PredefinedTkhProcessor.java	Fri Jun 29 16:29:23 2018 +0200
@@ -14,11 +14,7 @@
 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;
 
 /**
@@ -45,32 +41,7 @@
 
     @Override
     protected String generateSeries(final DiagramGenerator generator, final ArtifactAndFacet bundle, final ThemeDocument theme, final boolean visible) {
-        final CallContext context = generator.getContext();
-
-        final String facetName = bundle.getFacetName();
-        final AbstractTkhCalculationResult data = (AbstractTkhCalculationResult) bundle.getData(context); // differs from standard!
-        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);
-        }
+        return buildSeriesForTkh(generator, bundle, theme, visible);
 
-        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/common/TkhProcessor.java	Fri Jun 29 16:15:43 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/TkhProcessor.java	Fri Jun 29 16:29:23 2018 +0200
@@ -20,9 +20,6 @@
 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 {
@@ -47,33 +44,9 @@
 
     @Override
     protected String generateSeries(final DiagramGenerator generator, final ArtifactAndFacet bundle, final ThemeDocument theme, final boolean visible) {
-        final CallContext context = generator.getContext();
-
-        final String facetName = bundle.getFacetName();
-        final AbstractTkhCalculationResult data = (AbstractTkhCalculationResult) 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);
+        return buildSeriesForTkh(generator, bundle, theme, visible);
 
-        // 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 AbstractCalculationResult result, final int index) {

http://dive4elements.wald.intevation.org