changeset 3898:95d699c769fb

Bedheight difference calculation has chart outpus now. flys-artifacts/trunk@5562 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Raimund Renkert <raimund.renkert@intevation.de>
date Fri, 21 Sep 2012 14:29:32 +0000
parents bce2dd4310a6
children 663e82917b8f
files flys-artifacts/ChangeLog flys-artifacts/doc/conf/artifacts/minfo.xml flys-artifacts/doc/conf/conf.xml flys-artifacts/src/main/java/de/intevation/flys/artifacts/access/BedDifferencesAccess.java flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/FacetTypes.java flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/BedDiffCalculation.java flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/BedDiffEpochFacet.java flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/BedDiffEpochResult.java flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/BedDiffYearFacet.java flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/BedDiffYearResult.java flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/BedDifferencesResult.java flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/minfo/DifferencesState.java flys-artifacts/src/main/java/de/intevation/flys/exports/minfo/BedDiffEpochInfoGenerator.java flys-artifacts/src/main/java/de/intevation/flys/exports/minfo/BedDiffHeightYearGenerator.java flys-artifacts/src/main/java/de/intevation/flys/exports/minfo/BedDiffHeightYearInfoGenerator.java flys-artifacts/src/main/java/de/intevation/flys/exports/minfo/BedDiffYearInfoGenerator.java flys-artifacts/src/main/java/de/intevation/flys/exports/minfo/BedDifferenceEpochGenerator.java flys-artifacts/src/main/java/de/intevation/flys/exports/minfo/BedDifferenceYearGenerator.java
diffstat 18 files changed, 1043 insertions(+), 52 deletions(-) [+]
line wrap: on
line diff
--- a/flys-artifacts/ChangeLog	Fri Sep 21 14:18:16 2012 +0000
+++ b/flys-artifacts/ChangeLog	Fri Sep 21 14:29:32 2012 +0000
@@ -1,3 +1,40 @@
+2012-09-21  Raimund Renkert <raimund.renkert@intevation.de>
+
+	* src/main/java/de/intevation/flys/exports/minfo/BedDiffHeightYearInfoGenerator.java,
+	  src/main/java/de/intevation/flys/exports/minfo/BedDiffHeightYearGenerator.java,
+	  src/main/java/de/intevation/flys/exports/minfo/BedDiffEpochInfoGenerator.java,
+	  src/main/java/de/intevation/flys/exports/minfo/BedDiffYearInfoGenerator.java,
+	  src/main/java/de/intevation/flys/exports/minfo/BedDifferenceEpochGenerator.java,
+	  src/main/java/de/intevation/flys/exports/minfo/BedDifferenceYearGenerator.java:
+	  New. Chart generators for bedheight diff calculation charts.
+
+	* src/main/java/de/intevation/flys/artifacts/states/minfo/DifferencesState.java:
+	  Add facets to generate outputs.
+
+	* src/main/java/de/intevation/flys/artifacts/access/BedDifferencesAccess.java:
+	  Extract calculation relevant data.
+
+	* src/main/java/de/intevation/flys/artifacts/model/minfo/BedDifferencesResult.java,
+	  src/main/java/de/intevation/flys/artifacts/model/minfo/BedDiffYearResult.java,
+	  src/main/java/de/intevation/flys/artifacts/model/minfo/BedDiffEpochResult.java:
+	  Updated result set data fields.
+
+	* src/main/java/de/intevation/flys/artifacts/model/minfo/BedDiffCalculation.java:
+	  Updated the bedheight difference calculation.
+
+	* src/main/java/de/intevation/flys/artifacts/model/FacetTypes.java:
+	  Added new facet types.
+
+	* src/main/java/de/intevation/flys/artifacts/model/minfo/BedDiffEpochFacet.java,
+	  src/main/java/de/intevation/flys/artifacts/model/minfo/BedDiffYearFacet.java:
+	  New facets for bedheight differences.
+
+	* doc/conf/conf.xml:
+	  Added ouput generators.
+
+	* doc/conf/artifacts/minfo.xml:
+	  Added facets to outputmodes.
+
 2012-09-21  Raimund Renkert <raimund.renkert@intevation.de>
 
 	* src/main/java/de/intevation/flys/artifacts/model/minfo/BedHeight.java,
--- a/flys-artifacts/doc/conf/artifacts/minfo.xml	Fri Sep 21 14:18:16 2012 +0000
+++ b/flys-artifacts/doc/conf/artifacts/minfo.xml	Fri Sep 21 14:29:32 2012 +0000
@@ -182,12 +182,27 @@
 
         <state id="state.minfo.bed.differences" description="state.minfo.bed.differences" state="de.intevation.flys.artifacts.states.minfo.DifferencesState" helpText="help.minfo.bed.differences">
             <outputmodes>
-                <outputmode name="absolute_height" description="output.absolute_height" mime-type="image/png" type="chart">
+                <outputmode name="bed_difference_height_year" description="output.absolute_height" mime-type="image/png" type="chart">
                     <facets>
+                        <facet name="bedheight_difference.height_year" description="A facet for absolute heights"/>
+                        <facet name="longitudinal_section.annotations" description="facet.longitudinal_section.annotations"/>
                     </facets>
                 </outputmode>
-                <outputmode name="difference_year" description="output.difference_year" mime-type="img/png" type="chart">
+                <outputmode name="bed_difference_year" description="output.difference_year" mime-type="img/png" type="chart">
                     <facets>
+                        <facet name="bedheight_difference.year" description="A facet for bed height differences"/>
+                        <facet name="bedheight_difference.morph_width" description="A facet for morphologic width"/>
+                        <facet name="bedheight_difference.year.height1" description="A facet for raw heights."/>
+                        <facet name="bedheight_difference.year.height2" description="A facet for raw heights."/>
+                        <facet name="longitudinal_section.annotations" description="facet.longitudinal_section.annotations"/>
+                    </facets>
+                </outputmode>
+                <outputmode name="bed_difference_epoch" description="output.difference_epoch" mime-type="img/png" type="chart">
+                    <facets>
+                        <facet name="bedheight_difference.epoch" description="A facet for bed height differences"/>
+                        <facet name="bedheight_difference.epoch.height1" description="A facet for raw heights."/>
+                        <facet name="bedheight_difference.epoch.height2" description="A facet for raw heights."/>
+                        <facet name="longitudinal_section.annotations" description="facet.longitudinal_section.annotations"/>
                     </facets>
                 </outputmode>
             </outputmodes>
--- a/flys-artifacts/doc/conf/conf.xml	Fri Sep 21 14:18:16 2012 +0000
+++ b/flys-artifacts/doc/conf/conf.xml	Fri Sep 21 14:29:32 2012 +0000
@@ -289,6 +289,12 @@
         <output-generator name="bed_longitudinal_section">de.intevation.flys.exports.minfo.BedQualityGenerator</output-generator>
         <output-generator name="bed_longitudinal_section_chartinfo">de.intevation.flys.exports.minfo.BedQualityInfoGenerator</output-generator>
         <output-generator name="bed_quality_export">de.intevation.flys.exports.minfo.BedQualityExporter</output-generator>
+        <output-generator name="bed_difference_year">de.intevation.flys.exports.minfo.BedDifferenceYearGenerator</output-generator>
+        <output-generator name="bed_difference_year_chartinfo">de.intevation.flys.exports.minfo.BedDiffYearInfoGenerator</output-generator>
+        <output-generator name="bed_difference_epoch">de.intevation.flys.exports.minfo.BedDifferenceEpochGenerator</output-generator>
+        <output-generator name="bed_difference_epoch_chartinfo">de.intevation.flys.exports.minfo.BedDiffEpochInfoGenerator</output-generator>
+        <output-generator name="bed_difference_height_year">de.intevation.flys.exports.minfo.BedDiffHeightYearGenerator</output-generator>
+        <output-generator name="bed_difference_height_year_chartinfo">de.intevation.flys.exports.minfo.BedDiffHeightYearInfoGenerator</output-generator>
         <output-generator name="sq_relation_a">de.intevation.flys.exports.sq.SQRelationGeneratorA</output-generator>
         <output-generator name="sq_relation_b">de.intevation.flys.exports.sq.SQRelationGeneratorB</output-generator>
         <output-generator name="sq_relation_c">de.intevation.flys.exports.sq.SQRelationGeneratorC</output-generator>
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/access/BedDifferencesAccess.java	Fri Sep 21 14:18:16 2012 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/access/BedDifferencesAccess.java	Fri Sep 21 14:29:32 2012 +0000
@@ -1,8 +1,11 @@
 package de.intevation.flys.artifacts.access;
 
+import java.util.Arrays;
+
+import org.apache.log4j.Logger;
+
 import de.intevation.artifacts.CallContext;
 import de.intevation.flys.artifacts.FLYSArtifact;
-import de.intevation.flys.artifacts.model.minfo.BedHeight;
 import de.intevation.flys.utils.FLYSUtils;
 import de.intevation.flys.utils.StringUtil;
 
@@ -10,7 +13,7 @@
 public class BedDifferencesAccess
 extends RiverAccess
 {
-
+    private static Logger logger = Logger.getLogger(BedDifferencesAccess.class);
     private String yearEpoch;
     private String[] diffs;
 
@@ -22,19 +25,22 @@
     }
 
     public String getYearEpoch() {
+        yearEpoch = getString("ye_select");
         return yearEpoch;
     }
 
     public FLYSArtifact[][] getDifferenceArtifacts() {
-        FLYSArtifact[][] artifacts = new FLYSArtifact[diffs.length][2];
-        for (int i = 0; i < diffs.length; i++) {
-            String[] diff = diffs[i].split("#");
-            String diff1 = StringUtil.unbracket(diff[0]);
-            String diff2 = StringUtil.unbracket(diff[1]);
+        diffs = getString("diffids").split("#");
+        logger.debug("diffs: " + Arrays.toString(diffs));
+        FLYSArtifact[][] artifacts = new FLYSArtifact[diffs.length/2][2];
+        for (int i = 0; i < diffs.length; i += 2) {
+            String diff1 = StringUtil.unbracket(diffs[0 + 2*i]);
+            String diff2 = StringUtil.unbracket(diffs[1 + 2*i]);
             String[] diff1parts = diff1.split(";");
             String[] diff2parts = diff2.split(";");
+            logger.debug("creating 2 artifacts." + diff1parts[0] + "; " + diff2parts[0]);
             artifacts[i][0] = FLYSUtils.getArtifact(diff1parts[0], context);
-            artifacts[i][1] = FLYSUtils.getArtifact(diff2parts[1], context);
+            artifacts[i][1] = FLYSUtils.getArtifact(diff2parts[0], context);
         }
         return artifacts;
     }
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/FacetTypes.java	Fri Sep 21 14:18:16 2012 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/FacetTypes.java	Fri Sep 21 14:29:32 2012 +0000
@@ -229,6 +229,15 @@
     String BED_QUALITY_SEDIMENT_DENSITY_SUBLAYER = "bed_longitudinal_section.sediment_density_sublayer";
     String BED_QUALITY_BEDLOAD_DIAMETER          = "bed_longitudinal_section.bedload_diameter";
 
+    String BED_DIFFERENCE_YEAR          = "bedheight_difference.year";
+    String BED_DIFFERENCE_HEIGHT_YEAR   = "bedheight_difference.height_year";
+    String BED_DIFFERENCE_EPOCH         = "bedheight_difference.epoch";
+    String BED_DIFFERENCE_MORPH_WIDTH   = "bedheight_difference.morph_width";
+    String BED_DIFFERENCE_YEAR_HEIGHT1  = "bedheight_difference.year.height1";
+    String BED_DIFFERENCE_YEAR_HEIGHT2  = "bedheight_difference.year.height2";
+    String BED_DIFFERENCE_EPOCH_HEIGHT1 = "bedheight_difference.epoch.height1";
+    String BED_DIFFERENCE_EPOCH_HEIGHT2 = "bedheight_difference.epoch.height2";
+
     String SQ_OVERVIEW       = "sq_overview";
 
     String SQ_A_CURVE       = "sq_a_curve";
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/BedDiffCalculation.java	Fri Sep 21 14:18:16 2012 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/BedDiffCalculation.java	Fri Sep 21 14:29:32 2012 +0000
@@ -2,6 +2,7 @@
 
 import gnu.trove.TDoubleArrayList;
 
+import java.util.Date;
 import java.util.LinkedList;
 import java.util.List;
 
@@ -18,7 +19,7 @@
 {
 
     private static final Logger logger = Logger
-        .getLogger(BedQualityCalculation.class);
+        .getLogger(BedDiffCalculation.class);
 
     protected String river;
     protected String yearEpoch;
@@ -28,12 +29,13 @@
     }
 
     public CalculationResult calculate(BedDifferencesAccess access) {
-        logger.info("BedQualityCalculation.calculate");
+        logger.info("BedDiffCalculation.calculate");
 
         String river = access.getRiver();
         String yearEpoch = access.getYearEpoch();
         FLYSArtifact[][] artifacts = access.getDifferenceArtifacts();
 
+        logger.debug("got artifacts: " + artifacts.length + "; " + artifacts[0].length);
         if (river == null) {
             // TODO: i18n
             addProblem("minfo.missing.river");
@@ -58,28 +60,34 @@
     }
 
     private CalculationResult internalCalculate() {
-        List<BedDifferencesResult> results =
-            new LinkedList<BedDifferencesResult>();
 
         if (yearEpoch.equals("year")) {
+            List<BedDiffYearResult> results =
+                new LinkedList<BedDiffYearResult>();
+
             for (int i = 0; i < artifacts.length; i++) {
                 BedHeight[] pair =
                     getHeightPair(artifacts[i][0], artifacts[i][1], "single");
-                BedDifferencesResult res = calculateYearDifference(pair);
+                BedDiffYearResult res = calculateYearDifference(pair);
                 results.add(res);
             }
+            return new CalculationResult(
+                results.toArray(new BedDiffYearResult[results.size()]), this);
         }
         if (yearEpoch.equals("epoch")) {
+            List<BedDiffEpochResult> results =
+                new LinkedList<BedDiffEpochResult>();
             for (int i = 0; i < artifacts.length; i++) {
                 BedHeight[] pair =
                     getHeightPair(artifacts[i][0], artifacts[i][1], "epoch");
-                BedDifferencesResult res = calculateEpochDifference(pair);
+                BedDiffEpochResult res = calculateEpochDifference(pair);
                 results.add(res);
             }
+            return new CalculationResult(
+                results.toArray(new BedDiffEpochResult[results.size()]), this);
         }
 
-       return new CalculationResult(
-            results.toArray(new BedDifferencesResult[results.size()]), this);
+       return new CalculationResult();
     }
 
     private BedHeight[] getHeightPair(
@@ -101,7 +109,9 @@
         TDoubleArrayList stations = pair[0].getStations();
         TDoubleArrayList diffRes = new TDoubleArrayList();
         TDoubleArrayList kms = new TDoubleArrayList();
-        TDoubleArrayList morphs = new TDoubleArrayList();
+        TDoubleArrayList heights1 = new TDoubleArrayList();
+        TDoubleArrayList heights2 = new TDoubleArrayList();
+
         for (int i = 0; i < stations.size(); i++) {
             if (!Double.isNaN(pair[0].getHeight(stations.get(i))) &&
                 !Double.isNaN(pair[1].getHeight(stations.get(i)))) {
@@ -110,15 +120,13 @@
                     pair[1].getHeight(stations.get(i));
                 diffRes.add(hDiff);
                 kms.add(stations.get(i));
-                if (pair[0].getMorphWidth(i) > pair[1].getMorphWidth(i)) {
-                    morphs.add(pair[0].getMorphWidth(i));
-                }
-                else {
-                    morphs.add(pair[1].getMorphWidth(i));
-                }
+                heights1.add(pair[0].getHeight(stations.get(i)));
+                heights2.add(pair[1].getHeight(stations.get(i)));
             }
         }
-        return new BedDiffEpochResult(kms, diffRes, morphs);
+        Date start = ((BedHeightEpoch)pair[0]).getStart();
+        Date end = ((BedHeightEpoch)pair[1]).getEnd();
+        return new BedDiffEpochResult(kms, diffRes, heights1, heights2, start, end);
     }
 
     private BedDiffYearResult calculateYearDifference(BedHeight[] pair) {
@@ -127,8 +135,11 @@
         TDoubleArrayList diffRes = new TDoubleArrayList();
         TDoubleArrayList kms = new TDoubleArrayList();
         TDoubleArrayList morphs = new TDoubleArrayList();
-        TDoubleArrayList heights = new TDoubleArrayList();
+        TDoubleArrayList absolute = new TDoubleArrayList();
         TDoubleArrayList gap = new TDoubleArrayList();
+        TDoubleArrayList heights1 = new TDoubleArrayList();
+        TDoubleArrayList heights2 = new TDoubleArrayList();
+
         BedHeightSingle s1 = (BedHeightSingle)pair[0];
         BedHeightSingle s2 = (BedHeightSingle)pair[1];
         int range = s1.getYear() - s2.getYear();
@@ -136,28 +147,41 @@
             range = range * -1;
         }
         for (int i = 0; i < stations.size(); i++) {
-            if (!Double.isNaN(pair[0].getHeight(stations.get(i))) &&
-                !Double.isNaN(pair[1].getHeight(stations.get(i)))) {
+            if (!Double.isNaN(s1.getHeight(stations.get(i))) &&
+                !Double.isNaN(s2.getHeight(stations.get(i)))) {
                 double hDiff =
-                    pair[0].getHeight(stations.get(i)) -
-                    pair[1].getHeight(stations.get(i));
+                    s1.getHeight(stations.get(i)) -
+                    s2.getHeight(stations.get(i));
                 diffRes.add(hDiff);
-                kms.add(stations.get(i));
-                if (pair[0].getMorphWidth(i) > pair[1].getMorphWidth(i)) {
-                    morphs.add(pair[0].getMorphWidth(i));
+                double km = stations.get(i);
+                kms.add(km);
+                if (s1.getMorphWidth(km) >
+                    s2.getMorphWidth(km)) {
+                    morphs.add(s1.getMorphWidth(km));
                 }
                 else {
-                    morphs.add(pair[1].getMorphWidth(i));
+                    morphs.add(s2.getMorphWidth(km));
                 }
-                if (pair[0].getDataGap(i) > pair[1].getDataGap(i)) {
-                    gap.add(pair[0].getDataGap(i));
+                if (s1.getDataGap(km) > s2.getDataGap(km)) {
+                    gap.add(s1.getDataGap(km));
                 }
                 else {
-                    gap.add(pair[1].getDataGap(i));
+                    gap.add(s2.getDataGap(km));
                 }
-                heights.add(hDiff / range);
+                absolute.add((hDiff / range) * 100);
+                heights1.add(s1.getHeight(km));
+                heights2.add(s2.getHeight(km));
             }
         }
-        return new BedDiffYearResult(kms, diffRes, morphs, heights, gap);
+        return new BedDiffYearResult(
+            kms,
+            diffRes,
+            heights1,
+            heights2,
+            morphs,
+            absolute,
+            gap,
+            s1.getYear(),
+            s2.getYear());
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/BedDiffEpochFacet.java	Fri Sep 21 14:29:32 2012 +0000
@@ -0,0 +1,52 @@
+package de.intevation.flys.artifacts.model.minfo;
+
+import org.apache.log4j.Logger;
+
+import de.intevation.artifactdatabase.state.Facet;
+import de.intevation.artifacts.Artifact;
+import de.intevation.artifacts.CallContext;
+import de.intevation.flys.artifacts.FLYSArtifact;
+import de.intevation.flys.artifacts.model.CalculationResult;
+import de.intevation.flys.artifacts.model.DataFacet;
+import de.intevation.flys.artifacts.states.DefaultState.ComputeType;
+
+
+public class BedDiffEpochFacet
+extends DataFacet
+{
+    private static Logger logger = Logger.getLogger(BedDensityFacet.class);
+
+    public BedDiffEpochFacet() {
+    }
+
+    public BedDiffEpochFacet(int idx, String name, String description,
+        ComputeType type, String stateId, String hash) {
+        super(idx, name, description, type, hash, stateId);
+    }
+
+    public Object getData(Artifact artifact, CallContext context) {
+        logger.debug("Get data for bed density at index: " + index);
+
+        FLYSArtifact flys = (FLYSArtifact) artifact;
+
+        CalculationResult res = (CalculationResult) flys.compute(context, hash,
+            stateId, type, false);
+
+        Object[] data =
+            (BedDiffEpochResult[]) res.getData(); // TODO CAST TO SPECIFIC CLASS
+
+        return data != null && data.length > index ? data[index] : null;
+    }
+
+    /** Copy deeply. */
+    @Override
+    public Facet deepCopy() {
+        BedDiffEpochFacet copy = new BedDiffEpochFacet();
+        copy.set(this);
+        copy.type = type;
+        copy.hash = hash;
+        copy.stateId = stateId;
+        return copy;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/BedDiffEpochResult.java	Fri Sep 21 14:18:16 2012 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/BedDiffEpochResult.java	Fri Sep 21 14:29:32 2012 +0000
@@ -1,5 +1,7 @@
 package de.intevation.flys.artifacts.model.minfo;
 
+import java.util.Date;
+
 import gnu.trove.TDoubleArrayList;
 
 
@@ -7,6 +9,9 @@
 extends BedDifferencesResult
 {
 
+    protected Date start;
+    protected Date end;
+
     public BedDiffEpochResult () {
         super();
     }
@@ -14,8 +19,21 @@
     public BedDiffEpochResult (
         TDoubleArrayList kms,
         TDoubleArrayList differences,
-        TDoubleArrayList morphWidth
+        TDoubleArrayList heights1,
+        TDoubleArrayList heights2,
+        Date start,
+        Date end
     ) {
-        super(kms, differences, morphWidth);
+        super(kms, differences, heights1, heights2);
+        this.start = start;
+        this.end = end;
+    }
+
+    public Date getStart() {
+        return this.start;
+    }
+
+    public Date getEnd() {
+        return this.end;
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/BedDiffYearFacet.java	Fri Sep 21 14:29:32 2012 +0000
@@ -0,0 +1,52 @@
+package de.intevation.flys.artifacts.model.minfo;
+
+import org.apache.log4j.Logger;
+
+import de.intevation.artifactdatabase.state.Facet;
+import de.intevation.artifacts.Artifact;
+import de.intevation.artifacts.CallContext;
+import de.intevation.flys.artifacts.FLYSArtifact;
+import de.intevation.flys.artifacts.model.CalculationResult;
+import de.intevation.flys.artifacts.model.DataFacet;
+import de.intevation.flys.artifacts.states.DefaultState.ComputeType;
+
+
+public class BedDiffYearFacet
+extends DataFacet
+{
+    private static Logger logger = Logger.getLogger(BedDiffYearFacet.class);
+
+    public BedDiffYearFacet() {
+    }
+
+    public BedDiffYearFacet(int idx, String name, String description,
+        ComputeType type, String stateId, String hash) {
+        super(idx, name, description, type, hash, stateId);
+    }
+
+    public Object getData(Artifact artifact, CallContext context) {
+        logger.debug("Get data for bed density at index: " + index);
+
+        FLYSArtifact flys = (FLYSArtifact) artifact;
+
+        CalculationResult res = (CalculationResult) flys.compute(context, hash,
+            stateId, type, false);
+
+        Object[] data =
+            (BedDiffYearResult[]) res.getData(); // TODO CAST TO SPECIFIC CLASS
+
+        return data != null && data.length > index ? data[index] : null;
+    }
+
+    /** Copy deeply. */
+    @Override
+    public Facet deepCopy() {
+        BedDiffYearFacet copy = new BedDiffYearFacet();
+        copy.set(this);
+        copy.type = type;
+        copy.hash = hash;
+        copy.stateId = stateId;
+        return copy;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/BedDiffYearResult.java	Fri Sep 21 14:18:16 2012 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/BedDiffYearResult.java	Fri Sep 21 14:29:32 2012 +0000
@@ -9,23 +9,36 @@
 
     protected TDoubleArrayList bedHeights;
     protected TDoubleArrayList dataGap;
-
+    protected TDoubleArrayList morphWidth;
+    protected int start;
+    protected int end;
+    
     public BedDiffYearResult () {
         super();
         this.bedHeights = new TDoubleArrayList();
         this.dataGap = new TDoubleArrayList();
+        this.morphWidth = new TDoubleArrayList();
+        this.start = -1;
+        this.end = -1;
     }
 
     public BedDiffYearResult(
         TDoubleArrayList kms,
         TDoubleArrayList differences,
+        TDoubleArrayList heights1,
+        TDoubleArrayList heights2,
         TDoubleArrayList morphWidth,
         TDoubleArrayList bedHeights,
-        TDoubleArrayList dataGap
+        TDoubleArrayList dataGap,
+        int start,
+        int end
     ) {
-        super(kms, differences, morphWidth);
+        super(kms, differences, heights1, heights2);
         this.bedHeights = bedHeights;
         this.dataGap = dataGap;
+        this.morphWidth = morphWidth;
+        this.start = start;
+        this.end = end;
     }
 
     public TDoubleArrayList getBedHeights() {
@@ -35,4 +48,30 @@
     public TDoubleArrayList getDataGap() {
         return this.dataGap;
     }
+
+    public TDoubleArrayList getMorphWidth() {
+        return this.morphWidth;
+    }
+
+    public int getStart() {
+        return this.start;
+    }
+
+    public int getEnd() {
+        return this.end;
+    }
+
+    public double[][] getMorphWidthData() {
+        return new double[][] {
+            kms.toNativeArray(),
+            morphWidth.toNativeArray()
+        };
+    }
+
+    public double[][] getHeightPerYearData() {
+        return new double[][] {
+            kms.toNativeArray(),
+            bedHeights.toNativeArray()
+        };
+    }
 }
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/BedDifferencesResult.java	Fri Sep 21 14:18:16 2012 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/BedDifferencesResult.java	Fri Sep 21 14:29:32 2012 +0000
@@ -11,22 +11,25 @@
 
     protected TDoubleArrayList kms;
     protected TDoubleArrayList differences;
-    protected TDoubleArrayList morphWidth;
+    protected TDoubleArrayList height1;
+    protected TDoubleArrayList height2;
 
     public BedDifferencesResult () {
         kms = new TDoubleArrayList();
         differences = new TDoubleArrayList();
-        morphWidth = new TDoubleArrayList();
+
     }
 
     public BedDifferencesResult(
         TDoubleArrayList kms,
         TDoubleArrayList differences,
-        TDoubleArrayList morpWidth
+        TDoubleArrayList heights1,
+        TDoubleArrayList heights2
     ) {
         this.kms = kms;
         this.differences = differences;
-        this.morphWidth = morpWidth;
+        this.height1 = heights1;
+        this.height2 = heights2;
     }
 
     public TDoubleArrayList getKms() {
@@ -37,7 +40,32 @@
         return this.differences;
     }
 
-    public TDoubleArrayList getMorphWidth() {
-        return this.morphWidth;
+    public double[][] getDifferencesData() {
+        return new double[][] {
+            kms.toNativeArray(),
+            differences.toNativeArray()
+        };
+    }
+
+    public TDoubleArrayList getHeights1() {
+        return this.height1;
+    }
+
+    public TDoubleArrayList getHeights2() {
+        return this.height2;
+    }
+
+    public double[][] getHeights1Data() {
+        return new double[][] {
+            kms.toNativeArray(),
+            height1.toNativeArray()
+        };
+    }
+
+    public double[][] getHeights2Data() {
+        return new double[][] {
+            kms.toNativeArray(),
+            height2.toNativeArray()
+        };
     }
 }
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/minfo/DifferencesState.java	Fri Sep 21 14:18:16 2012 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/minfo/DifferencesState.java	Fri Sep 21 14:29:32 2012 +0000
@@ -1,16 +1,248 @@
 package de.intevation.flys.artifacts.states.minfo;
 
+import java.text.DateFormat;
+import java.util.ArrayList;
+import java.util.List;
+
 import org.apache.log4j.Logger;
 
+import de.intevation.artifactdatabase.state.Facet;
+import de.intevation.artifacts.CallContext;
+import de.intevation.artifacts.CallMeta;
+import de.intevation.flys.artifacts.FLYSArtifact;
+import de.intevation.flys.artifacts.access.BedDifferencesAccess;
+import de.intevation.flys.artifacts.model.CalculationResult;
+import de.intevation.flys.artifacts.model.FacetTypes;
+import de.intevation.flys.artifacts.model.minfo.BedDiffCalculation;
+import de.intevation.flys.artifacts.model.minfo.BedDiffEpochFacet;
+import de.intevation.flys.artifacts.model.minfo.BedDiffEpochResult;
+import de.intevation.flys.artifacts.model.minfo.BedDiffYearFacet;
+import de.intevation.flys.artifacts.model.minfo.BedDiffYearResult;
+import de.intevation.flys.artifacts.model.minfo.BedDifferencesResult;
+import de.intevation.flys.artifacts.resources.Resources;
 import de.intevation.flys.artifacts.states.DefaultState;
+import de.intevation.flys.utils.Formatter;
 
 /**
  * @author <a href="mailto:raimund.renkert@intevation.de">Raimund Renkert</a>
  */
-public class DifferencesState extends DefaultState {
+public class DifferencesState
+extends DefaultState
+implements FacetTypes
+{
     /** The logger used in this class. */
     private static Logger logger = Logger.getLogger(DifferencesState.class);
+    public static final String I18N_DIFF_YEAR = "beddifference.year";
+    public static final String I18N_DIFF_EPOCH = "beddifference.epoch";
+
+    public static final String I18N_FACET_BED_DIFF_YEAR = "facet.bedheight.diff.year";
+    public static final String I18N_FACET_BED_DIFF_ABSOLUTE = "facet.bedheight.diff.absolute";
+    public static final String I18N_FACET_BED_DIFF_MORPH = "facet.bedheight.diff.morph";
+    public static final String I18N_FACET_BED_DIFF_EPOCH = "facet.bedheight.diff.epoch";
+    public static final String I18N_FACET_BED_DIFF_HEIGHT1 = "facet.bedheight.diff.height1";
+    public static final String I18N_FACET_BED_DIFF_HEIGHT2 = "facet.bedheight.diff.height2";
 
     public DifferencesState() {
     }
+
+    @Override
+    public Object computeAdvance(FLYSArtifact artifact, String hash,
+        CallContext context, List<Facet> facets, Object old) {
+        logger.debug("BedQualityState.computeAdvance");
+
+        List<Facet> newFacets = new ArrayList<Facet>();
+
+        BedDifferencesAccess access =
+            new BedDifferencesAccess(artifact, context);
+
+        CalculationResult res = old instanceof CalculationResult ? (CalculationResult) old
+            : new BedDiffCalculation().calculate(access);
+
+        if (facets == null || res == null) {
+            return res;
+        }
+
+        BedDifferencesResult[] results = (BedDifferencesResult[]) res.getData();
+
+        if (results == null || results.length == 0) {
+            logger.warn("Calculation computed no results!");
+            return res;
+        }
+
+        generateFacets(context, newFacets, results, getID(), hash);
+        logger.debug("Created " + newFacets.size() + " new Facets.");
+
+        facets.addAll(newFacets);
+
+        return res;
+    }
+
+    protected void generateFacets(CallContext context, List<Facet> newFacets,
+        BedDifferencesResult[] results, String stateId, String hash) {
+        logger.debug("BedQualityState.generateFacets");
+
+        CallMeta meta = context.getMeta();
+
+        for (int idx = 0; idx < results.length; idx++) {
+            if (results[idx] instanceof BedDiffYearResult) {
+                newFacets.add(new BedDiffYearFacet(
+                    idx,
+                    BED_DIFFERENCE_YEAR,
+                    createBedDiffYearDescription(
+                        meta,
+                        (BedDiffYearResult)results[idx]),
+                    ComputeType.ADVANCE,
+                    stateId,
+                    hash));
+                newFacets.add(new BedDiffYearFacet(
+                    idx,
+                    BED_DIFFERENCE_MORPH_WIDTH,
+                    createBedDiffMorphDescription(
+                        meta,
+                        (BedDiffYearResult)results[idx]),
+                    ComputeType.ADVANCE,
+                    stateId,
+                    hash));
+                newFacets.add(new BedDiffYearFacet(
+                    idx,
+                    BED_DIFFERENCE_YEAR_HEIGHT1,
+                    createBedDiffHeightDescription(
+                        meta,
+                        (BedDiffYearResult)results[idx],
+                        0),
+                    ComputeType.ADVANCE,
+                    stateId,
+                    hash));
+                 newFacets.add(new BedDiffYearFacet(
+                    idx,
+                    BED_DIFFERENCE_YEAR_HEIGHT2,
+                    createBedDiffHeightDescription(
+                        meta,
+                        (BedDiffYearResult)results[idx],
+                        1),
+                    ComputeType.ADVANCE,
+                    stateId,
+                    hash));
+                newFacets.add(new BedDiffYearFacet(
+                    idx,
+                    BED_DIFFERENCE_HEIGHT_YEAR,
+                    createBedDiffAbsoluteDescription(
+                        meta,
+                        (BedDiffYearResult)results[idx]),
+                    ComputeType.ADVANCE,
+                    stateId,
+                    hash));
+            }
+            if (results[idx] instanceof BedDiffEpochResult) {
+                newFacets.add(new BedDiffEpochFacet(
+                    idx,
+                    BED_DIFFERENCE_EPOCH,
+                    createBedDiffEpochDescription(
+                        meta,
+                        (BedDiffEpochResult)results[idx]),
+                    ComputeType.ADVANCE,
+                    stateId,
+                    hash));
+                newFacets.add(new BedDiffEpochFacet(
+                    idx,
+                    BED_DIFFERENCE_EPOCH_HEIGHT1,
+                    createBedDiffHeightEpochDescription(
+                        meta,
+                        (BedDiffEpochResult)results[idx],
+                        0),
+                    ComputeType.ADVANCE,
+                    stateId,
+                    hash));
+                newFacets.add(new BedDiffEpochFacet(
+                    idx,
+                    BED_DIFFERENCE_EPOCH_HEIGHT2,
+                    createBedDiffHeightEpochDescription(
+                        meta,
+                        (BedDiffEpochResult)results[idx],
+                        1),
+                    ComputeType.ADVANCE,
+                    stateId,
+                    hash));
+ 
+            }
+        }
+    }
+
+    private String createBedDiffHeightDescription(
+        CallMeta meta,
+        BedDiffYearResult result,
+        int ndx
+    ) {
+        String range = result.getStart() + " - " + result.getEnd();
+
+        if (ndx == 0) {
+            return Resources.getMsg(meta, I18N_FACET_BED_DIFF_HEIGHT1,
+                I18N_FACET_BED_DIFF_HEIGHT1, new Object[] { range });
+        }
+        else {
+            return Resources.getMsg(meta, I18N_FACET_BED_DIFF_HEIGHT2,
+                I18N_FACET_BED_DIFF_HEIGHT2, new Object[] {range});
+        }
+    }
+
+    private String createBedDiffHeightEpochDescription(
+        CallMeta meta,
+        BedDiffEpochResult result,
+        int ndx
+    ) {
+        DateFormat df = Formatter.getDateFormatter(meta, "yyyy");
+        String range =
+            df.format(result.getStart())
+            + " - " +
+            df.format(result.getEnd());
+
+        if (ndx == 0) {
+            return Resources.getMsg(meta, I18N_FACET_BED_DIFF_HEIGHT1,
+                I18N_FACET_BED_DIFF_HEIGHT1, new Object[] { range });
+        }
+        else {
+            return Resources.getMsg(meta, I18N_FACET_BED_DIFF_HEIGHT2,
+                I18N_FACET_BED_DIFF_HEIGHT2, new Object[] {range});
+        }
+    }
+
+    protected String createBedDiffYearDescription(
+        CallMeta meta,
+        BedDiffYearResult result) {
+        String range = result.getStart() + " - " + result.getEnd();
+
+        return Resources.getMsg(meta, I18N_FACET_BED_DIFF_YEAR,
+            I18N_FACET_BED_DIFF_YEAR, new Object[] { range });
+    }
+
+    protected String createBedDiffMorphDescription(
+        CallMeta meta,
+        BedDiffYearResult result) {
+        String range = result.getStart() + " - " + result.getEnd();
+
+        return Resources.getMsg(meta, I18N_FACET_BED_DIFF_MORPH,
+            I18N_FACET_BED_DIFF_MORPH, new Object[] { range });
+    }
+
+    protected String createBedDiffAbsoluteDescription(
+        CallMeta meta,
+        BedDiffYearResult result) {
+        String range = result.getStart() + " - " + result.getEnd();
+
+        return Resources.getMsg(meta, I18N_FACET_BED_DIFF_ABSOLUTE,
+            I18N_FACET_BED_DIFF_ABSOLUTE, new Object[] { range });
+    }
+
+    protected String createBedDiffEpochDescription(
+        CallMeta meta,
+        BedDiffEpochResult result) {
+        DateFormat df = Formatter.getDateFormatter(meta, "yyyy");
+        String range =
+            df.format(result.getStart())
+            + " - " +
+            df.format(result.getEnd());
+
+        return Resources.getMsg(meta, I18N_FACET_BED_DIFF_EPOCH,
+            I18N_FACET_BED_DIFF_EPOCH, new Object[] { range });
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/minfo/BedDiffEpochInfoGenerator.java	Fri Sep 21 14:29:32 2012 +0000
@@ -0,0 +1,12 @@
+package de.intevation.flys.exports.minfo;
+
+import de.intevation.flys.exports.ChartInfoGenerator;
+
+
+public class BedDiffEpochInfoGenerator
+extends ChartInfoGenerator
+{
+   public BedDiffEpochInfoGenerator() {
+        super(new BedDifferenceEpochGenerator());
+   }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/minfo/BedDiffHeightYearGenerator.java	Fri Sep 21 14:29:32 2012 +0000
@@ -0,0 +1,113 @@
+package de.intevation.flys.exports.minfo;
+
+import org.apache.log4j.Logger;
+import org.jfree.data.xy.XYSeries;
+import org.w3c.dom.Document;
+
+import de.intevation.artifactdatabase.state.ArtifactAndFacet;
+import de.intevation.artifactdatabase.state.Facet;
+import de.intevation.flys.artifacts.model.FacetTypes;
+import de.intevation.flys.artifacts.model.minfo.BedDiffYearResult;
+import de.intevation.flys.exports.StyledSeriesBuilder;
+import de.intevation.flys.exports.XYChartGenerator;
+import de.intevation.flys.jfree.FLYSAnnotation;
+import de.intevation.flys.jfree.StyledXYSeries;
+
+
+public class BedDiffHeightYearGenerator
+extends XYChartGenerator
+implements FacetTypes
+{
+    public enum YAXIS {
+        D(0);
+
+        protected int idx;
+
+        private YAXIS(int c) {
+            idx = c;
+        }
+    }
+
+    /** The logger that is used in this generator. */
+    private static Logger logger = Logger.getLogger(BedDiffHeightYearGenerator.class);
+
+    public static final String I18N_CHART_TITLE = "chart.beddifference.height.title";
+    public static final String I18N_XAXIS_LABEL = "chart.beddifference.height.xaxis.label";
+    public static final String I18N_YAXIS_LABEL = "chart.beddifference.height.yaxis.label";
+
+    public static final String I18N_CHART_TITLE_DEFAULT = "Sohlenhöhen Differenz";
+    public static final String I18N_XAXIS_LABEL_DEFAULT = "Fluss-Km";
+    public static final String I18N_YAXIS_LABEL_DEFAULT = "delta S [cm / Jahr]";
+
+    @Override
+    protected YAxisWalker getYAxisWalker() {
+        return new YAxisWalker() {
+
+            @Override
+            public int length() {
+                return YAXIS.values().length;
+            }
+
+            @Override
+            public String getId(int idx) {
+                YAXIS[] yaxes = YAXIS.values();
+                return yaxes[idx].toString();
+            }
+        };
+    }
+
+    @Override
+    public void doOut(ArtifactAndFacet bundle, Document attr, boolean visible) {
+        String name = bundle.getFacetName();
+
+        logger.debug("doOut: " + name);
+
+        if (name == null) {
+            logger.error("No facet name for doOut(). No output generated!");
+            return;
+        }
+
+        Facet facet = bundle.getFacet();
+
+        if (facet == null) {
+            return;
+        }
+
+        if (name.equals(BED_DIFFERENCE_HEIGHT_YEAR)) {
+            doBedDifferenceYearOut(
+                (BedDiffYearResult) bundle.getData(context),
+                bundle, attr, visible);
+        }
+        else if (name.equals(LONGITUDINAL_ANNOTATION)) {
+            doAnnotations(
+                (FLYSAnnotation) bundle.getData(context),
+                 bundle,
+                 attr,
+                 visible);
+        }
+    }
+
+    @Override
+    protected String getDefaultChartTitle() {
+        return msg(I18N_CHART_TITLE, I18N_CHART_TITLE_DEFAULT);
+    }
+
+    @Override
+    protected String getDefaultXAxisLabel() {
+        return msg(I18N_XAXIS_LABEL, I18N_XAXIS_LABEL_DEFAULT);
+    }
+
+    @Override
+    protected String getDefaultYAxisLabel(int pos) {
+        return msg(I18N_YAXIS_LABEL, I18N_YAXIS_LABEL_DEFAULT);
+    }
+
+    protected void doBedDifferenceYearOut(BedDiffYearResult data,
+        ArtifactAndFacet aandf, Document theme, boolean visible) {
+
+        XYSeries series = new StyledXYSeries(aandf.getFacetDescription(), theme);
+        StyledSeriesBuilder.addPoints(series, data.getHeightPerYearData(), true);
+
+        addAxisSeries(series, YAXIS.D.idx, visible);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/minfo/BedDiffHeightYearInfoGenerator.java	Fri Sep 21 14:29:32 2012 +0000
@@ -0,0 +1,12 @@
+package de.intevation.flys.exports.minfo;
+
+import de.intevation.flys.exports.ChartInfoGenerator;
+
+
+public class BedDiffHeightYearInfoGenerator
+extends ChartInfoGenerator
+{
+    public BedDiffHeightYearInfoGenerator() {
+        super (new BedDiffHeightYearGenerator());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/minfo/BedDiffYearInfoGenerator.java	Fri Sep 21 14:29:32 2012 +0000
@@ -0,0 +1,12 @@
+package de.intevation.flys.exports.minfo;
+
+import de.intevation.flys.exports.ChartInfoGenerator;
+
+
+public class BedDiffYearInfoGenerator
+extends ChartInfoGenerator
+{
+    public BedDiffYearInfoGenerator() {
+        super(new BedDifferenceYearGenerator());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/minfo/BedDifferenceEpochGenerator.java	Fri Sep 21 14:29:32 2012 +0000
@@ -0,0 +1,151 @@
+package de.intevation.flys.exports.minfo;
+
+import org.apache.log4j.Logger;
+import org.jfree.data.xy.XYSeries;
+import org.w3c.dom.Document;
+
+import de.intevation.artifactdatabase.state.ArtifactAndFacet;
+import de.intevation.artifactdatabase.state.Facet;
+import de.intevation.flys.artifacts.model.FacetTypes;
+import de.intevation.flys.artifacts.model.minfo.BedDiffEpochResult;
+import de.intevation.flys.exports.StyledSeriesBuilder;
+import de.intevation.flys.exports.XYChartGenerator;
+import de.intevation.flys.jfree.FLYSAnnotation;
+import de.intevation.flys.jfree.StyledXYSeries;
+
+
+public class BedDifferenceEpochGenerator
+extends XYChartGenerator
+implements FacetTypes
+{
+    public enum YAXIS {
+        D(0), H(1);
+
+        protected int idx;
+
+        private YAXIS(int c) {
+            idx = c;
+        }
+    }
+
+    /** The logger that is used in this generator. */
+    private static Logger logger = Logger.getLogger(BedQualityGenerator.class);
+
+    public static final String I18N_CHART_TITLE = "chart.beddifference.epoch.title";
+    public static final String I18N_XAXIS_LABEL = "chart.beddifference.xaxis.label";
+    public static final String I18N_YAXIS_LABEL = "chart.beddifference.yaxis.label.diff";
+    public static final String I18N_SECOND_YAXIS_LABEL = "chart.beddifference.yaxis.label.height";
+
+    public static final String I18N_CHART_TITLE_DEFAULT = "Sohlenhöhen Differenz";
+    public static final String I18N_XAXIS_LABEL_DEFAULT = "Fluss-Km";
+    public static final String I18N_YAXIS_LABEL_DEFAULT = "delta S [m]";
+    public static final String I18N_SECOND_YAXIS_LABEL_DEFAULT = "Höhe [m]";
+
+    @Override
+    protected YAxisWalker getYAxisWalker() {
+        return new YAxisWalker() {
+
+            @Override
+            public int length() {
+                return YAXIS.values().length;
+            }
+
+            @Override
+            public String getId(int idx) {
+                YAXIS[] yaxes = YAXIS.values();
+                return yaxes[idx].toString();
+            }
+        };
+    }
+
+    @Override
+    public void doOut(ArtifactAndFacet bundle, Document attr, boolean visible) {
+        String name = bundle.getFacetName();
+
+        logger.debug("doOut: " + name);
+
+        if (name == null) {
+            logger.error("No facet name for doOut(). No output generated!");
+            return;
+        }
+
+        Facet facet = bundle.getFacet();
+
+        if (facet == null) {
+            return;
+        }
+
+        if (name.equals(BED_DIFFERENCE_EPOCH)) {
+            doBedDifferenceEpochOut(
+                (BedDiffEpochResult) bundle.getData(context),
+                bundle, attr, visible);
+        }
+        else if (name.equals(BED_DIFFERENCE_EPOCH_HEIGHT1)) {
+            doBedDifferenceHeightsOut((BedDiffEpochResult)bundle.getData(context),
+                bundle, attr, visible, 0);
+        }
+        else if (name.equals(BED_DIFFERENCE_EPOCH_HEIGHT2)) {
+            doBedDifferenceHeightsOut((BedDiffEpochResult)bundle.getData(context),
+                bundle, attr, visible, 1);
+        }
+        else if (name.equals(LONGITUDINAL_ANNOTATION)) {
+            doAnnotations(
+                (FLYSAnnotation) bundle.getData(context),
+                 bundle,
+                 attr,
+                 visible);
+        }
+    }
+
+    @Override
+    protected String getDefaultChartTitle() {
+        return msg(I18N_CHART_TITLE, I18N_CHART_TITLE_DEFAULT);
+    }
+
+    @Override
+    protected String getDefaultXAxisLabel() {
+        return msg(I18N_XAXIS_LABEL, I18N_XAXIS_LABEL_DEFAULT);
+    }
+
+    @Override
+    protected String getDefaultYAxisLabel(int pos) {
+        String label = "default";
+        if (pos == YAXIS.D.idx) {
+            label = msg(I18N_YAXIS_LABEL, I18N_YAXIS_LABEL_DEFAULT);
+        }
+        else if (pos == YAXIS.H.idx) {
+            label = msg(I18N_SECOND_YAXIS_LABEL, I18N_SECOND_YAXIS_LABEL_DEFAULT);
+        }
+ 
+        return label;
+    }
+
+    protected void doBedDifferenceEpochOut(BedDiffEpochResult data,
+        ArtifactAndFacet aandf, Document theme, boolean visible) {
+
+        XYSeries series = new StyledXYSeries(aandf.getFacetDescription(), theme);
+        StyledSeriesBuilder.addPoints(series, data.getDifferencesData(), true);
+
+        addAxisSeries(series, YAXIS.D.idx, visible);
+    }
+
+    private void doBedDifferenceHeightsOut(
+        BedDiffEpochResult data,
+        ArtifactAndFacet bundle,
+        Document attr,
+        boolean visible,
+        int idx) {
+         logger.debug("doBedDifferenceHeightOut()");
+
+        XYSeries series = new StyledXYSeries(bundle.getFacetDescription(), attr);
+        if (idx == 0) {
+            StyledSeriesBuilder.addPoints(series, data.getHeights1Data(), true);
+        }
+        else {
+            StyledSeriesBuilder.addPoints(series, data.getHeights2Data(), true);
+        }
+
+        addAxisSeries(series, YAXIS.H.idx, visible);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/minfo/BedDifferenceYearGenerator.java	Fri Sep 21 14:29:32 2012 +0000
@@ -0,0 +1,173 @@
+package de.intevation.flys.exports.minfo;
+
+import org.apache.log4j.Logger;
+import org.jfree.data.xy.XYSeries;
+import org.w3c.dom.Document;
+
+import de.intevation.artifactdatabase.state.ArtifactAndFacet;
+import de.intevation.artifactdatabase.state.Facet;
+import de.intevation.flys.artifacts.model.FacetTypes;
+import de.intevation.flys.artifacts.model.minfo.BedDiffYearResult;
+import de.intevation.flys.exports.StyledSeriesBuilder;
+import de.intevation.flys.exports.XYChartGenerator;
+import de.intevation.flys.jfree.FLYSAnnotation;
+import de.intevation.flys.jfree.StyledXYSeries;
+
+
+public class BedDifferenceYearGenerator
+extends XYChartGenerator
+implements FacetTypes
+{
+    public enum YAXIS {
+        D(0), M(1), H(2);
+
+        protected int idx;
+
+        private YAXIS(int c) {
+            idx = c;
+        }
+    }
+
+    /** The logger that is used in this generator. */
+    private static Logger logger = Logger.getLogger(BedDifferenceYearGenerator.class);
+
+    public static final String I18N_CHART_TITLE = "chart.beddifference.year.title";
+    public static final String I18N_XAXIS_LABEL = "chart.beddifference.xaxis.label";
+    public static final String I18N_YAXIS_LABEL = "chart.beddifference.yaxis.label.diff";
+    public static final String I18N_SECOND_YAXIS_LABEL = "chart.beddifference.yaxis.label.morph";
+    public static final String I18N_THIRD_YAXIS_LABEL = "chart.beddifference.yaxis.label.heights";
+
+    public static final String I18N_CHART_TITLE_DEFAULT = "Sohlenhöhen Differenz";
+    public static final String I18N_XAXIS_LABEL_DEFAULT = "Fluss-Km";
+    public static final String I18N_YAXIS_LABEL_DEFAULT = "delta S [m]";
+    public static final String I18N_SECOND_YAXIS_LABEL_DEFAULT = "Morph. Breite [m]";
+    public static final String I18N_THIRD_YAXIS_LABEL_DEFAULT = "Höhe [m]";
+
+    @Override
+    protected YAxisWalker getYAxisWalker() {
+        return new YAxisWalker() {
+
+            @Override
+            public int length() {
+                return YAXIS.values().length;
+            }
+
+            @Override
+            public String getId(int idx) {
+                YAXIS[] yaxes = YAXIS.values();
+                return yaxes[idx].toString();
+            }
+        };
+    }
+
+    @Override
+    public void doOut(ArtifactAndFacet bundle, Document attr, boolean visible) {
+        String name = bundle.getFacetName();
+
+        logger.debug("doOut: " + name);
+
+        if (name == null) {
+            logger.error("No facet name for doOut(). No output generated!");
+            return;
+        }
+
+        Facet facet = bundle.getFacet();
+
+        if (facet == null) {
+            return;
+        }
+
+        if (name.equals(BED_DIFFERENCE_YEAR)) {
+            doBedDifferenceYearOut(
+                (BedDiffYearResult) bundle.getData(context),
+                bundle, attr, visible);
+        }
+        else if (name.equals(BED_DIFFERENCE_MORPH_WIDTH)) {
+            doBedDifferenceMorphWidthOut(
+                (BedDiffYearResult) bundle.getData(context),
+                bundle, attr, visible);
+        }
+        else if (name.equals(BED_DIFFERENCE_YEAR_HEIGHT1)) {
+            doBedDifferenceHeightsOut(
+                (BedDiffYearResult)bundle.getData(context),
+                bundle, attr, visible, 0);
+        }
+        else if (name.equals(BED_DIFFERENCE_YEAR_HEIGHT2)) {
+            doBedDifferenceHeightsOut(
+                (BedDiffYearResult)bundle.getData(context),
+                bundle, attr, visible, 1);
+        }
+        else if (name.equals(LONGITUDINAL_ANNOTATION)) {
+            doAnnotations(
+                (FLYSAnnotation) bundle.getData(context),
+                 bundle,
+                 attr,
+                 visible);
+        }
+    }
+
+    private void doBedDifferenceHeightsOut(
+        BedDiffYearResult data,
+        ArtifactAndFacet bundle,
+        Document attr,
+        boolean visible,
+        int idx) {
+         logger.debug("doBedDifferenceYearOut()");
+
+        XYSeries series = new StyledXYSeries(bundle.getFacetDescription(), attr);
+        if (idx == 0) {
+            StyledSeriesBuilder.addPoints(series, data.getHeights1Data(), true);
+        }
+        else {
+            StyledSeriesBuilder.addPoints(series, data.getHeights2Data(), true);
+        }
+
+        addAxisSeries(series, YAXIS.H.idx, visible);
+    }
+
+    @Override
+    protected String getDefaultChartTitle() {
+        return msg(I18N_CHART_TITLE, I18N_CHART_TITLE_DEFAULT);
+    }
+
+    @Override
+    protected String getDefaultXAxisLabel() {
+        return msg(I18N_XAXIS_LABEL, I18N_XAXIS_LABEL_DEFAULT);
+    }
+
+    @Override
+    protected String getDefaultYAxisLabel(int pos) {
+        String label = "default";
+        if (pos == YAXIS.D.idx) {
+            label = msg(I18N_YAXIS_LABEL, I18N_YAXIS_LABEL_DEFAULT);
+        }
+        else if (pos == YAXIS.M.idx) {
+            label = msg(I18N_SECOND_YAXIS_LABEL, I18N_SECOND_YAXIS_LABEL_DEFAULT);
+        }
+        else if (pos == YAXIS.H.idx) {
+            label = msg(I18N_THIRD_YAXIS_LABEL, I18N_THIRD_YAXIS_LABEL_DEFAULT);
+        }
+ 
+        return label;
+    }
+
+    protected void doBedDifferenceYearOut(BedDiffYearResult data,
+        ArtifactAndFacet aandf, Document theme, boolean visible) {
+        logger.debug("doBedDifferenceYearOut()");
+
+        XYSeries series = new StyledXYSeries(aandf.getFacetDescription(), theme);
+        StyledSeriesBuilder.addPoints(series, data.getDifferencesData(), true);
+
+        addAxisSeries(series, YAXIS.D.idx, visible);
+    }
+
+    protected void doBedDifferenceMorphWidthOut(BedDiffYearResult data,
+        ArtifactAndFacet aandf, Document theme, boolean visible) {
+        logger.debug("doBedDifferencesMorphWidthOut()");
+
+        XYSeries series = new StyledXYSeries(aandf.getFacetDescription(), theme);
+        StyledSeriesBuilder.addPoints(series, data.getMorphWidthData(), true);
+
+        addAxisSeries(series, YAXIS.M.idx, visible);
+    }
+}

http://dive4elements.wald.intevation.org