[PATCH 1 of 2] Merge branch generator-refectoring into default
Wald Commits
scm-commit at wald.intevation.org
Tue Sep 24 12:32:18 CEST 2013
# HG changeset patch
# User Andre Heinecke <aheinecke at intevation.de>
# Date 1380018584 -7200
# Node ID 3c7471b929d1391033129e42571066f00b2ce421
# Parent bdadffad35b10cb2205f10198e99fd1ad5898ff6
# Parent a0b00cfe1799406c11a323b501e6339726bc5be5
Merge branch generator-refectoring into default.
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/doc/conf/conf.xml
--- a/artifacts/doc/conf/conf.xml Mon Sep 23 11:37:13 2013 +0200
+++ b/artifacts/doc/conf/conf.xml Tue Sep 24 12:29:44 2013 +0200
@@ -7,6 +7,7 @@
<!ENTITY rest-server SYSTEM "rest-server.xml">
<!ENTITY floodmap SYSTEM "floodmap.xml">
<!ENTITY rivermap SYSTEM "rivermap.xml">
+ <!ENTITY generators SYSTEM "generators.xml">
]>
<artifact-database>
<export-secret>YOUR_SECRET</export-secret>
@@ -284,104 +285,7 @@
</hook>
</hooks>
- <output-generators>
- <output-generator name="discharge_curve">org.dive4elements.river.exports.DischargeCurveGenerator</output-generator>
- <output-generator name="discharge_curve_chartinfo">org.dive4elements.river.exports.DischargeCurveInfoGenerator</output-generator>
- <output-generator name="cross_section">org.dive4elements.river.exports.CrossSectionGenerator</output-generator>
- <output-generator name="cross_section_chartinfo">org.dive4elements.river.exports.CrossSectionInfoGenerator</output-generator>
- <output-generator name="computed_discharge_curve">org.dive4elements.river.exports.ComputedDischargeCurveGenerator</output-generator>
- <output-generator name="computed_discharge_curve_chartinfo">org.dive4elements.river.exports.ComputedDischargeCurveInfoGenerator</output-generator>
- <output-generator name="longitudinal_section">org.dive4elements.river.exports.LongitudinalSectionGenerator</output-generator>
- <output-generator name="longitudinal_section_chartinfo">org.dive4elements.river.exports.LongitudinalSectionInfoGenerator</output-generator>
- <output-generator name="duration_curve">org.dive4elements.river.exports.DurationCurveGenerator</output-generator>
- <output-generator name="duration_curve_chartinfo">org.dive4elements.river.exports.DurationCurveInfoGenerator</output-generator>
- <output-generator name="discharge_longitudinal_section">org.dive4elements.river.exports.DischargeLongitudinalSectionGenerator</output-generator>
- <output-generator name="discharge_longitudinal_section_chartinfo">org.dive4elements.river.exports.DischargeLongitudinalSectionInfoGenerator</output-generator>
- <output-generator name="waterlevel_export">org.dive4elements.river.exports.WaterlevelExporter</output-generator>
- <output-generator name="extreme_wq_curve">org.dive4elements.river.exports.extreme.ExtremeWQCurveGenerator</output-generator>
- <output-generator name="extreme_curve_export">org.dive4elements.river.exports.WaterlevelExporter</output-generator>
- <output-generator name="extreme_wq_curve_chartinfo">org.dive4elements.river.exports.extreme.ExtremeWQCurveInfoGenerator</output-generator>
- <output-generator name="fix_wq_curve">org.dive4elements.river.exports.fixings.FixWQCurveGenerator</output-generator>
- <output-generator name="fix_wq_curve_chartinfo">org.dive4elements.river.exports.fixings.FixWQCurveInfoGenerator</output-generator>
- <output-generator name="durationcurve_export">org.dive4elements.river.exports.DurationCurveExporter</output-generator>
- <output-generator name="computed_dischargecurve_export">org.dive4elements.river.exports.ComputedDischargeCurveExporter</output-generator>
- <output-generator name="discharge_longitudinal_section_export">org.dive4elements.river.exports.DischargeLongitudinalSectionExporter</output-generator>
- <output-generator name="w_differences">org.dive4elements.river.exports.WDifferencesCurveGenerator</output-generator>
- <output-generator name="w_differences_chartinfo">org.dive4elements.river.exports.WDifferencesCurveInfoGenerator</output-generator>
- <output-generator name="w_differences_export">org.dive4elements.river.exports.WDifferencesExporter</output-generator>
- <output-generator name="floodmap">org.dive4elements.river.exports.MapGenerator</output-generator>
- <output-generator name="map">org.dive4elements.river.exports.MapGenerator</output-generator>
- <output-generator name="reference_curve">org.dive4elements.river.exports.ReferenceCurveGenerator</output-generator>
- <output-generator name="reference_curve_normalized">org.dive4elements.river.exports.NormalizedReferenceCurveGenerator</output-generator>
- <output-generator name="reference_curve_normalized_chartinfo">org.dive4elements.river.exports.NormalizedReferenceCurveInfoGenerator</output-generator>
- <output-generator name="reference_curve_chartinfo">org.dive4elements.river.exports.ReferenceCurveInfoGenerator</output-generator>
- <output-generator name="reference_curve_export">org.dive4elements.river.exports.ReferenceCurveExporter</output-generator>
- <output-generator name="historical_discharge">org.dive4elements.river.exports.HistoricalDischargeCurveGenerator</output-generator>
- <output-generator name="historical_discharge_chartinfo">org.dive4elements.river.exports.HistoricalDischargeCurveInfoGenerator</output-generator>
- <output-generator name="historical_discharge_wq">org.dive4elements.river.exports.HistoricalDischargeWQCurveGenerator</output-generator>
- <output-generator name="historical_discharge_wq_chartinfo">org.dive4elements.river.exports.HistoricalDischargeWQCurveInfoGenerator</output-generator>
- <output-generator name="historical_discharge_export">org.dive4elements.river.exports.HistoricalDischargeCurveExporter</output-generator>
- <output-generator name="flow_velocity">org.dive4elements.river.exports.FlowVelocityGenerator</output-generator>
- <output-generator name="flow_velocity_chartinfo">org.dive4elements.river.exports.FlowVelocityInfoGenerator</output-generator>
- <output-generator name="flow_velocity_export">org.dive4elements.river.exports.FlowVelocityExporter</output-generator>
- <output-generator name="bedheight_middle">org.dive4elements.river.exports.MiddleBedHeightGenerator</output-generator>
- <output-generator name="bedheight_middle_chartinfo">org.dive4elements.river.exports.MiddleBedHeightInfoGenerator</output-generator>
- <output-generator name="bedheight_middle_export">org.dive4elements.river.exports.MiddleBedHeightExporter</output-generator>
- <output-generator name="bed_longitudinal_section">org.dive4elements.river.exports.minfo.BedQualityGenerator</output-generator>
- <output-generator name="bed_longitudinal_section_chartinfo">org.dive4elements.river.exports.minfo.BedQualityInfoGenerator</output-generator>
- <output-generator name="bed_quality_export">org.dive4elements.river.exports.minfo.BedQualityExporter</output-generator>
- <output-generator name="bed_difference_year">org.dive4elements.river.exports.minfo.BedDifferenceYearGenerator</output-generator>
- <output-generator name="bed_difference_year_chartinfo">org.dive4elements.river.exports.minfo.BedDiffYearInfoGenerator</output-generator>
- <output-generator name="bed_difference_epoch">org.dive4elements.river.exports.minfo.BedDifferenceEpochGenerator</output-generator>
- <output-generator name="bed_difference_epoch_chartinfo">org.dive4elements.river.exports.minfo.BedDiffEpochInfoGenerator</output-generator>
- <output-generator name="bed_difference_height_year">org.dive4elements.river.exports.minfo.BedDiffHeightYearGenerator</output-generator>
- <output-generator name="bed_difference_height_year_chartinfo">org.dive4elements.river.exports.minfo.BedDiffHeightYearInfoGenerator</output-generator>
- <output-generator name="bedheight_difference_export">org.dive4elements.river.exports.minfo.BedDifferenceExporter</output-generator>
- <output-generator name="sq_relation_a">org.dive4elements.river.exports.sq.SQRelationGeneratorA</output-generator>
- <output-generator name="sq_relation_b">org.dive4elements.river.exports.sq.SQRelationGeneratorB</output-generator>
- <output-generator name="sq_relation_c">org.dive4elements.river.exports.sq.SQRelationGeneratorC</output-generator>
- <output-generator name="sq_relation_d">org.dive4elements.river.exports.sq.SQRelationGeneratorD</output-generator>
- <output-generator name="sq_relation_e">org.dive4elements.river.exports.sq.SQRelationGeneratorE</output-generator>
- <output-generator name="sq_relation_f">org.dive4elements.river.exports.sq.SQRelationGeneratorF</output-generator>
- <output-generator name="sq_relation_a_chartinfo">org.dive4elements.river.exports.sq.SQRelationInfoGenerator</output-generator>
- <output-generator name="sq_relation_b_chartinfo">org.dive4elements.river.exports.sq.SQRelationInfoGenerator</output-generator>
- <output-generator name="sq_relation_c_chartinfo">org.dive4elements.river.exports.sq.SQRelationInfoGenerator</output-generator>
- <output-generator name="sq_relation_d_chartinfo">org.dive4elements.river.exports.sq.SQRelationInfoGenerator</output-generator>
- <output-generator name="sq_relation_e_chartinfo">org.dive4elements.river.exports.sq.SQRelationInfoGenerator</output-generator>
- <output-generator name="sq_relation_f_chartinfo">org.dive4elements.river.exports.sq.SQRelationInfoGenerator</output-generator>
- <output-generator name="sq_relation_export">org.dive4elements.river.exports.sq.SQRelationExporter</output-generator>
- <output-generator name="sq_overview">org.dive4elements.river.exports.sq.SQOverviewGenerator</output-generator>
- <output-generator name="fix_parameters_export">org.dive4elements.river.exports.fixings.ParametersExporter</output-generator>
- <output-generator name="fix_deltawt_export">org.dive4elements.river.exports.fixings.DeltaWtExporter</output-generator>
- <output-generator name="fix_deltawt_curve">org.dive4elements.river.exports.fixings.FixDeltaWtGenerator</output-generator>
- <output-generator name="fix_deltawt_curve_chartinfo">org.dive4elements.river.exports.fixings.FixDeltaWtInfoGenerator</output-generator>
- <output-generator name="fix_longitudinal_section_curve">org.dive4elements.river.exports.fixings.FixLongitudinalSectionGenerator</output-generator>
- <output-generator name="fix_longitudinal_section_curve_chartinfo">org.dive4elements.river.exports.fixings.FixLongitudinalSectionInfoGenerator</output-generator>
- <output-generator name="fix_derivate_curve">org.dive4elements.river.exports.fixings.FixDerivedCurveGenerator</output-generator>
- <output-generator name="fix_derivate_curve_chartinfo">org.dive4elements.river.exports.fixings.FixDerivedCurveInfoGenerator</output-generator>
- <output-generator name="fix_waterlevel_export">org.dive4elements.river.exports.WaterlevelExporter</output-generator>
- <output-generator name="fix_vollmer_wq_curve">org.dive4elements.river.exports.fixings.FixWQCurveGenerator</output-generator>
- <output-generator name="fix_vollmer_wq_curve_chartinfo">org.dive4elements.river.exports.fixings.FixWQCurveInfoGenerator</output-generator>
- <output-generator name="sedimentload_ls">org.dive4elements.river.exports.minfo.SedimentLoadLSGenerator</output-generator>
- <output-generator name="sedimentload_ls_export">org.dive4elements.river.exports.minfo.SedimentLoadExporter</output-generator>
- <output-generator name="sedimentload_ls_chartinfo">org.dive4elements.river.exports.minfo.SedimentLoadLSInfoGenerator</output-generator>
- <!-- Error report generators. -->
- <output-generator name="discharge_longitudinal_section_report">org.dive4elements.river.exports.ReportGenerator</output-generator>
- <output-generator name="waterlevel_report">org.dive4elements.river.exports.ReportGenerator</output-generator>
- <output-generator name="computed_dischargecurve_report">org.dive4elements.river.exports.ReportGenerator</output-generator>
- <output-generator name="durationcurve_report">org.dive4elements.river.exports.ReportGenerator</output-generator>
- <output-generator name="wsplgen_report">org.dive4elements.river.exports.ReportGenerator</output-generator>
- <output-generator name="historical_discharge_report">org.dive4elements.river.exports.ReportGenerator</output-generator>
- <output-generator name="reference_curve_report">org.dive4elements.river.exports.ReportGenerator</output-generator>
- <output-generator name="fix_report">org.dive4elements.river.exports.ReportGenerator</output-generator>
- <output-generator name="extreme_curve_report">org.dive4elements.river.exports.ReportGenerator</output-generator>
- <output-generator name="sedimentload_ls_report">org.dive4elements.river.exports.ReportGenerator</output-generator>
- <!-- AT exporter. -->
- <output-generator name="computed_dischargecurve_at_export">org.dive4elements.river.exports.ATExporter</output-generator>
- <output-generator name="gauge_discharge_curve_at_export">org.dive4elements.river.exports.ATExporter</output-generator>
- <output-generator name="fix_wq_curve_at_export">org.dive4elements.river.exports.fixings.FixATExport</output-generator>
- <output-generator name="wsplgen">org.dive4elements.river.exports.ShapeExporter</output-generator>
- </output-generators>
+ &generators;
<!-- Path to the template file of the meta data. -->
<metadata>
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/doc/conf/generators.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/doc/conf/generators.xml Tue Sep 24 12:29:44 2013 +0200
@@ -0,0 +1,146 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<output-generators>
+ <output-generator names="discharge_curve" class="org.dive4elements.river.exports.DischargeCurveGenerator"/>
+ <output-generator names="discharge_curve_chartinfo" class="org.dive4elements.river.exports.DischargeCurveInfoGenerator"/>
+ <output-generator names="cross_section" class="org.dive4elements.river.exports.CrossSectionGenerator"/>
+ <output-generator names="cross_section_chartinfo" class="org.dive4elements.river.exports.CrossSectionInfoGenerator"/>
+ <output-generator names="computed_discharge_curve" class="org.dive4elements.river.exports.ComputedDischargeCurveGenerator"/>
+ <output-generator names="computed_discharge_curve_chartinfo" class="org.dive4elements.river.exports.ComputedDischargeCurveInfoGenerator"/>
+ <output-generator names="longitudinal_section,longitudinal_section_chartinfo,discharge_longitudinal_section,discharge_longitudinal_section_chartinfo"
+ class="org.dive4elements.river.exports.LongitudinalSectionGenerator2"
+ converter="org.dive4elements.river.exports.DiagramAttributes">
+ <axis name="W"/>
+ <axis name="D"/>
+ <axis name="Q" include-zero="true"/>
+ <axis name="" type="X"/>
+ <title key="chart.longitudinal.section.title" default="W-Längsschnitt"/>
+ <subtitle key="chart.longitudinal.section.subtitle" default="-">
+ <arg expr="artifact.river"/>
+ <arg expr="artifact.ld_from" type="double"/>
+ <arg expr="artifact.ld_to" type="double"/>
+ </subtitle>
+ <domain-axis key="chart.longitudinal.section.xaxis.label" default="Fluss-Km">
+ <arg expr="artifact.river"/>
+ </domain-axis>
+ <processor class="org.dive4elements.river.exports.process.AnnotationProcessor" axis="none"/>
+ <processor class="org.dive4elements.river.exports.process.WOutProcessor" axis="W"/>
+ <processor class="org.dive4elements.river.exports.process.WDiffProcessor" axis="D"/>
+ <processor class="org.dive4elements.river.exports.process.QOutProcessor" axis="Q"/>
+ <processor class="org.dive4elements.river.exports.process.BedheightProcessor" axis="W"/>
+ <processor class="org.dive4elements.river.exports.process.BedDiffYearProcessor" axis="W"/>
+ <processor class="org.dive4elements.river.exports.process.BedDiffHeightYearProcessor" axis="W"/>
+ <processor class="org.dive4elements.river.exports.process.ManualPointsProcessor" axis="W"/>
+ <!-- The area processor decides based on the facet name which axis to choose.
+ You have to ensure that there is a W and Q axis accordingly -->
+ <processor class="org.dive4elements.river.exports.process.AreaProcessor" axis="none"/>
+ </output-generator>
+ <output-generator names="w_differences,w_differences_chartinfo"
+ class="org.dive4elements.river.exports.DiagramGenerator"
+ converter="org.dive4elements.river.exports.DiagramAttributes">
+ <axis name="W"/>
+ <axis name="D"/>
+ <axis name="Q" include-zero="true"/>
+ <axis name="" type="X"/>
+ <title key="chart.w_differences.title" default="Differences"/>
+ <subtitle key="chart.w_differences.subtitle" default="-">
+ <arg expr="artifact.river"/>
+ </subtitle>
+ <domain-axis key="chart.longitudinal.section.xaxis.label" default="Fluss-Km">
+ <arg expr="artifact.river"/>
+ </domain-axis>
+ <processor class="org.dive4elements.river.exports.process.AnnotationProcessor" axis="none"/>
+ <processor class="org.dive4elements.river.exports.process.WOutProcessor" axis="W"/>
+ <processor class="org.dive4elements.river.exports.process.WDiffProcessor" axis="D"/>
+ <processor class="org.dive4elements.river.exports.process.QOutProcessor" axis="Q"/>
+ <processor class="org.dive4elements.river.exports.process.BedheightProcessor" axis="W"/>
+ <processor class="org.dive4elements.river.exports.process.BedDiffYearProcessor" axis="W"/>
+ <processor class="org.dive4elements.river.exports.process.BedDiffHeightYearProcessor" axis="W"/>
+ <processor class="org.dive4elements.river.exports.process.ManualPointsProcessor" axis="W"/>
+ <processor class="org.dive4elements.river.exports.process.AreaProcessor" axis="none"/>
+ </output-generator>
+ <output-generator names="duration_curve" class="org.dive4elements.river.exports.DurationCurveGenerator"/>
+ <output-generator names="duration_curve_chartinfo" class="org.dive4elements.river.exports.DurationCurveInfoGenerator"/>
+ <output-generator names="waterlevel_export" class="org.dive4elements.river.exports.WaterlevelExporter"/>
+ <output-generator names="extreme_wq_curve" class="org.dive4elements.river.exports.extreme.ExtremeWQCurveGenerator"/>
+ <output-generator names="extreme_curve_export" class="org.dive4elements.river.exports.WaterlevelExporter"/>
+ <output-generator names="extreme_wq_curve_chartinfo" class="org.dive4elements.river.exports.extreme.ExtremeWQCurveInfoGenerator"/>
+ <output-generator names="fix_wq_curve" class="org.dive4elements.river.exports.fixings.FixWQCurveGenerator"/>
+ <output-generator names="fix_wq_curve_chartinfo" class="org.dive4elements.river.exports.fixings.FixWQCurveInfoGenerator"/>
+ <output-generator names="durationcurve_export" class="org.dive4elements.river.exports.DurationCurveExporter"/>
+ <output-generator names="computed_dischargecurve_export" class="org.dive4elements.river.exports.ComputedDischargeCurveExporter"/>
+ <output-generator names="discharge_longitudinal_section_export" class="org.dive4elements.river.exports.DischargeLongitudinalSectionExporter"/>
+ <output-generator names="w_differences_export" class="org.dive4elements.river.exports.WDifferencesExporter"/>
+ <output-generator names="floodmap" class="org.dive4elements.river.exports.MapGenerator"/>
+ <output-generator names="map" class="org.dive4elements.river.exports.MapGenerator"/>
+ <output-generator names="reference_curve" class="org.dive4elements.river.exports.ReferenceCurveGenerator"/>
+ <output-generator names="reference_curve_normalized" class="org.dive4elements.river.exports.NormalizedReferenceCurveGenerator"/>
+ <output-generator names="reference_curve_normalized_chartinfo" class="org.dive4elements.river.exports.NormalizedReferenceCurveInfoGenerator"/>
+ <output-generator names="reference_curve_chartinfo" class="org.dive4elements.river.exports.ReferenceCurveInfoGenerator"/>
+ <output-generator names="reference_curve_export" class="org.dive4elements.river.exports.ReferenceCurveExporter"/>
+ <output-generator names="historical_discharge" class="org.dive4elements.river.exports.HistoricalDischargeCurveGenerator"/>
+ <output-generator names="historical_discharge_chartinfo" class="org.dive4elements.river.exports.HistoricalDischargeCurveInfoGenerator"/>
+ <output-generator names="historical_discharge_wq" class="org.dive4elements.river.exports.HistoricalDischargeWQCurveGenerator"/>
+ <output-generator names="historical_discharge_wq_chartinfo" class="org.dive4elements.river.exports.HistoricalDischargeWQCurveInfoGenerator"/>
+ <output-generator names="historical_discharge_export" class="org.dive4elements.river.exports.HistoricalDischargeCurveExporter"/>
+ <output-generator names="flow_velocity" class="org.dive4elements.river.exports.FlowVelocityGenerator"/>
+ <output-generator names="flow_velocity_chartinfo" class="org.dive4elements.river.exports.FlowVelocityInfoGenerator"/>
+ <output-generator names="flow_velocity_export" class="org.dive4elements.river.exports.FlowVelocityExporter"/>
+ <output-generator names="bedheight_middle" class="org.dive4elements.river.exports.MiddleBedHeightGenerator"/>
+ <output-generator names="bedheight_middle_chartinfo" class="org.dive4elements.river.exports.MiddleBedHeightInfoGenerator"/>
+ <output-generator names="bedheight_middle_export" class="org.dive4elements.river.exports.MiddleBedHeightExporter"/>
+ <output-generator names="bed_longitudinal_section" class="org.dive4elements.river.exports.minfo.BedQualityGenerator"/>
+ <output-generator names="bed_longitudinal_section_chartinfo" class="org.dive4elements.river.exports.minfo.BedQualityInfoGenerator"/>
+ <output-generator names="bed_quality_export" class="org.dive4elements.river.exports.minfo.BedQualityExporter"/>
+ <output-generator names="bed_difference_year" class="org.dive4elements.river.exports.minfo.BedDifferenceYearGenerator"/>
+ <output-generator names="bed_difference_year_chartinfo" class="org.dive4elements.river.exports.minfo.BedDiffYearInfoGenerator"/>
+ <output-generator names="bed_difference_epoch" class="org.dive4elements.river.exports.minfo.BedDifferenceEpochGenerator"/>
+ <output-generator names="bed_difference_epoch_chartinfo" class="org.dive4elements.river.exports.minfo.BedDiffEpochInfoGenerator"/>
+ <output-generator names="bed_difference_height_year" class="org.dive4elements.river.exports.minfo.BedDiffHeightYearGenerator"/>
+ <output-generator names="bed_difference_height_year_chartinfo" class="org.dive4elements.river.exports.minfo.BedDiffHeightYearInfoGenerator"/>
+ <output-generator names="bedheight_difference_export" class="org.dive4elements.river.exports.minfo.BedDifferenceExporter"/>
+ <output-generator names="sq_relation_a" class="org.dive4elements.river.exports.sq.SQRelationGeneratorA"/>
+ <output-generator names="sq_relation_b" class="org.dive4elements.river.exports.sq.SQRelationGeneratorB"/>
+ <output-generator names="sq_relation_c" class="org.dive4elements.river.exports.sq.SQRelationGeneratorC"/>
+ <output-generator names="sq_relation_d" class="org.dive4elements.river.exports.sq.SQRelationGeneratorD"/>
+ <output-generator names="sq_relation_e" class="org.dive4elements.river.exports.sq.SQRelationGeneratorE"/>
+ <output-generator names="sq_relation_f" class="org.dive4elements.river.exports.sq.SQRelationGeneratorF"/>
+ <output-generator names="sq_relation_a_chartinfo" class="org.dive4elements.river.exports.sq.SQRelationInfoGenerator"/>
+ <output-generator names="sq_relation_b_chartinfo" class="org.dive4elements.river.exports.sq.SQRelationInfoGenerator"/>
+ <output-generator names="sq_relation_c_chartinfo" class="org.dive4elements.river.exports.sq.SQRelationInfoGenerator"/>
+ <output-generator names="sq_relation_d_chartinfo" class="org.dive4elements.river.exports.sq.SQRelationInfoGenerator"/>
+ <output-generator names="sq_relation_e_chartinfo" class="org.dive4elements.river.exports.sq.SQRelationInfoGenerator"/>
+ <output-generator names="sq_relation_f_chartinfo" class="org.dive4elements.river.exports.sq.SQRelationInfoGenerator"/>
+ <output-generator names="sq_relation_export" class="org.dive4elements.river.exports.sq.SQRelationExporter"/>
+ <output-generator names="sq_overview" class="org.dive4elements.river.exports.sq.SQOverviewGenerator"/>
+ <output-generator names="fix_parameters_export" class="org.dive4elements.river.exports.fixings.ParametersExporter"/>
+ <output-generator names="fix_deltawt_export" class="org.dive4elements.river.exports.fixings.DeltaWtExporter"/>
+ <output-generator names="fix_deltawt_curve" class="org.dive4elements.river.exports.fixings.FixDeltaWtGenerator"/>
+ <output-generator names="fix_deltawt_curve_chartinfo" class="org.dive4elements.river.exports.fixings.FixDeltaWtInfoGenerator"/>
+ <output-generator names="fix_longitudinal_section_curve" class="org.dive4elements.river.exports.fixings.FixLongitudinalSectionGenerator"/>
+ <output-generator names="fix_longitudinal_section_curve_chartinfo" class="org.dive4elements.river.exports.fixings.FixLongitudinalSectionInfoGenerator"/>
+ <output-generator names="fix_derivate_curve" class="org.dive4elements.river.exports.fixings.FixDerivedCurveGenerator"/>
+ <output-generator names="fix_derivate_curve_chartinfo" class="org.dive4elements.river.exports.fixings.FixDerivedCurveInfoGenerator"/>
+ <output-generator names="fix_waterlevel_export" class="org.dive4elements.river.exports.WaterlevelExporter"/>
+ <output-generator names="fix_vollmer_wq_curve" class="org.dive4elements.river.exports.fixings.FixWQCurveGenerator"/>
+ <output-generator names="fix_vollmer_wq_curve_chartinfo" class="org.dive4elements.river.exports.fixings.FixWQCurveInfoGenerator"/>
+ <output-generator names="sedimentload_ls" class="org.dive4elements.river.exports.minfo.SedimentLoadLSGenerator"/>
+ <output-generator names="sedimentload_ls_export" class="org.dive4elements.river.exports.minfo.SedimentLoadExporter"/>
+ <output-generator names="sedimentload_ls_chartinfo" class="org.dive4elements.river.exports.minfo.SedimentLoadLSInfoGenerator"/>
+ <!-- Error report generators. -->
+ <output-generator names="discharge_longitudinal_section_report" class="org.dive4elements.river.exports.ReportGenerator"/>
+ <output-generator names="waterlevel_report" class="org.dive4elements.river.exports.ReportGenerator"/>
+ <output-generator names="computed_dischargecurve_report" class="org.dive4elements.river.exports.ReportGenerator"/>
+ <output-generator names="durationcurve_report" class="org.dive4elements.river.exports.ReportGenerator"/>
+ <output-generator names="wsplgen_report" class="org.dive4elements.river.exports.ReportGenerator"/>
+ <output-generator names="historical_discharge_report" class="org.dive4elements.river.exports.ReportGenerator"/>
+ <output-generator names="reference_curve_report" class="org.dive4elements.river.exports.ReportGenerator"/>
+ <output-generator names="fix_report" class="org.dive4elements.river.exports.ReportGenerator"/>
+ <output-generator names="extreme_curve_report" class="org.dive4elements.river.exports.ReportGenerator"/>
+ <output-generator names="sedimentload_ls_report" class="org.dive4elements.river.exports.ReportGenerator"/>
+ <!-- AT exporter. -->
+ <output-generator names="computed_dischargecurve_at_export" class="org.dive4elements.river.exports.ATExporter"/>
+ <output-generator names="gauge_discharge_curve_at_export" class="org.dive4elements.river.exports.ATExporter"/>
+ <output-generator names="fix_wq_curve_at_export" class="org.dive4elements.river.exports.fixings.FixATExport"/>
+ <output-generator names="wsplgen" class="org.dive4elements.river.exports.ShapeExporter"/>
+</output-generators>
+
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/pom.xml
--- a/artifacts/pom.xml Mon Sep 23 11:37:13 2013 +0200
+++ b/artifacts/pom.xml Tue Sep 24 12:29:44 2013 +0200
@@ -75,9 +75,9 @@
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
- <groupId>jfree</groupId>
+ <groupId>org.jfree</groupId>
<artifactId>jfreechart</artifactId>
- <version>1.0.13</version>
+ <version>1.0.15</version>
</dependency>
<dependency>
<groupId>org.apache.xmlgraphics</groupId>
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/artifacts/context/RiverContext.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/context/RiverContext.java Mon Sep 23 11:37:13 2013 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/context/RiverContext.java Tue Sep 24 12:29:44 2013 +0200
@@ -17,6 +17,7 @@
import org.dive4elements.artifactdatabase.DefaultArtifactContext;
import org.dive4elements.artifacts.CallContext;
import org.dive4elements.river.exports.OutGenerator;
+import org.dive4elements.river.utils.Pair;
/**
@@ -99,17 +100,26 @@
? (RiverContext) context
: (RiverContext) context.globalContext();
- Map<String, Class> generators = (Map<String, Class>)
- flysContext.get(RiverContext.OUTGENERATORS_KEY);
+ Map<String, Pair<Class<OutGenerator>, Object>> generators =
+ (Map<String, Pair<Class<OutGenerator>, Object>>)flysContext
+ .get(RiverContext.OUTGENERATORS_KEY);
if (generators == null) {
return null;
}
- Class clazz = generators.get(name);
+ Pair<Class<OutGenerator>, Object> pair = generators.get(name);
+
+ if (pair == null) {
+ logger.warn("No generator class found for " + name);
+ return null;
+ }
try {
- return clazz != null ? (OutGenerator) clazz.newInstance() : null;
+ Class<OutGenerator> clazz = pair.getA();
+ OutGenerator generator = clazz.newInstance();
+ generator.setup(pair.getB());
+ return generator;
}
catch (InstantiationException ie) {
logger.error(ie, ie);
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/artifacts/context/RiverContextFactory.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/context/RiverContextFactory.java Mon Sep 23 11:37:13 2013 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/context/RiverContextFactory.java Tue Sep 24 12:29:44 2013 +0200
@@ -8,24 +8,8 @@
package org.dive4elements.river.artifacts.context;
-import org.dive4elements.artifactdatabase.state.State;
-import org.dive4elements.artifactdatabase.state.StateEngine;
-import org.dive4elements.artifactdatabase.transition.Transition;
-import org.dive4elements.artifactdatabase.transition.TransitionEngine;
-import org.dive4elements.artifacts.ArtifactContextFactory;
-import org.dive4elements.artifacts.GlobalContext;
-import org.dive4elements.artifacts.common.utils.Config;
-import org.dive4elements.artifacts.common.utils.XMLUtils;
-import org.dive4elements.river.artifacts.model.Module;
-import org.dive4elements.river.artifacts.model.ZoomScale;
-import org.dive4elements.river.artifacts.states.StateFactory;
-import org.dive4elements.river.artifacts.transitions.TransitionFactory;
-import org.dive4elements.river.themes.Theme;
-import org.dive4elements.river.themes.ThemeFactory;
-import org.dive4elements.river.themes.ThemeGroup;
-import org.dive4elements.river.themes.ThemeMapping;
+import java.io.File;
-import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -34,12 +18,41 @@
import javax.xml.xpath.XPathConstants;
import org.apache.log4j.Logger;
+
+import org.dive4elements.artifactdatabase.state.State;
+import org.dive4elements.artifactdatabase.state.StateEngine;
+
+import org.dive4elements.artifactdatabase.transition.Transition;
+import org.dive4elements.artifactdatabase.transition.TransitionEngine;
+
+import org.dive4elements.artifacts.ArtifactContextFactory;
+import org.dive4elements.artifacts.GlobalContext;
+
+import org.dive4elements.artifacts.common.utils.Config;
+import org.dive4elements.artifacts.common.utils.ElementConverter;
+import org.dive4elements.artifacts.common.utils.XMLUtils;
+
+import org.dive4elements.river.artifacts.model.Module;
+import org.dive4elements.river.artifacts.model.ZoomScale;
+
+import org.dive4elements.river.artifacts.states.StateFactory;
+
+import org.dive4elements.river.artifacts.transitions.TransitionFactory;
+
+import org.dive4elements.river.exports.OutGenerator;
+
+import org.dive4elements.river.themes.Theme;
+import org.dive4elements.river.themes.ThemeFactory;
+import org.dive4elements.river.themes.ThemeGroup;
+import org.dive4elements.river.themes.ThemeMapping;
+
+import org.dive4elements.river.utils.Pair;
+
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
-
/**
* The ArtifactContextFactory is used to initialize basic components and put
* them into the global context of the application.
@@ -307,7 +320,6 @@
* @param context the RiverContext.
*/
protected void configureOutGenerators(Document config, RiverContext context){
- Map<String, Class<?>> generators = new HashMap<String, Class<?>>();
NodeList outGenerators = (NodeList) XMLUtils.xpath(
config,
@@ -323,28 +335,60 @@
logger.info("Found " + num + " configured output generators.");
+ Map<String, Pair<Class<OutGenerator>, Object>> generators =
+ new HashMap<String, Pair<Class<OutGenerator>, Object>>();
+
int idx = 0;
for (int i = 0; i < num; i++) {
- Node item = outGenerators.item(i);
+ Element item = (Element)outGenerators.item(i);
- String name = (String) XMLUtils.xpath(
- item, "@name", XPathConstants.STRING);
+ String names = item.getAttribute("names").trim();
+ String clazz = item.getAttribute("class").trim();
+ String converter = item.getAttribute("converter").trim();
- String clazz = (String) XMLUtils.xpath(
- item, "text()", XPathConstants.STRING);
-
- if (name == null || clazz == null) {
+ if (names.isEmpty() || clazz.isEmpty()) {
continue;
}
+ Class<OutGenerator> generatorClass = null;
+
try {
- generators.put(name, Class.forName(clazz));
-
- idx++;
+ generatorClass = (Class<OutGenerator>)Class.forName(clazz);
}
catch (ClassNotFoundException cnfe) {
- logger.warn(cnfe, cnfe);
+ logger.error(cnfe, cnfe);
+ continue;
+ }
+
+ Object cfg = null;
+
+ if (!converter.isEmpty()) {
+ try {
+ ElementConverter ec =
+ (ElementConverter)Class.forName(converter)
+ .newInstance();
+ cfg = ec.convert(item);
+ }
+ catch (ClassNotFoundException cnfe) {
+ logger.error(cnfe, cnfe);
+ }
+ catch (InstantiationException ie) {
+ logger.error(ie);
+ }
+ catch (IllegalAccessException iae) {
+ logger.error(iae);
+ }
+ }
+
+ Pair<Class<OutGenerator>, Object> pair =
+ new Pair<Class<OutGenerator>, Object>(generatorClass, cfg);
+
+ for (String key: names.split("[\\s,]")) {
+ if (!(key = key.trim()).isEmpty()) {
+ generators.put(key, pair);
+ idx++;
+ }
}
}
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/artifacts/model/W.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/model/W.java Mon Sep 23 11:37:13 2013 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/model/W.java Tue Sep 24 12:29:44 2013 +0200
@@ -109,7 +109,7 @@
}
public boolean guessWaterIncreasing(float factor) {
- return DataUtil.guessWaterIncreasing(ws, factor);
+ return DataUtil.guessDataIncreasing(ws, factor);
}
public int [] longestIncreasingWRangeIndices() {
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/artifacts/model/WKms.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/model/WKms.java Mon Sep 23 11:37:13 2013 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/model/WKms.java Tue Sep 24 12:29:44 2013 +0200
@@ -24,5 +24,10 @@
TDoubleArrayList allWs();
boolean guessWaterIncreasing();
+
+ /** Guess if the Water flows from right to left.
+ *
+ * @return True if km's and ws's both grow in the same direction */
+ boolean guessRTLData();
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/artifacts/model/WKmsImpl.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/model/WKmsImpl.java Mon Sep 23 11:37:13 2013 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/model/WKmsImpl.java Tue Sep 24 12:29:44 2013 +0200
@@ -82,11 +82,16 @@
@Override
public boolean guessWaterIncreasing() {
- return guessWaterIncreasing(0.05f);
+ return guessDataIncreasing(0.05f);
}
- protected boolean guessWaterIncreasing(float factor) {
- return DataUtil.guessWaterIncreasing(ws, factor);
+ protected boolean guessDataIncreasing(float factor) {
+ return DataUtil.guessDataIncreasing(ws, factor);
+ }
+
+ @Override
+ public boolean guessRTLData() {
+ return DataUtil.guessSameDirectionData(ws, allKms());
}
@Override
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/artifacts/model/WQKms.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/model/WQKms.java Mon Sep 23 11:37:13 2013 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/model/WQKms.java Tue Sep 24 12:29:44 2013 +0200
@@ -8,6 +8,7 @@
package org.dive4elements.river.artifacts.model;
+import org.dive4elements.river.utils.DataUtil;
import org.dive4elements.river.utils.DoubleUtil;
import gnu.trove.TDoubleArrayList;
@@ -153,5 +154,10 @@
/* Behold the first km might be larger then the last! */
return new double[] {getKm(0), getKm(size()-1)};
}
+
+ @Override
+ public boolean guessRTLData() {
+ return DataUtil.guessSameDirectionData(ws, allKms());
+ }
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/artifacts/states/CalculationSelect.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/states/CalculationSelect.java Mon Sep 23 11:37:13 2013 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/states/CalculationSelect.java Tue Sep 24 12:29:44 2013 +0200
@@ -77,7 +77,7 @@
CALCULATION_DISCHARGE_CURVE,
CALCULATION_HISTORICAL_DISCHARGE_CURVE,
CALCULATION_DURATION_CURVE,
-// CALCULATION_DISCHARGE_LONGITUDINAL_CURVE,
+ CALCULATION_DISCHARGE_LONGITUDINAL_CURVE,
CALCULATION_W_DIFFERENCES,
CALCULATION_REFERENCE_CURVE //,
// CALCULATION_EXTREME
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/collections/D4EArtifactCollection.java
--- a/artifacts/src/main/java/org/dive4elements/river/collections/D4EArtifactCollection.java Mon Sep 23 11:37:13 2013 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/collections/D4EArtifactCollection.java Tue Sep 24 12:29:44 2013 +0200
@@ -330,7 +330,7 @@
// XXX NOTE: the outGen is not able to process its generate() operation,
// because it has no OutputStream set!
- outGen.init(XMLUtils.newDocument(), null, getContext());
+ outGen.init(out, XMLUtils.newDocument(), null, getContext());
prepareMasterArtifact(outGen);
try {
@@ -382,16 +382,12 @@
// If type contains 'chartinfo' use a generator that
// just allow access to width, height etc.
- OutGenerator generator = null;
- if (type != null
- && type.length() > 0
- && type.indexOf("chartinfo") > 0)
- {
- generator = RiverContext.getOutGenerator(context, type, subtype);
- }
- else {
- generator = RiverContext.getOutGenerator(context, name, subtype);
- }
+
+ String key = type != null && !type.isEmpty() && type.indexOf("chartinfo") > 0
+ ? type
+ : name;
+
+ OutGenerator generator = RiverContext.getOutGenerator(context, key, subtype);
if (generator == null) {
log.error("There is no generator specified for output: " + name);
@@ -417,7 +413,7 @@
}
}
- generator.init(format, out, context);
+ generator.init(key, format, out, context);
generator.setSettings(settings);
generator.setCollection(this);
prepareMasterArtifact(generator);
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/exports/ATExporter.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/ATExporter.java Mon Sep 23 11:37:13 2013 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/ATExporter.java Tue Sep 24 12:29:44 2013 +0200
@@ -44,7 +44,8 @@
protected WQ data;
protected CallContext context;
protected OutputStream out;
- protected D4EArtifact master;
+ protected D4EArtifact master;
+ protected String outName;
protected D4EArtifactCollection collection;
@@ -53,7 +54,13 @@
}
@Override
- public void init(Document request, OutputStream out, CallContext context) {
+ public void setup(Object config) {
+ logger.debug("ATExporter.setup");
+ }
+
+ @Override
+ public void init(String outName, Document request, OutputStream out, CallContext context) {
+ this.outName = outName;
this.context = context;
this.out = out;
}
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/exports/AbstractExporter.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/AbstractExporter.java Mon Sep 23 11:37:13 2013 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/AbstractExporter.java Tue Sep 24 12:29:44 2013 +0200
@@ -65,6 +65,9 @@
/** XPath that points to the desired export facet. */
public static final String XPATH_FACET = "/art:action/@art:type";
+ /** The out name to serve. */
+ protected String outName;
+
/** The document of the incoming out() request. */
protected Document request;
@@ -115,11 +118,21 @@
*/
protected abstract void addData(Object data);
+ public void setup(Object config) {
+ logger.debug("AbstractExporter.setup");
+ }
+
@Override
- public void init(Document request, OutputStream out, CallContext context) {
+ public void init(
+ String outName,
+ Document request,
+ OutputStream out,
+ CallContext context
+ ) {
logger.debug("AbstractExporter.init");
+ this.outName = outName;
this.request = request;
this.out = out;
this.context = context;
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/exports/ChartGenerator.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/ChartGenerator.java Mon Sep 23 11:37:13 2013 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/ChartGenerator.java Tue Sep 24 12:29:44 2013 +0200
@@ -30,6 +30,7 @@
import org.dive4elements.river.jfree.Style;
import org.dive4elements.river.jfree.StyledAreaSeriesCollection;
import org.dive4elements.river.jfree.StyledSeries;
+import org.dive4elements.river.jfree.AxisDataset;
import org.dive4elements.river.model.River;
import org.dive4elements.river.themes.LineStyle;
import org.dive4elements.river.themes.TextStyle;
@@ -136,6 +137,8 @@
/** List of annotations to insert in plot. */
protected List<RiverAnnotation> annotations = new ArrayList<RiverAnnotation>();
+ protected String outName;
+
/**
* A mini interface that allows to walk over the YAXIS enums defined in
* subclasses.
@@ -149,26 +152,6 @@
- public interface AxisDataset {
-
- void addDataset(XYDataset dataset);
-
- XYDataset[] getDatasets();
-
- boolean isEmpty();
-
- void setRange(Range range);
-
- Range getRange();
-
- boolean isArea(XYDataset dataset);
-
- void setPlotAxisIndex(int idx);
-
- int getPlotAxisIndex();
-
- } // end of AxisDataset interface
-
/**
@@ -178,6 +161,10 @@
datasets = new TreeMap<Integer, AxisDataset>();
}
+ @Override
+ public void setup(Object config) {
+ logger.debug("ChartGenerator.setup");
+ }
/**
* Adds annotations to list. The given annotation will be visible.
@@ -699,9 +686,10 @@
@Override
- public void init(Document request, OutputStream out, CallContext context) {
+ public void init(String outName, Document request, OutputStream out, CallContext context) {
logger.debug("ChartGenerator.init");
+ this.outName = outName;
this.request = request;
this.out = out;
this.context = context;
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/exports/ChartGenerator2.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/ChartGenerator2.java Tue Sep 24 12:29:44 2013 +0200
@@ -0,0 +1,1572 @@
+/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde
+ * Software engineering by Intevation GmbH
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+
+package org.dive4elements.river.exports;
+
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.Graphics2D;
+import java.awt.Paint;
+import java.awt.Stroke;
+import java.awt.TexturePaint;
+import java.awt.Transparency;
+
+import java.awt.geom.Rectangle2D;
+
+import java.awt.image.BufferedImage;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+import javax.xml.xpath.XPathConstants;
+
+import org.apache.log4j.Logger;
+
+import org.dive4elements.artifactdatabase.state.ArtifactAndFacet;
+import org.dive4elements.artifactdatabase.state.Settings;
+
+import org.dive4elements.artifacts.Artifact;
+import org.dive4elements.artifacts.ArtifactNamespaceContext;
+import org.dive4elements.artifacts.CallContext;
+import org.dive4elements.artifacts.CallMeta;
+import org.dive4elements.artifacts.PreferredLocale;
+
+import org.dive4elements.artifacts.common.utils.XMLUtils;
+
+import org.dive4elements.river.artifacts.D4EArtifact;
+
+import org.dive4elements.river.artifacts.access.RangeAccess;
+
+import org.dive4elements.river.artifacts.resources.Resources;
+
+import org.dive4elements.river.collections.D4EArtifactCollection;
+
+import org.dive4elements.river.java2d.NOPGraphics2D;
+
+import org.dive4elements.river.jfree.AxisDataset;
+import org.dive4elements.river.jfree.Bounds;
+import org.dive4elements.river.jfree.DoubleBounds;
+import org.dive4elements.river.jfree.EnhancedLineAndShapeRenderer;
+import org.dive4elements.river.jfree.RiverAnnotation;
+import org.dive4elements.river.jfree.StableXYDifferenceRenderer;
+import org.dive4elements.river.jfree.Style;
+import org.dive4elements.river.jfree.StyledAreaSeriesCollection;
+import org.dive4elements.river.jfree.StyledSeries;
+
+import org.dive4elements.river.model.River;
+
+import org.dive4elements.river.themes.ThemeDocument;
+
+import org.dive4elements.river.utils.Formatter;
+import org.dive4elements.river.utils.RiverUtils;
+
+import org.jfree.chart.ChartRenderingInfo;
+import org.jfree.chart.JFreeChart;
+import org.jfree.chart.LegendItem;
+import org.jfree.chart.LegendItemCollection;
+
+import org.jfree.chart.axis.NumberAxis;
+
+import org.jfree.chart.plot.XYPlot;
+
+import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
+
+import org.jfree.chart.title.TextTitle;
+
+import org.jfree.data.Range;
+
+import org.jfree.data.general.Series;
+
+import org.jfree.data.xy.XYDataset;
+
+import org.jfree.ui.RectangleInsets;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * Implementation of the OutGenerator interface for charts.
+ * It should provide some basic things that equal in all chart types.
+ *
+ */
+public abstract class ChartGenerator2 implements OutGenerator {
+
+ private static Logger logger = Logger.getLogger(ChartGenerator2.class);
+
+ public static final boolean USE_NOP_GRAPHICS =
+ Boolean.getBoolean("info.rendering.nop.graphics");
+
+
+ public static final int DEFAULT_CHART_WIDTH = 600;
+ public static final int DEFAULT_CHART_HEIGHT = 400;
+ public static final String DEFAULT_CHART_FORMAT = "png";
+ public static final Color DEFAULT_GRID_COLOR = Color.GRAY;
+ public static final float DEFAULT_GRID_LINE_WIDTH = 0.3f;
+ public static final int DEFAULT_FONT_SIZE = 12;
+ public static final String DEFAULT_FONT_NAME = "Tahoma";
+
+
+ public static final String XPATH_CHART_SIZE =
+ "/art:action/art:attributes/art:size";
+
+ public static final String XPATH_CHART_FORMAT =
+ "/art:action/art:attributes/art:format/@art:value";
+
+ public static final String XPATH_CHART_X_RANGE =
+ "/art:action/art:attributes/art:xrange";
+
+ public static final String XPATH_CHART_Y_RANGE =
+ "/art:action/art:attributes/art:yrange";
+
+
+ /** The document of the incoming out() request.*/
+ protected Document request;
+
+ /** The output stream where the data should be written to.*/
+ protected OutputStream out;
+
+ /** The CallContext object.*/
+ protected CallContext context;
+
+ protected D4EArtifactCollection collection;
+
+ /** The artifact that is used to decorate the chart with meta information.*/
+ protected Artifact master;
+
+ /** The settings that should be used during output creation.*/
+ protected Settings settings;
+
+ /** Map of datasets ("index"). */
+ protected SortedMap<Integer, AxisDataset> datasets;
+
+ /** List of annotations to insert in plot. */
+ protected List<RiverAnnotation> annotations = new ArrayList<RiverAnnotation>();
+
+ protected abstract List<AxisSection> buildYAxisSections();
+
+ protected String outName;
+
+ /**
+ * Default constructor that initializes internal data structures.
+ */
+ public ChartGenerator2() {
+ datasets = new TreeMap<Integer, AxisDataset>();
+ }
+
+ /**
+ * Adds annotations to list. The given annotation will be visible.
+ */
+ public void addAnnotations(RiverAnnotation annotation) {
+ annotations.add(annotation);
+ }
+
+ /**
+ * This method needs to be implemented by concrete subclasses to create new
+ * instances of JFreeChart.
+ *
+ * @return a new instance of a JFreeChart.
+ */
+ public abstract JFreeChart generateChart();
+
+
+ /** For every outable (i.e. facets), this function is
+ * called and handles the data accordingly. */
+ @Override
+ public abstract void doOut(
+ ArtifactAndFacet bundle,
+ ThemeDocument attr,
+ boolean visible);
+
+
+
+ protected abstract Series getSeriesOf(XYDataset dataset, int idx);
+
+ /**
+ * Returns the default title of a chart.
+ *
+ * @return the default title of a chart.
+ */
+ protected abstract String getDefaultChartTitle();
+
+ protected abstract String getDefaultYAxisLabel(String axisName);
+
+
+ /**
+ * Returns the default X-Axis label of a chart.
+ *
+ * @return the default X-Axis label of a chart.
+ */
+ protected abstract String getDefaultXAxisLabel();
+
+ /**
+ * This method is used to create new AxisDataset instances which may differ
+ * in concrete subclasses.
+ *
+ * @param idx The index of an axis.
+ */
+ protected abstract AxisDataset createAxisDataset(int idx);
+
+
+ /**
+ * Combines the ranges of the X axis at index <i>idx</i>.
+ *
+ * @param bounds A new Bounds.
+ * @param idx The index of the X axis that should be comined with
+ * <i>range</i>.
+ */
+ protected abstract void combineXBounds(Bounds bounds, int idx);
+
+
+ /**
+ * Combines the ranges of the Y axis at index <i>idx</i>.
+ *
+ * @param bounds A new Bounds.
+ * @param index The index of the Y axis that should be comined with.
+ * <i>range</i>.
+ */
+ protected abstract void combineYBounds(Bounds bounds, int index);
+
+
+ /**
+ * This method is used to determine the ranges for axes at a given index.
+ *
+ * @param index The index of the axes at the plot.
+ *
+ * @return a Range[] with [xrange, yrange];
+ */
+ public abstract Range[] getRangesForAxis(int index);
+
+ public abstract Bounds getXBounds(int axis);
+
+ protected abstract void setXBounds(int axis, Bounds bounds);
+
+ public abstract Bounds getYBounds(int axis);
+
+ protected abstract void setYBounds(int axis, Bounds bounds);
+
+
+ /**
+ * This method retrieves the chart subtitle by calling getChartSubtitle()
+ * and adds it as TextTitle to the chart.
+ * The default implementation of getChartSubtitle() returns the same
+ * as getDefaultChartSubtitle() which must be implemented by derived
+ * classes. If you want to add multiple subtitles to the chart override
+ * this method and add your subtitles manually.
+ *
+ * @param chart The JFreeChart chart object.
+ */
+ protected void addSubtitles(JFreeChart chart) {
+ String subtitle = getChartSubtitle();
+
+ if (subtitle != null && subtitle.length() > 0) {
+ chart.addSubtitle(new TextTitle(subtitle));
+ }
+ }
+
+ /**
+ * Generate chart.
+ */
+ @Override
+ public void generate() throws IOException {
+
+ logger.debug("ChartGenerator2.generate");
+
+ if (outName.indexOf("chartinfo") > 0) {
+ generateInfo();
+ }
+ else {
+ generateImage();
+ }
+ }
+
+
+ /** Generate only meta infos */
+ private void generateInfo() throws IOException {
+
+ logger.debug("ChartInfoGenerator2.generateInfo");
+
+ JFreeChart chart = generateChart();
+
+ int[] size = getSize();
+ if (size == null) {
+ size = getDefaultSize();
+ }
+
+ ChartRenderingInfo info = new ChartRenderingInfo();
+
+ long startTime = System.currentTimeMillis();
+
+ if (USE_NOP_GRAPHICS) {
+ BufferedImage image =
+ new BufferedImage(size[0], size[1], Transparency.BITMASK);
+
+ Graphics2D g2d = image.createGraphics();
+ Graphics2D nop = new NOPGraphics2D(g2d);
+
+ chart.draw(
+ nop,
+ new Rectangle2D.Double(0, 0, size[0], size[1]),
+ null,
+ info);
+
+ nop.dispose();
+ }
+ else {
+ chart.createBufferedImage(
+ size[0], size[1], Transparency.BITMASK, info);
+ }
+
+ long stopTime = System.currentTimeMillis();
+
+ if (logger.isDebugEnabled()) {
+ logger.debug("Rendering info took: " +
+ (stopTime-startTime) + "ms");
+ }
+
+
+ InfoGeneratorHelper2 helper = new InfoGeneratorHelper2(this);
+ Document doc = helper.createInfoDocument(chart, info);
+
+ XMLUtils.toStream(doc, out);
+ }
+
+ /** Generate the diagram as an image. */
+ private void generateImage() throws IOException {
+ logger.debug("ChartGenerator2.generateImage");
+
+ JFreeChart chart = generateChart();
+
+ String format = getFormat();
+ int[] size = getSize();
+
+ if (size == null) {
+ size = getExportDimension();
+ }
+
+ context.putContextValue("chart.width", size[0]);
+ context.putContextValue("chart.height", size[1]);
+
+ if (format.equals(ChartExportHelper.FORMAT_PNG)) {
+ context.putContextValue("chart.image.format", "png");
+
+ ChartExportHelper.exportImage(
+ out,
+ chart,
+ context);
+ }
+ else if (format.equals(ChartExportHelper.FORMAT_PDF)) {
+ preparePDFContext(context);
+
+ ChartExportHelper.exportPDF(
+ out,
+ chart,
+ context);
+ }
+ else if (format.equals(ChartExportHelper.FORMAT_SVG)) {
+ prepareSVGContext(context);
+
+ ChartExportHelper.exportSVG(
+ out,
+ chart,
+ context);
+ }
+ else if (format.equals(ChartExportHelper.FORMAT_CSV)) {
+ context.putContextValue("chart.image.format", "csv");
+
+ ChartExportHelper.exportCSV(
+ out,
+ chart,
+ context);
+ }
+ }
+
+
+ @Override
+ public void init(String outName, Document request, OutputStream out, CallContext context) {
+ logger.debug("ChartGenerator2.init");
+
+ this.outName = outName;
+ this.request = request;
+ this.out = out;
+ this.context = context;
+ }
+
+
+ /** Sets the master artifact. */
+ @Override
+ public void setMasterArtifact(Artifact master) {
+ this.master = master;
+ }
+
+
+ /**
+ * Gets the master artifact.
+ * @return the master artifact.
+ */
+ public Artifact getMaster() {
+ return master;
+ }
+
+
+ /** Sets the collection. */
+ @Override
+ public void setCollection(D4EArtifactCollection collection) {
+ this.collection = collection;
+ }
+
+
+ @Override
+ public void setSettings(Settings settings) {
+ this.settings = settings;
+ }
+
+
+ /**
+ * Returns an instance of <i>ChartSettings</i> with a chart specific section
+ * but with no axes settings.
+ *
+ * @return an instance of <i>ChartSettings</i>.
+ */
+ @Override
+ public Settings getSettings() {
+ if (this.settings != null) {
+ return this.settings;
+ }
+
+ ChartSettings settings = new ChartSettings();
+
+ ChartSection chartSection = buildChartSection();
+ LegendSection legendSection = buildLegendSection();
+ ExportSection exportSection = buildExportSection();
+
+ settings.setChartSection(chartSection);
+ settings.setLegendSection(legendSection);
+ settings.setExportSection(exportSection);
+
+ List<AxisSection> axisSections = buildAxisSections();
+ for (AxisSection axisSection: axisSections) {
+ settings.addAxisSection(axisSection);
+ }
+
+ return settings;
+ }
+
+
+ /**
+ * Creates a new <i>ChartSection</i>.
+ *
+ * @return a new <i>ChartSection</i>.
+ */
+ protected ChartSection buildChartSection() {
+ ChartSection chartSection = new ChartSection();
+ chartSection.setTitle(getChartTitle());
+ chartSection.setSubtitle(getChartSubtitle());
+ chartSection.setDisplayGrid(isGridVisible());
+ chartSection.setDisplayLogo(showLogo());
+ chartSection.setLogoVPlacement(logoVPlace());
+ chartSection.setLogoHPlacement(logoHPlace());
+ return chartSection;
+ }
+
+
+ /**
+ * Creates a new <i>LegendSection</i>.
+ *
+ * @return a new <i>LegendSection</i>.
+ */
+ protected LegendSection buildLegendSection() {
+ LegendSection legendSection = new LegendSection();
+ legendSection.setVisibility(isLegendVisible());
+ legendSection.setFontSize(getLegendFontSize());
+ legendSection.setAggregationThreshold(10);
+ return legendSection;
+ }
+
+
+ /**
+ * Creates a new <i>ExportSection</i> with default values <b>WIDTH=600</b>
+ * and <b>HEIGHT=400</b>.
+ *
+ * @return a new <i>ExportSection</i>.
+ */
+ protected ExportSection buildExportSection() {
+ ExportSection exportSection = new ExportSection();
+ exportSection.setWidth(600);
+ exportSection.setHeight(400);
+ return exportSection;
+ }
+
+
+ /**
+ * Creates a list of Sections that contains all axes of the chart (including
+ * X and Y axes).
+ *
+ * @return a list of Sections for each axis in this chart.
+ */
+ protected List<AxisSection> buildAxisSections() {
+ List<AxisSection> axisSections = new ArrayList<AxisSection>();
+
+ axisSections.addAll(buildXAxisSections());
+ axisSections.addAll(buildYAxisSections());
+
+ return axisSections;
+ }
+
+
+ /**
+ * Creates a new Section for chart's X axis.
+ *
+ * @return a List that contains a Section for the X axis.
+ */
+ protected List<AxisSection> buildXAxisSections() {
+ List<AxisSection> axisSections = new ArrayList<AxisSection>();
+
+ String identifier = "X";
+
+ AxisSection axisSection = new AxisSection();
+ axisSection.setIdentifier(identifier);
+ axisSection.setLabel(getXAxisLabel());
+ axisSection.setFontSize(14);
+ axisSection.setFixed(false);
+
+ // XXX We are able to find better default ranges that [0,0], but the Y
+ // axes currently have no better ranges set.
+ axisSection.setUpperRange(0d);
+ axisSection.setLowerRange(0d);
+
+ axisSections.add(axisSection);
+
+ return axisSections;
+ }
+
+
+ /**
+ * Returns the <i>settings</i> as <i>ChartSettings</i>.
+ *
+ * @return the <i>settings</i> as <i>ChartSettings</i> or null, if
+ * <i>settings</i> is not an instance of <i>ChartSettings</i>.
+ */
+ public ChartSettings getChartSettings() {
+ if (settings instanceof ChartSettings) {
+ return (ChartSettings) settings;
+ }
+
+ return null;
+ }
+
+
+ /**
+ * Returns the chart title provided by <i>settings</i>.
+ *
+ * @param settings A ChartSettings object.
+ *
+ * @return the title provided by <i>settings</i> or null if no
+ * <i>ChartSection</i> is provided by <i>settings</i>.
+ *
+ * @throws NullPointerException if <i>settings</i> is null.
+ */
+ public String getChartTitle(ChartSettings settings) {
+ ChartSection cs = settings.getChartSection();
+ return cs != null ? cs.getTitle() : null;
+ }
+
+
+ /**
+ * Returns the chart subtitle provided by <i>settings</i>.
+ *
+ * @param settings A ChartSettings object.
+ *
+ * @return the subtitle provided by <i>settings</i> or null if no
+ * <i>ChartSection</i> is provided by <i>settings</i>.
+ *
+ * @throws NullPointerException if <i>settings</i> is null.
+ */
+ public String getChartSubtitle(ChartSettings settings) {
+ ChartSection cs = settings.getChartSection();
+ return cs != null ? cs.getSubtitle() : null;
+ }
+
+
+ /**
+ * Returns a boolean object that determines if the chart grid should be
+ * visible or not. This information needs to be provided by <i>settings</i>,
+ * otherweise the default is true.
+ *
+ * @param settings A ChartSettings object.
+ *
+ * @return true, if the chart grid should be visible otherwise false.
+ *
+ * @throws NullPointerException if <i>settings</i> is null.
+ */
+ public boolean isGridVisible(ChartSettings settings) {
+ ChartSection cs = settings.getChartSection();
+ Boolean displayGrid = cs.getDisplayGrid();
+
+ return displayGrid != null ? displayGrid : true;
+ }
+
+
+ /**
+ * Returns a boolean object that determines if the chart legend should be
+ * visible or not. This information needs to be provided by <i>settings</i>,
+ * otherwise the default is true.
+ *
+ * @param settings A ChartSettings object.
+ *
+ * @return true, if the chart legend should be visible otherwise false.
+ *
+ * @throws NullPointerException if <i>settings</i> is null.
+ */
+ public boolean isLegendVisible(ChartSettings settings) {
+ LegendSection ls = settings.getLegendSection();
+ Boolean displayLegend = ls.getVisibility();
+
+ return displayLegend != null ? displayLegend : true;
+ }
+
+
+ /**
+ * Returns the legend font size specified in <i>settings</i> or null if no
+ * <i>LegendSection</i> is provided by <i>settings</i>.
+ *
+ * @param settings A ChartSettings object.
+ *
+ * @return the legend font size or null.
+ *
+ * @throws NullPointerException if <i>settings</i> is null.
+ */
+ public Integer getLegendFontSize(ChartSettings settings) {
+ LegendSection ls = settings.getLegendSection();
+ return ls != null ? ls.getFontSize() : null;
+ }
+
+
+ /**
+ * Returns the title of a chart. The return value depends on the existence
+ * of ChartSettings: if there are ChartSettings set, this method returns the
+ * chart title provided by those settings. Otherwise, this method returns
+ * getDefaultChartTitle().
+ *
+ * @return the title of a chart.
+ */
+ protected String getChartTitle() {
+ ChartSettings chartSettings = getChartSettings();
+
+ if (chartSettings != null) {
+ return getChartTitle(chartSettings);
+ }
+
+ return getDefaultChartTitle();
+ }
+
+
+ /**
+ * Returns the subtitle of a chart. The return value depends on the
+ * existence of ChartSettings: if there are ChartSettings set, this method
+ * returns the chart title provided by those settings. Otherwise, this
+ * method returns getDefaultChartSubtitle().
+ *
+ * @return the subtitle of a chart.
+ */
+ protected String getChartSubtitle() {
+ ChartSettings chartSettings = getChartSettings();
+
+ if (chartSettings != null) {
+ return getChartSubtitle(chartSettings);
+ }
+
+ return getDefaultChartSubtitle();
+ }
+
+
+ /**
+ * This method always returns null. Override it in subclasses that require
+ * subtitles.
+ *
+ * @return null.
+ */
+ protected String getDefaultChartSubtitle() {
+ // Override this method in subclasses
+ return null;
+ }
+
+
+ /**
+ * This method is used to determine, if the chart's legend is visible or
+ * not. If a <i>settings</i> instance is set, this instance determines the
+ * visibility otherwise, this method returns true as default if no
+ * <i>settings</i> is set.
+ *
+ * @return true, if the legend should be visible, otherwise false.
+ */
+ protected boolean isLegendVisible() {
+ ChartSettings chartSettings = getChartSettings();
+ if (chartSettings != null) {
+ return isLegendVisible(chartSettings);
+ }
+
+ return true;
+ }
+
+
+ /** Where to place the logo. */
+ protected String logoHPlace() {
+ ChartSettings chartSettings = getChartSettings();
+ if (chartSettings != null) {
+ ChartSection cs = chartSettings.getChartSection();
+ String place = cs.getLogoHPlacement();
+
+ return place;
+ }
+ return "center";
+ }
+
+
+ /** Where to place the logo. */
+ protected String logoVPlace() {
+ ChartSettings chartSettings = getChartSettings();
+ if (chartSettings != null) {
+ ChartSection cs = chartSettings.getChartSection();
+ String place = cs.getLogoVPlacement();
+
+ return place;
+ }
+ return "top";
+ }
+
+
+ /** Return the logo id from settings. */
+ protected String showLogo(ChartSettings chartSettings) {
+ if (chartSettings != null) {
+ ChartSection cs = chartSettings.getChartSection();
+ String logo = cs.getDisplayLogo();
+
+ return logo;
+ }
+ return "none";
+ }
+
+
+ /**
+ * This method is used to determine if a logo should be added to the plot.
+ *
+ * @return logo name (null if none).
+ */
+ protected String showLogo() {
+ ChartSettings chartSettings = getChartSettings();
+ return showLogo(chartSettings);
+ }
+
+
+ /**
+ * This method is used to determine the font size of the chart's legend. If
+ * a <i>settings</i> instance is set, this instance determines the font
+ * size, otherwise this method returns 12 as default if no <i>settings</i>
+ * is set or if it doesn't provide a legend font size.
+ *
+ * @return a legend font size.
+ */
+ protected int getLegendFontSize() {
+ Integer fontSize = null;
+
+ ChartSettings chartSettings = getChartSettings();
+ if (chartSettings != null) {
+ fontSize = getLegendFontSize(chartSettings);
+ }
+
+ return fontSize != null ? fontSize : DEFAULT_FONT_SIZE;
+ }
+
+
+ /**
+ * This method is used to determine if the resulting chart should display
+ * grid lines or not. <b>Note: this method always returns true!</b>
+ *
+ * @return true, if the chart should display grid lines, otherwise false.
+ */
+ protected boolean isGridVisible() {
+ return true;
+ }
+
+
+ /**
+ * Returns the X-Axis label of a chart.
+ *
+ * @return the X-Axis label of a chart.
+ */
+ protected String getXAxisLabel() {
+ ChartSettings chartSettings = getChartSettings();
+ if (chartSettings == null) {
+ return getDefaultXAxisLabel();
+ }
+
+ AxisSection as = chartSettings.getAxisSection("X");
+ if (as != null) {
+ String label = as.getLabel();
+
+ if (label != null) {
+ return label;
+ }
+ }
+
+ return getDefaultXAxisLabel();
+ }
+
+
+ /**
+ * This method returns the font size for the X axis. If the font size is
+ * specified in ChartSettings (if <i>chartSettings</i> is set), this size is
+ * returned. Otherwise the default font size 12 is returned.
+ *
+ * @return the font size for the x axis.
+ */
+ protected int getXAxisLabelFontSize() {
+ ChartSettings chartSettings = getChartSettings();
+ if (chartSettings == null) {
+ return DEFAULT_FONT_SIZE;
+ }
+
+ AxisSection as = chartSettings.getAxisSection("X");
+ Integer fontSize = as.getFontSize();
+
+ return fontSize != null ? fontSize : DEFAULT_FONT_SIZE;
+ }
+
+ /**
+ * Glue between axis names and index.
+ */
+ protected abstract String axisIndexToName(int index);
+
+ /**
+ * This method returns the font size for an Y axis. If the font size is
+ * specified in ChartSettings (if <i>chartSettings</i> is set), this size is
+ * returned. Otherwise the default font size 12 is returned.
+ *
+ * @return the font size for the x axis.
+ */
+ protected int getYAxisFontSize(int index) {
+ ChartSettings chartSettings = getChartSettings();
+ if (chartSettings == null) {
+ return DEFAULT_FONT_SIZE;
+ }
+
+ AxisSection as = chartSettings.getAxisSection(axisIndexToName(index));
+ if (as == null) {
+ return DEFAULT_FONT_SIZE;
+ }
+ Integer fontSize = as.getFontSize();
+
+ return fontSize != null ? fontSize : DEFAULT_FONT_SIZE;
+ }
+
+ /**
+ * This method returns the export dimension specified in ChartSettings as
+ * int array [width,height].
+ *
+ * @return an int array with [width,height].
+ */
+ protected int[] getExportDimension() {
+ ChartSettings chartSettings = getChartSettings();
+ if (chartSettings == null) {
+ return new int[] { 600, 400 };
+ }
+
+ ExportSection export = chartSettings.getExportSection();
+ Integer width = export.getWidth();
+ Integer height = export.getHeight();
+
+ if (width != null && height != null) {
+ return new int[] { width, height };
+ }
+
+ return new int[] { 600, 400 };
+ }
+
+ protected abstract String getYAxisLabel(String axisName);
+
+ /**
+ * This method searches for a specific axis in the <i>settings</i> if
+ * <i>settings</i> is set. If the axis was found, this method returns the
+ * specified axis range if the axis range is fixed. Otherwise, this method
+ * returns null.
+ *
+ * @param axisId The identifier of an axis.
+ *
+ * @return the specified axis range from <i>settings</i> if the axis is
+ * fixed, otherwise null.
+ */
+ public Range getRangeForAxisFromSettings(String axisId) {
+ ChartSettings chartSettings = getChartSettings();
+ if (chartSettings == null) {
+ return null;
+ }
+
+ AxisSection as = chartSettings.getAxisSection(axisId);
+
+ if (as == null) {
+ return null;
+ }
+
+ Boolean fixed = as.isFixed();
+
+ if (fixed != null && fixed) {
+ Double upper = as.getUpperRange();
+ Double lower = as.getLowerRange();
+
+ if (upper != null && lower != null) {
+ return lower < upper
+ ? new Range(lower, upper)
+ : new Range(upper, lower);
+ }
+ }
+
+ return null;
+ }
+
+
+ /**
+ * Adds a new AxisDataset which contains <i>dataset</i> at index <i>idx</i>.
+ *
+ * @param dataset An XYDataset.
+ * @param idx The axis index.
+ * @param visible Determines, if the dataset should be visible or not.
+ */
+ public void addAxisDataset(XYDataset dataset, int idx, boolean visible) {
+ if (dataset == null || idx < 0) {
+ return;
+ }
+
+ AxisDataset axisDataset = getAxisDataset(idx);
+
+ Bounds[] xyBounds = ChartHelper.getBounds(dataset);
+
+ if (xyBounds == null) {
+ logger.warn("Skip XYDataset for Axis (invalid ranges): " + idx);
+ return;
+ }
+
+ if (visible) {
+ if (logger.isDebugEnabled()) {
+ logger.debug("Add new AxisDataset at index: " + idx);
+ logger.debug("X extent: " + xyBounds[0]);
+ logger.debug("Y extent: " + xyBounds[1]);
+ }
+
+ axisDataset.addDataset(dataset);
+ }
+
+ combineXBounds(xyBounds[0], 0);
+ combineYBounds(xyBounds[1], idx);
+ }
+
+
+ /**
+ * This method grants access to the AxisDatasets stored in <i>datasets</i>.
+ * If no AxisDataset exists for index <i>idx</i>, a new AxisDataset is
+ * created using <i>createAxisDataset()</i>.
+ *
+ * @param idx The index of the desired AxisDataset.
+ *
+ * @return an existing or new AxisDataset.
+ */
+ public AxisDataset getAxisDataset(int idx) {
+ AxisDataset axisDataset = datasets.get(idx);
+
+ if (axisDataset == null) {
+ axisDataset = createAxisDataset(idx);
+ datasets.put(idx, axisDataset);
+ }
+
+ return axisDataset;
+ }
+
+
+ /**
+ * Adjust some Stroke/Grid parameters for <i>plot</i>. The chart
+ * <i>Settings</i> are applied in this method.
+ *
+ * @param plot The XYPlot which is adapted.
+ */
+ protected void adjustPlot(XYPlot plot) {
+ Stroke gridStroke = new BasicStroke(
+ DEFAULT_GRID_LINE_WIDTH,
+ BasicStroke.CAP_BUTT,
+ BasicStroke.JOIN_MITER,
+ 3.0f,
+ new float[] { 3.0f },
+ 0.0f);
+
+ ChartSettings cs = getChartSettings();
+ boolean isGridVisible = cs != null ? isGridVisible(cs) : true;
+
+ plot.setDomainGridlineStroke(gridStroke);
+ plot.setDomainGridlinePaint(DEFAULT_GRID_COLOR);
+ plot.setDomainGridlinesVisible(isGridVisible);
+
+ plot.setRangeGridlineStroke(gridStroke);
+ plot.setRangeGridlinePaint(DEFAULT_GRID_COLOR);
+ plot.setRangeGridlinesVisible(isGridVisible);
+
+ plot.setAxisOffset(new RectangleInsets(0d, 0d, 0d, 0d));
+ }
+
+
+ /**
+ * This helper mehtod is used to extract the current locale from instance
+ * vairable <i>context</i>.
+ *
+ * @return the current locale.
+ */
+ protected Locale getLocale() {
+ CallMeta meta = context.getMeta();
+ PreferredLocale[] prefs = meta.getLanguages();
+
+ int len = prefs != null ? prefs.length : 0;
+
+ Locale[] locales = new Locale[len];
+
+ for (int i = 0; i < len; i++) {
+ locales[i] = prefs[i].getLocale();
+ }
+
+ return meta.getPreferredLocale(locales);
+ }
+
+
+ /**
+ * Look up \param key in i18n dictionary.
+ * @param key key for which to find i18nd version.
+ * @param def default, returned if lookup failed.
+ * @return value found in i18n dictionary, \param def if no value found.
+ */
+ public String msg(String key, String def) {
+ return Resources.getMsg(context.getMeta(), key, def);
+ }
+
+ /**
+ * Look up \param key in i18n dictionary.
+ * @param key key for which to find i18nd version.
+ * @return value found in i18n dictionary, key itself if failed.
+ */
+ public String msg(String key) {
+ return Resources.getMsg(context.getMeta(), key, key);
+ }
+
+ public String msg(String key, String def, Object[] args) {
+ return Resources.getMsg(context.getMeta(), key, def, args);
+ }
+
+
+ protected String getRiverName() {
+ D4EArtifact flys = (D4EArtifact) master;
+
+ River river = RiverUtils.getRiver(flys);
+ return (river != null) ? river.getName() : "";
+ }
+
+
+ protected double[] getRange() {
+ D4EArtifact flys = (D4EArtifact) master;
+
+ RangeAccess rangeAccess = new RangeAccess(flys);
+ return rangeAccess.getKmRange();
+ }
+
+
+ /**
+ * Returns the size of a chart export as array which has been specified by
+ * the incoming request document.
+ *
+ * @return the size of a chart as [width, height] or null if no width or
+ * height are given in the request document.
+ */
+ protected int[] getSize() {
+ int[] size = new int[2];
+
+ Element sizeEl = (Element)XMLUtils.xpath(
+ request,
+ XPATH_CHART_SIZE,
+ XPathConstants.NODE,
+ ArtifactNamespaceContext.INSTANCE);
+
+ if (sizeEl != null) {
+ String uri = ArtifactNamespaceContext.NAMESPACE_URI;
+
+ String w = sizeEl.getAttributeNS(uri, "width");
+ String h = sizeEl.getAttributeNS(uri, "height");
+
+ if (w.length() > 0 && h.length() > 0) {
+ try {
+ size[0] = Integer.parseInt(w);
+ size[1] = Integer.parseInt(h);
+ }
+ catch (NumberFormatException nfe) {
+ logger.warn("Wrong values for chart width/height.");
+ }
+ }
+ }
+
+ return size[0] > 0 && size[1] > 0 ? size : null;
+ }
+
+
+ /**
+ * This method returns the format specified in the <i>request</i> document
+ * or <i>DEFAULT_CHART_FORMAT</i> if no format is specified in
+ * <i>request</i>.
+ *
+ * @return the format used to export this chart.
+ */
+ protected String getFormat() {
+ String format = (String) XMLUtils.xpath(
+ request,
+ XPATH_CHART_FORMAT,
+ XPathConstants.STRING,
+ ArtifactNamespaceContext.INSTANCE);
+
+ return format == null || format.length() == 0
+ ? DEFAULT_CHART_FORMAT
+ : format;
+ }
+
+
+ /**
+ * Returns the X-Axis range as String array from request document.
+ * If the (x|y)range elements are not found in request document, return
+ * null (i.e. not zoomed).
+ *
+ * @return a String array with [lower, upper], null if not in document.
+ */
+ protected String[] getDomainAxisRangeFromRequest() {
+ Element xrange = (Element)XMLUtils.xpath(
+ request,
+ XPATH_CHART_X_RANGE,
+ XPathConstants.NODE,
+ ArtifactNamespaceContext.INSTANCE);
+
+ if (xrange == null) {
+ return null;
+ }
+
+ String uri = ArtifactNamespaceContext.NAMESPACE_URI;
+
+ String lower = xrange.getAttributeNS(uri, "from");
+ String upper = xrange.getAttributeNS(uri, "to");
+
+ return new String[] { lower, upper };
+ }
+
+
+ /** Returns null if the (x|y)range-element was not found in request document.
+ * This usally means that the axis are not manually zoomed, i.e. showing
+ * full data extent. */
+ protected String[] getValueAxisRangeFromRequest() {
+ Element yrange = (Element)XMLUtils.xpath(
+ request,
+ XPATH_CHART_Y_RANGE,
+ XPathConstants.NODE,
+ ArtifactNamespaceContext.INSTANCE);
+
+ if (yrange == null) {
+ return null;
+ }
+
+
+ String uri = ArtifactNamespaceContext.NAMESPACE_URI;
+
+ String lower = yrange.getAttributeNS(uri, "from");
+ String upper = yrange.getAttributeNS(uri, "to");
+
+ return new String[] { lower, upper };
+ }
+
+
+ /**
+ * Returns the default size of a chart export as array.
+ *
+ * @return the default size of a chart as [width, height].
+ */
+ protected int[] getDefaultSize() {
+ return new int[] { DEFAULT_CHART_WIDTH, DEFAULT_CHART_HEIGHT };
+ }
+
+
+ /**
+ * Add datasets stored in instance variable <i>datasets</i> to plot.
+ * <i>datasets</i> actually stores instances of AxisDataset, so each of this
+ * datasets is mapped to a specific axis as well.
+ *
+ * @param plot plot to add datasets to.
+ */
+ protected void addDatasets(XYPlot plot) {
+ logger.debug("addDatasets()");
+
+ // AxisDatasets are sorted, but some might be empty.
+ // Thus, generate numbering on the fly.
+ int axisIndex = 0;
+ int datasetIndex = 0;
+
+ for (Map.Entry<Integer, AxisDataset> entry: datasets.entrySet()) {
+ if (!entry.getValue().isEmpty()) {
+ // Add axis and range information.
+ AxisDataset axisDataset = entry.getValue();
+ NumberAxis axis = createYAxis(entry.getKey());
+
+ plot.setRangeAxis(axisIndex, axis);
+
+ if (axis.getAutoRangeIncludesZero()) {
+ axisDataset.setRange(
+ Range.expandToInclude(axisDataset.getRange(), 0d));
+ }
+
+ setYBounds(axisIndex, expandPointRange(axisDataset.getRange()));
+
+ // Add contained datasets, mapping to axis.
+ for (XYDataset dataset: axisDataset.getDatasets()) {
+ plot.setDataset(datasetIndex, dataset);
+ plot.mapDatasetToRangeAxis(datasetIndex, axisIndex);
+
+ applyThemes(plot, dataset,
+ datasetIndex,
+ axisDataset.isArea(dataset));
+
+ datasetIndex++;
+ }
+
+ axisDataset.setPlotAxisIndex(axisIndex);
+ axisIndex++;
+ }
+ }
+ }
+
+
+ /**
+ * @param idx "index" of dataset/series (first dataset to be drawn has
+ * index 0), correlates with renderer index.
+ * @param isArea true if the series describes an area and shall be rendered
+ * as such.
+ */
+ protected void applyThemes(
+ XYPlot plot,
+ XYDataset series,
+ int idx,
+ boolean isArea
+ ) {
+ if (isArea) {
+ applyAreaTheme(plot, (StyledAreaSeriesCollection) series, idx);
+ }
+ else {
+ applyLineTheme(plot, series, idx);
+ }
+ }
+
+
+ /**
+ * This method applies the themes defined in the series itself. Therefore,
+ * <i>StyledXYSeries.applyTheme()</i> is called, which modifies the renderer
+ * for the series.
+ *
+ * @param plot The plot.
+ * @param dataset The XYDataset which needs to support Series objects.
+ * @param idx The index of the renderer / dataset.
+ */
+ protected void applyLineTheme(XYPlot plot, XYDataset dataset, int idx) {
+ logger.debug("Apply LineTheme for dataset at index: " + idx);
+
+ LegendItemCollection lic = new LegendItemCollection();
+ LegendItemCollection anno = plot.getFixedLegendItems();
+
+ Font legendFont = createLegendLabelFont();
+
+ XYLineAndShapeRenderer renderer = createRenderer(plot, idx);
+
+ for (int s = 0, num = dataset.getSeriesCount(); s < num; s++) {
+ Series series = getSeriesOf(dataset, s);
+
+ if (series instanceof StyledSeries) {
+ Style style = ((StyledSeries) series).getStyle();
+ style.applyTheme(renderer, s);
+ }
+
+ // special case: if there is just one single item, we need to enable
+ // points for this series, otherwise we would not see anything in
+ // the chart area.
+ if (series.getItemCount() == 1) {
+ renderer.setSeriesShapesVisible(s, true);
+ }
+
+ LegendItem legendItem = renderer.getLegendItem(idx, s);
+ if (legendItem.getLabel().endsWith(" ") ||
+ legendItem.getLabel().endsWith("interpol")) {
+ legendItem = null;
+ }
+
+ if (legendItem != null) {
+ legendItem.setLabelFont(legendFont);
+ lic.add(legendItem);
+ }
+ else {
+ logger.warn("Could not get LegentItem for renderer: "
+ + idx + ", series-idx " + s);
+ }
+ }
+
+ if (anno != null) {
+ lic.addAll(anno);
+ }
+
+ plot.setFixedLegendItems(lic);
+
+ plot.setRenderer(idx, renderer);
+ }
+
+
+ /**
+ * @param plot The plot.
+ * @param area A StyledAreaSeriesCollection object.
+ * @param idx The index of the dataset.
+ */
+ protected void applyAreaTheme(
+ XYPlot plot,
+ StyledAreaSeriesCollection area,
+ int idx
+ ) {
+ LegendItemCollection lic = new LegendItemCollection();
+ LegendItemCollection anno = plot.getFixedLegendItems();
+
+ Font legendFont = createLegendLabelFont();
+
+ logger.debug("Registering an 'area'renderer at idx: " + idx);
+
+ StableXYDifferenceRenderer dRenderer =
+ new StableXYDifferenceRenderer();
+
+ if (area.getMode() == StyledAreaSeriesCollection.FILL_MODE.UNDER) {
+ dRenderer.setPositivePaint(createTransparentPaint());
+ }
+
+ plot.setRenderer(idx, dRenderer);
+
+ area.applyTheme(dRenderer);
+
+ // i18n
+ dRenderer.setAreaLabelNumberFormat(Formatter.getFormatter(context.getMeta(), 2, 4));
+
+ dRenderer.setAreaLabelTemplate(Resources.getMsg(
+ context.getMeta(), "area.label.template", "Area=%sm2"));
+
+ LegendItem legendItem = dRenderer.getLegendItem(idx, 0);
+ if (legendItem != null) {
+ legendItem.setLabelFont(legendFont);
+ lic.add(legendItem);
+ }
+ else {
+ logger.warn("Could not get LegentItem for renderer: "
+ + idx + ", series-idx " + 0);
+ }
+
+ if (anno != null) {
+ lic.addAll(anno);
+ }
+
+ plot.setFixedLegendItems(lic);
+ }
+
+
+ /**
+ * Expands a given range if it collapses into one point.
+ *
+ * @param range Range to be expanded if upper == lower bound.
+ *
+ * @return Bounds of point plus 5 percent in each direction.
+ */
+ private Bounds expandPointRange(Range range) {
+ if (range == null) {
+ return null;
+ }
+ else if (range.getLowerBound() == range.getUpperBound()) {
+ Range expandedRange = ChartHelper.expandRange(range, 5d);
+ return new DoubleBounds(expandedRange.getLowerBound(), expandedRange.getUpperBound());
+ }
+
+ return new DoubleBounds(range.getLowerBound(), range.getUpperBound());
+ }
+
+
+ /**
+ * Creates a new instance of EnhancedLineAndShapeRenderer.
+ *
+ * @param plot The plot which is set for the new renderer.
+ * @param idx This value is not used in the current implementation.
+ *
+ * @return a new instance of EnhancedLineAndShapeRenderer.
+ */
+ protected XYLineAndShapeRenderer createRenderer(XYPlot plot, int idx) {
+ logger.debug("Create EnhancedLineAndShapeRenderer for idx: " + idx);
+
+ EnhancedLineAndShapeRenderer r =
+ new EnhancedLineAndShapeRenderer(true, false);
+
+ r.setPlot(plot);
+
+ return r;
+ }
+
+
+ /**
+ * Creates a new instance of <i>IdentifiableNumberAxis</i>.
+ *
+ * @param idx The index of the new axis.
+ * @param label The label of the new axis.
+ *
+ * @return an instance of IdentifiableNumberAxis.
+ */
+ protected NumberAxis createNumberAxis(int idx, String label) {
+ return new IdentifiableNumberAxis(axisIndexToName(idx), label);
+ }
+
+
+ /**
+ * Create Y (range) axis for given index.
+ * Shall be overriden by subclasses.
+ */
+ protected NumberAxis createYAxis(int index) {
+
+ Font labelFont = new Font(
+ DEFAULT_FONT_NAME,
+ Font.BOLD,
+ getYAxisFontSize(index));
+
+ String axisName = axisIndexToName(index);
+
+ IdentifiableNumberAxis axis = new IdentifiableNumberAxis(
+ axisName, getYAxisLabel(axisName));
+
+ axis.setAutoRangeIncludesZero(false);
+ axis.setLabelFont(labelFont);
+ axis.setTickLabelFont(labelFont);
+
+ return axis;
+ }
+
+
+ /**
+ * Creates a new LegendItem with <i>name</i> and font provided by
+ * <i>createLegendLabelFont()</i>.
+ *
+ * @param theme The theme of the chart line.
+ * @param name The displayed name of the item.
+ *
+ * @return a new LegendItem instance.
+ */
+ public LegendItem createLegendItem(ThemeDocument theme, String name) {
+ // OPTIMIZE Pass font, parsed Theme items.
+
+ Color color = theme.parseLineColorField();
+ if (color == null) {
+ color = Color.BLACK;
+ }
+
+ LegendItem legendItem = new LegendItem(name, color);
+
+ legendItem.setLabelFont(createLegendLabelFont());
+ return legendItem;
+ }
+
+
+ /**
+ * Creates Font (Family and size) to use when creating Legend Items. The
+ * font size depends in the return value of <i>getLegendFontSize()</i>.
+ *
+ * @return a new Font instance with <i>DEFAULT_FONT_NAME</i>.
+ */
+ protected Font createLegendLabelFont() {
+ return new Font(
+ DEFAULT_FONT_NAME,
+ Font.PLAIN,
+ getLegendFontSize()
+ );
+ }
+
+
+ /**
+ * Create new legend entries, dependent on settings.
+ * @param plot The plot for which to modify the legend.
+ */
+ public void aggregateLegendEntries(XYPlot plot) {
+ int AGGR_THRESHOLD = 0;
+
+ if (getChartSettings() == null) {
+ return;
+ }
+ Integer threshold = getChartSettings().getLegendSection()
+ .getAggregationThreshold();
+
+ AGGR_THRESHOLD = (threshold != null) ? threshold.intValue() : 0;
+
+ LegendProcessor.aggregateLegendEntries(plot, AGGR_THRESHOLD);
+ }
+
+
+ /**
+ * Returns a transparently textured paint.
+ *
+ * @return a transparently textured paint.
+ */
+ protected static Paint createTransparentPaint() {
+ // TODO why not use a transparent color?
+ BufferedImage texture = new BufferedImage(
+ 1, 1, BufferedImage.TYPE_4BYTE_ABGR);
+
+ return new TexturePaint(
+ texture, new Rectangle2D.Double(0d, 0d, 0d, 0d));
+ }
+
+
+ protected void preparePDFContext(CallContext context) {
+ int[] dimension = getExportDimension();
+
+ context.putContextValue("chart.width", dimension[0]);
+ context.putContextValue("chart.height", dimension[1]);
+ context.putContextValue("chart.marginLeft", 5f);
+ context.putContextValue("chart.marginRight", 5f);
+ context.putContextValue("chart.marginTop", 5f);
+ context.putContextValue("chart.marginBottom", 5f);
+ context.putContextValue(
+ "chart.page.format",
+ ChartExportHelper.DEFAULT_PAGE_SIZE);
+ }
+
+
+ protected void prepareSVGContext(CallContext context) {
+ int[] dimension = getExportDimension();
+
+ context.putContextValue("chart.width", dimension[0]);
+ context.putContextValue("chart.height", dimension[1]);
+ context.putContextValue(
+ "chart.encoding",
+ ChartExportHelper.DEFAULT_ENCODING);
+ }
+
+ /**
+ * Retuns the call context. May be null if init hasn't been called yet.
+ *
+ * @return the CallContext instance
+ */
+ public CallContext getCallContext() {
+ return context;
+ }
+}
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/exports/ChartInfoGenerator.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/ChartInfoGenerator.java Mon Sep 23 11:37:13 2013 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/ChartInfoGenerator.java Tue Sep 24 12:29:44 2013 +0200
@@ -69,6 +69,10 @@
this.generator = generator;
}
+ public void setup(Object config) {
+ logger.debug("ChartInfoGenerator.setup");
+ }
+
/**
* Dispatches the operation to the instantiated generator.
@@ -77,10 +81,10 @@
* @param out
* @param context
*/
- public void init(Document request, OutputStream out, CallContext context) {
+ public void init(String outName, Document request, OutputStream out, CallContext context) {
this.out = out;
- generator.init(request, out, context);
+ generator.init(outName, request, out, context);
}
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/exports/ComputedDischargeCurveExporter.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/ComputedDischargeCurveExporter.java Mon Sep 23 11:37:13 2013 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/ComputedDischargeCurveExporter.java Tue Sep 24 12:29:44 2013 +0200
@@ -19,8 +19,6 @@
import java.text.DateFormat;
import java.util.Locale;
-import org.w3c.dom.Document;
-
import org.apache.log4j.Logger;
import au.com.bytecode.opencsv.CSVWriter;
@@ -32,7 +30,6 @@
import org.dive4elements.artifacts.common.utils.Config;
-import org.dive4elements.artifacts.CallContext;
import org.dive4elements.artifacts.CallMeta;
import org.dive4elements.river.artifacts.D4EArtifact;
@@ -82,15 +79,10 @@
protected boolean isCalculated;
protected Date validSince;
- public void init(Document request, OutputStream out, CallContext context) {
- logger.debug("ComputedDischargeCurveExporter.init");
-
- super.init(request, out, context);
-
- this.data = new ArrayList<WQKms>();
+ public ComputedDischargeCurveExporter() {
+ data = new ArrayList<WQKms>();
}
-
@Override
protected void addData(Object d) {
if (d instanceof CalculationResult) {
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/exports/CrossSectionGenerator.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/CrossSectionGenerator.java Mon Sep 23 11:37:13 2013 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/CrossSectionGenerator.java Tue Sep 24 12:29:44 2013 +0200
@@ -70,7 +70,6 @@
/** Trivial Constructor. */
public CrossSectionGenerator() {
- super();
}
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/exports/DiagramAttributes.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/DiagramAttributes.java Tue Sep 24 12:29:44 2013 +0200
@@ -0,0 +1,374 @@
+/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde
+ * Software engineering by Intevation GmbH
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+
+package org.dive4elements.river.exports;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+import org.dive4elements.river.exports.process.Processor;
+
+import org.apache.log4j.Logger;
+
+import org.dive4elements.artifacts.CallContext;
+
+import org.dive4elements.river.artifacts.resources.Resources;
+import org.dive4elements.river.artifacts.D4EArtifact;
+
+import org.dive4elements.artifacts.common.utils.ElementConverter;
+
+public class DiagramAttributes
+implements ElementConverter
+{
+ private static Logger log = Logger.getLogger(DiagramAttributes.class);
+
+ public class Instance {
+
+ private List<Processor> processors;
+
+ public Instance() {
+ processors = createProcessors();
+ }
+
+ private List<Processor> createProcessors() {
+ List<Processor> processors =
+ new ArrayList<Processor>(axesProcessors.size());
+ for (AxisProcessor ap: axesProcessors) {
+ Processor pr = ap.createProcessor();
+ if (pr != null) {
+ processors.add(pr);
+ }
+ }
+ return processors;
+ }
+
+ public Processor getProcessorForAxisName(String axisName) {
+ for (Processor pr: processors) {
+ String aName = pr.getAxisName();
+ if (aName != null && axisName.equals(aName)) {
+ return pr;
+ }
+ }
+ return null;
+ }
+
+ public List<Processor> getProcessors() {
+ return processors;
+ }
+
+ public Title getTitle() {
+ return DiagramAttributes.this.getTitle();
+ }
+
+ public Title getSubtitle() {
+ return DiagramAttributes.this.getSubtitle();
+ }
+
+ public Title getDomainAxisTitle() {
+ return DiagramAttributes.this.getDomainAxisTitle();
+ }
+
+ public int getAxisIndex(String axisName) {
+ return DiagramAttributes.this.getAxisIndex(axisName);
+ }
+
+ public String getAxisName(int index) {
+ return DiagramAttributes.this.getAxisName(index);
+ }
+
+ public List<AxisAttributes> getAxesAttributes() {
+ return DiagramAttributes.this.getAxesAttributes();
+ }
+ } // class Instance
+
+ public static class AxisAttributes {
+ private String name;
+ private boolean isLeftAlign;
+ private boolean forceAlign;
+ private boolean includeZero;
+
+ public AxisAttributes() {
+ }
+
+ public AxisAttributes(
+ String name,
+ boolean isLeftAlign,
+ boolean forceAlign,
+ boolean includeZero
+ ) {
+ this.name = name;
+ this.isLeftAlign = isLeftAlign;
+ this.forceAlign = forceAlign;
+ this.includeZero = includeZero;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public boolean isLeftAlign() {
+ return isLeftAlign;
+ }
+
+ public boolean forceAlign() {
+ return forceAlign;
+ }
+
+ public boolean includeZero() {
+ return includeZero;
+ }
+ } // class AxisAttributes
+
+ public static class AxisProcessor {
+
+ private Class<Processor> processorClass;
+ private String axisName;
+
+ public AxisProcessor(Class<Processor> processorClass, String axisName) {
+ this.processorClass = processorClass;
+ this.axisName = axisName;
+ }
+
+ public Processor createProcessor() {
+ try {
+ Processor pr = processorClass.newInstance();
+ pr.setAxisName(axisName);
+ return pr;
+ }
+ catch (InstantiationException ie) {
+ log.error(ie, ie);
+ }
+ catch (IllegalAccessException iae) {
+ log.error(iae, iae);
+ }
+ return null;
+ }
+
+ } // class AxisProcessor
+
+ public static class Argument {
+ private String expression;
+ private String type;
+
+ public Argument() {
+ }
+
+ public Argument(String expression, String type) {
+ this.expression = expression;
+ this.type = type;
+ }
+
+ public Object evaluate(D4EArtifact artifact, CallContext context) {
+ if (expression.startsWith("artifact.")) {
+ String value = artifact.getDataAsString(
+ expression.substring("artifact.".length()));
+ return convert(value);
+ }
+ if (expression.startsWith("context.")) {
+ return context.getContextValue(
+ expression.substring("context.".length()));
+ }
+ return expression;
+ }
+
+ private Object convert(String value) {
+ if (value == null || type == null) {
+ return value;
+ }
+ if ("double".equals(type)) {
+ return Double.valueOf(value);
+ }
+ if ("int".equals(type)) {
+ return Integer.valueOf(value);
+ }
+ // TODO: more types
+ return value;
+ }
+ } // class Argument
+
+ public static class Title {
+
+ private String key;
+ private String def;
+ private List<Argument> arguments;
+
+ public Title() {
+ arguments = new ArrayList<Argument>(5);
+ }
+
+ public Title(String key) {
+ this(key, key);
+ }
+
+ public Title(String key, String def) {
+ this();
+ this.key = key;
+ this.def = def;
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public void addArgument(Argument argument) {
+ arguments.add(argument);
+ }
+
+ public String evaluate(D4EArtifact artifact, CallContext context) {
+ if (key == null || key.isEmpty()) {
+ return def;
+ }
+ Object [] args = new Object[arguments.size()];
+ for (int i = 0; i < args.length; ++i) {
+ args[i] = arguments.get(i).evaluate(artifact, context);
+ }
+ return Resources.getMsg(context.getMeta(), key, def, args);
+ }
+ } // class Title
+
+ private List<AxisAttributes> axesAttrs;
+ private List<AxisProcessor> axesProcessors;
+
+ private Title title;
+ private Title subtitle;
+ private Title domainAxisTitle;
+
+ public DiagramAttributes() {
+ axesAttrs = new ArrayList<AxisAttributes>(5);
+ axesProcessors = new ArrayList<AxisProcessor>(5);
+ }
+
+ @Override
+ public Object convert(Element config) {
+ parseAxis(config);
+ parseProcessors(config);
+ parseTitle(config);
+ parseSubtitle(config);
+ parseDomainAxisTitle(config);
+ return this;
+ }
+
+ public List<AxisAttributes> getAxesAttributes() {
+ return axesAttrs;
+ }
+
+ private void parseAxis(Element config) {
+ NodeList axisNodes = config.getElementsByTagName("axis");
+
+ for (int i = 0, N = axisNodes.getLength(); i < N; ++i) {
+ Element axisElement = (Element)axisNodes.item(i);
+ String name = axisElement.getAttribute("name").trim();
+ String align = axisElement.getAttribute("align").trim();
+ String includeZero =
+ axisElement.getAttribute("include-zero").trim();
+ if (name.isEmpty()) {
+ continue;
+ }
+ boolean isleftAlign = false;
+ boolean forceAlign = false;
+ for (String part: align.split("[\\s,]")) {
+ part = part.trim();
+ if ("left" .equals(part)) isleftAlign = true;
+ else if ("right".equals(part)) isleftAlign = false;
+ else if ("force".equals(part)) forceAlign = true;
+ }
+
+ axesAttrs.add(new AxisAttributes(
+ name, isleftAlign, forceAlign,
+ includeZero.equals("true")));
+ }
+ }
+
+ public List<AxisProcessor> getAxesProcessors() {
+ return axesProcessors;
+ }
+
+ public Title getTitle() {
+ return title;
+ }
+
+ public Title getSubtitle() {
+ return subtitle;
+ }
+
+ public Title getDomainAxisTitle() {
+ return domainAxisTitle;
+ }
+
+ private void parseProcessors(Element config) {
+ NodeList processorNodes = config.getElementsByTagName("processor");
+
+ for (int i = 0, N = processorNodes.getLength(); i < N; ++i) {
+ Element processorElement = (Element)processorNodes.item(i);
+ String className = processorElement.getAttribute("class").trim();
+ String axisName = processorElement.getAttribute("axis").trim();
+ if (className.isEmpty() || axisName.isEmpty()) {
+ continue;
+ }
+
+ try {
+ Class<Processor> processorClass =
+ (Class<Processor>)Class.forName(className);
+ axesProcessors.add(new AxisProcessor(processorClass, axisName));
+ }
+ catch (ClassNotFoundException cnfe) {
+ log.error(cnfe, cnfe);
+ }
+ }
+ }
+
+ private void parseTitle(Element config) {
+ title = extractTitle(config, "title");
+ }
+
+ private void parseSubtitle(Element config) {
+ subtitle = extractTitle(config, "subtitle");
+ }
+
+ private void parseDomainAxisTitle(Element config) {
+ domainAxisTitle = extractTitle(config, "domain-axis");
+ }
+
+ private static Title extractTitle(Element config, String tagName) {
+ NodeList titleNodes = config.getElementsByTagName(tagName);
+ if (titleNodes.getLength() < 1) {
+ return null;
+ }
+ Element titleElement = (Element)titleNodes.item(0);
+ String key = titleElement.getAttribute("key");
+ String def = titleElement.getAttribute("default");
+ Title title = new Title(key, def);
+ NodeList argumentNodes = titleElement.getElementsByTagName("arg");
+ for (int i = 0, N = argumentNodes.getLength(); i < N; ++i) {
+ Element argumentElement = (Element)argumentNodes.item(i);
+ String expression = argumentElement.getAttribute("expr");
+ String type = argumentElement.getAttribute("type");
+ title.addArgument(new Argument(expression, type));
+ }
+ return title;
+ }
+
+ public int getAxisIndex(String axisName) {
+ for (int i = axesAttrs.size()-1; i >= 0; --i) {
+ if (axesAttrs.get(i).getName().equals(axisName)) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ public String getAxisName(int index) {
+ return index < 0 || index >= axesAttrs.size()
+ ? "" // null?
+ : axesAttrs.get(index).getName();
+ }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/exports/DiagramGenerator.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/DiagramGenerator.java Tue Sep 24 12:29:44 2013 +0200
@@ -0,0 +1,1119 @@
+/* Copyright (C) 2013 by Bundesanstalt für Gewässerkunde
+ * Software engineering by Intevation GmbH
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+
+package org.dive4elements.river.exports;
+
+import java.awt.Color;
+import java.awt.Font;
+
+import java.text.NumberFormat;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.swing.ImageIcon;
+
+import org.apache.log4j.Logger;
+
+import org.dive4elements.artifactdatabase.state.ArtifactAndFacet;
+import org.dive4elements.artifactdatabase.state.Facet;
+
+import org.dive4elements.river.artifacts.D4EArtifact;
+
+import org.dive4elements.river.exports.process.Processor;
+
+import org.dive4elements.river.jfree.AnnotationHelper;
+import org.dive4elements.river.jfree.AxisDataset;
+import org.dive4elements.river.jfree.Bounds;
+import org.dive4elements.river.jfree.DoubleBounds;
+import org.dive4elements.river.jfree.StyledAreaSeriesCollection;
+
+import org.dive4elements.river.themes.ThemeDocument;
+
+import org.jfree.chart.ChartFactory;
+import org.jfree.chart.JFreeChart;
+import org.jfree.chart.LegendItem;
+
+import org.jfree.chart.annotations.XYAnnotation;
+import org.jfree.chart.annotations.XYImageAnnotation;
+
+import org.jfree.chart.axis.LogarithmicAxis;
+import org.jfree.chart.axis.NumberAxis;
+import org.jfree.chart.axis.ValueAxis;
+
+import org.jfree.chart.plot.Marker;
+import org.jfree.chart.plot.PlotOrientation;
+import org.jfree.chart.plot.XYPlot;
+
+import org.jfree.data.Range;
+
+import org.jfree.data.general.Series;
+
+import org.jfree.data.xy.XYDataset;
+import org.jfree.data.xy.XYSeries;
+import org.jfree.data.xy.XYSeriesCollection;
+
+
+/**
+ * The main diagram creation class.
+ *
+ * This class is the glue between output processors and facets.
+ * The generator creates one diagram and calls the appropiate
+ * processors for the state and
+ *
+ * With respect to datasets, ranges and axis, there are following requirements:
+ * <ul>
+ * <li> First in, first drawn: "Early" datasets should be of lower Z-Oder
+ * than later ones (only works per-axis). </li>
+ * <li> Visible axis should initially show the range of all datasets that
+ * show data for this axis (even invisible ones). Motivation: Once
+ * a dataset (theme) has been activated, it should be on screen. </li>
+ * <li> There should always be a Y-Axis on the "left". </li>
+ * </ul>
+ */
+public class DiagramGenerator extends ChartGenerator2 {
+
+ public static final int AXIS_SPACE = 5;
+
+ /** The logger that is used in this generator. */
+ private static Logger logger = Logger.getLogger(DiagramGenerator.class);
+
+ protected List<Marker> domainMarkers = new ArrayList<Marker>();
+
+ protected List<Marker> valueMarkers = new ArrayList<Marker>();
+
+ /** The max X range to include all X values of all series for each axis. */
+ protected Map<Integer, Bounds> xBounds;
+
+ /** The max Y range to include all Y values of all series for each axis. */
+ protected Map<Integer, Bounds> yBounds;
+
+ /** Whether or not the plot is inverted (left-right). */
+ private boolean inverted;
+
+ protected DiagramAttributes.Instance diagramAttributes;
+
+ public DiagramGenerator() {
+ super();
+
+ xBounds = new HashMap<Integer, Bounds>();
+ yBounds = new HashMap<Integer, Bounds>();
+ }
+
+ @Override
+ public void setup(Object config) {
+
+ if (!(config instanceof DiagramAttributes)) {
+ logger.error("invalid config type");
+ return;
+ }
+ DiagramAttributes da = (DiagramAttributes)config;
+ diagramAttributes = da.new Instance();
+ }
+
+ /**
+ * Generate the chart anew (including localized axis and all).
+ */
+ @Override
+ public JFreeChart generateChart() {
+ logger.debug("DiagramGenerator.generateChart");
+
+ JFreeChart chart = ChartFactory.createXYLineChart(
+ getChartTitle(),
+ "",
+ "",
+ null,
+ PlotOrientation.VERTICAL,
+ isLegendVisible(),
+ false,
+ false);
+
+ XYPlot plot = (XYPlot) chart.getPlot();
+ ValueAxis axis = createXAxis(getXAxisLabel());
+ plot.setDomainAxis(axis);
+
+ chart.setBackgroundPaint(Color.WHITE);
+ plot.setBackgroundPaint(Color.WHITE);
+ addSubtitles(chart);
+ adjustPlot(plot);
+
+ //debugAxis(plot);
+
+ addDatasets(plot);
+
+ //debugDatasets(plot);
+
+ addMarkers(plot);
+
+ recoverEmptyPlot(plot);
+ preparePointRanges(plot);
+
+ //debugAxis(plot);
+
+ localizeAxes(plot);
+ adjustAxes(plot);
+ if (!(axis instanceof LogarithmicAxis)) {
+ // XXX:
+ // The auto zoom without a range tries
+ // to include 0 in a logarithmic axis
+ // which triggers a bug in jfreechart that causes
+ // the values to be drawn carthesian
+ autoZoom(plot);
+ }
+
+ //debugAxis(plot);
+
+ // These have to go after the autozoom.
+ AnnotationHelper.addAnnotationsToRenderer(annotations, plot,
+ getChartSettings(), datasets);
+
+ // Add a logo (maybe).
+ addLogo(plot);
+
+ aggregateLegendEntries(plot);
+
+ return chart;
+ }
+
+ public String getOutName() {
+ return outName;
+ }
+
+ /**
+ * Return left most data points x value (on first axis).
+ */
+ protected double getLeftX() {
+ if (inverted) {
+ return (Double)getXBounds(0).getUpper();
+ }
+ return (Double)getXBounds(0).getLower();
+ }
+
+
+ /**
+ * Return right most data points x value (on first axis).
+ */
+ protected double getRightX() {
+ if (inverted) {
+ return (Double)getXBounds(0).getLower();
+ }
+ return (Double)getXBounds(0).getUpper();
+ }
+
+
+ /** Add a logo as background annotation to plot. */
+ protected void addLogo(XYPlot plot) {
+ String logo = showLogo();
+ if (logo == null) {
+ logger.debug("No logo to show chosen");
+ return;
+ }
+
+ ImageIcon imageIcon = null;
+ if (logo.equals("none")) {
+ return;
+ }
+ /*
+ If you want to add images, remember to change code in these places:
+ flys-artifacts:
+ DiagramGenerator.java
+ Timeseries*Generator.java and
+ in the flys-client projects Chart*Propert*Editor.java.
+ Also, these images have to be put in
+ flys-artifacts/src/main/resources/images/
+ flys-client/src/main/webapp/images/
+ */
+ java.net.URL imageURL;
+ if (logo.equals("Intevation")) {
+ imageURL = DiagramGenerator.class.getResource("/images/intevation.png");
+ }
+ else { // TODO else if ...
+ imageURL = DiagramGenerator.class.getResource("/images/bfg_logo.gif");
+ }
+ imageIcon = new ImageIcon(imageURL);
+
+
+ double xPos = 0d, yPos = 0d;
+
+ String placeh = logoHPlace();
+ String placev = logoVPlace();
+
+ if (placev == null || placev.equals("none")) {
+ placev = "top";
+ }
+ if (placev.equals("top")) {
+ yPos = (Double)getYBounds(0).getUpper();
+ }
+ else if (placev.equals("bottom")) {
+ yPos = (Double)getYBounds(0).getLower();
+ }
+ else if (placev.equals("center")) {
+ yPos = ((Double)getYBounds(0).getUpper() + (Double)getYBounds(0).getLower())/2d;
+ }
+ else {
+ logger.debug("Unknown place-v value: " + placev);
+ }
+
+ if (placeh == null || placeh.equals("none")) {
+ placeh = "center";
+ }
+ if (placeh.equals("left")) {
+ xPos = getLeftX();
+ }
+ else if (placeh.equals("right")) {
+ xPos = getRightX();
+ }
+ else if (placeh.equals("center")) {
+ xPos = ((Double)getXBounds(0).getUpper() + (Double)getXBounds(0).getLower())/2d;
+ }
+ else {
+ logger.debug("Unknown place-h value: " + placeh);
+ }
+
+ logger.debug("logo position: " + xPos + "/" + yPos);
+
+ org.jfree.ui.RectangleAnchor anchor
+ = org.jfree.ui.RectangleAnchor.TOP;
+ if (placev.equals("top")) {
+ if (placeh.equals("left")) {
+ anchor = org.jfree.ui.RectangleAnchor.TOP_LEFT;
+ }
+ else if (placeh.equals("right")) {
+ anchor = org.jfree.ui.RectangleAnchor.TOP_RIGHT;
+ }
+ else if (placeh.equals("center")) {
+ anchor = org.jfree.ui.RectangleAnchor.TOP;
+ }
+ }
+ else if (placev.equals("bottom")) {
+ if (placeh.equals("left")) {
+ anchor = org.jfree.ui.RectangleAnchor.BOTTOM_LEFT;
+ }
+ else if (placeh.equals("right")) {
+ anchor = org.jfree.ui.RectangleAnchor.BOTTOM_RIGHT;
+ }
+ else if (placeh.equals("center")) {
+ anchor = org.jfree.ui.RectangleAnchor.BOTTOM;
+ }
+ }
+ else if (placev.equals("center")) {
+ if (placeh.equals("left")) {
+ anchor = org.jfree.ui.RectangleAnchor.LEFT;
+ }
+ else if (placeh.equals("right")) {
+ anchor = org.jfree.ui.RectangleAnchor.RIGHT;
+ }
+ else if (placeh.equals("center")) {
+ anchor = org.jfree.ui.RectangleAnchor.CENTER;
+ }
+ }
+
+ XYAnnotation xyannotation =
+ new XYImageAnnotation(xPos, yPos, imageIcon.getImage(), anchor);
+ plot.getRenderer().addAnnotation(xyannotation, org.jfree.ui.Layer.BACKGROUND);
+ }
+
+
+ protected NumberAxis createXAxis(String label) {
+ return new NumberAxis(label);
+ }
+
+
+ @Override
+ protected Series getSeriesOf(XYDataset dataset, int idx) {
+ return ((XYSeriesCollection) dataset).getSeries(idx);
+ }
+
+
+ @Override
+ protected AxisDataset createAxisDataset(int idx) {
+ logger.debug("Create new AxisDataset for index: " + idx);
+ return new AxisDataset(idx);
+ }
+
+
+ /**
+ * Put debug output about datasets.
+ */
+ public void debugDatasets(XYPlot plot) {
+ logger.debug("Number of datasets: " + plot.getDatasetCount());
+ for (int i = 0, P = plot.getDatasetCount(); i < P; i++) {
+ if (plot.getDataset(i) == null) {
+ logger.debug("Dataset #" + i + " is null");
+ continue;
+ }
+ logger.debug("Dataset #" + i + ":" + plot.getDataset(i));
+ XYSeriesCollection series = (XYSeriesCollection) plot.getDataset(i);
+ logger.debug("X-Extend of Dataset: " + series.getSeries(0).getMinX()
+ + " " + series.getSeries(0).getMaxX());
+ logger.debug("Y-Extend of Dataset: " + series.getSeries(0).getMinY()
+ + " " + series.getSeries(0).getMaxY());
+ }
+ }
+
+
+ /**
+ * Put debug output about axes.
+ */
+ public void debugAxis(XYPlot plot) {
+ logger.debug("...............");
+ for (int i = 0, P = plot.getRangeAxisCount(); i < P; i++) {
+ if (plot.getRangeAxis(i) == null)
+ logger.debug("Range-Axis #" + i + " == null");
+ else {
+ logger.debug("Range-Axis " + i + " != null [" +
+ plot.getRangeAxis(i).getRange().getLowerBound() +
+ " " + plot.getRangeAxis(i).getRange().getUpperBound() +
+ "]");
+ }
+ }
+ for (int i = 0, P = plot.getDomainAxisCount(); i < P; i++) {
+ if (plot.getDomainAxis(i) == null)
+ logger.debug("Domain-Axis #" + i + " == null");
+ else {
+ logger.debug("Domain-Axis " + i + " != null [" +
+ plot.getDomainAxis(i).getRange().getLowerBound() +
+ " " + plot.getDomainAxis(i).getRange().getUpperBound() +
+ "]");
+ }
+ }
+ logger.debug("...............");
+ }
+
+ /**
+ * Registers an area to be drawn.
+ * @param area Area to be drawn.
+ * @param axisName Name of the axis.
+ * @param visible Whether or not to be visible (important for range calculations).
+ */
+ public void addAreaSeries(StyledAreaSeriesCollection area, String axisName, boolean visible) {
+ addAreaSeries(area, diagramAttributes.getAxisIndex(axisName), visible);
+ }
+
+ /**
+ * Registers an area to be drawn.
+ * @param area Area to be drawn.
+ * @param index 'axis index'
+ * @param visible Whether or not to be visible (important for range calculations).
+ */
+ public void addAreaSeries(StyledAreaSeriesCollection area, int index, boolean visible) {
+ if (area == null) {
+ logger.warn("Cannot yet render above/under curve.");
+ return;
+ }
+
+ AxisDataset axisDataset = (AxisDataset) getAxisDataset(index);
+
+ if (visible) {
+ axisDataset.addArea(area);
+ }
+ else {
+ /* No range merging, for areas extending to infinity this
+ * causes problems. */
+ }
+ }
+
+ /**
+ * Add given series if visible, if not visible adjust ranges (such that
+ * all points in data would be plotted once visible).
+ * @param series the data series to include in plot.
+ * @param index index of the axis.
+ * @param visible whether or not the data should be plotted.
+ */
+ public void addAxisSeries(XYSeries series, int index, boolean visible) {
+ if (series == null) {
+ return;
+ }
+
+ logger.debug("Y Range of XYSeries: " +
+ series.getMinY() + " | " + series.getMaxY());
+
+ addAxisDataset(new XYSeriesCollection(series), index, visible);
+ }
+
+ /**
+ * Add given series if visible, if not visible adjust ranges (such that
+ * all points in data would be plotted once visible).
+ * @param series the data series to include in plot.
+ * @param axisName name of the axis.
+ * @param visible whether or not the data should be plotted.
+ */
+ public void addAxisSeries(XYSeries series, String axisName, boolean visible) {
+ addAxisSeries(series, diagramAttributes.getAxisIndex(axisName), visible);
+ }
+
+
+ /**
+ * Add the given vertical marker to the chart.
+ */
+ public void addDomainMarker(Marker marker) {
+ addDomainMarker(marker, true);
+ }
+
+
+ /**
+ * Add the given vertical marker to the chart.<b>Note:</b> the marker is
+ * added to the chart only if it is not null and if <i>visible</i> is true.
+ * @param marker The marker that should be added to the chart.
+ * @param visible The visibility of the marker.
+ */
+ public void addDomainMarker(Marker marker, boolean visible) {
+ if (visible && marker != null) {
+ domainMarkers.add(marker);
+ }
+ }
+
+
+ /**
+ * Add the given vertical marker to the chart.
+ */
+ public void addValueMarker(Marker marker) {
+ addValueMarker(marker, true);
+ }
+
+
+ /**
+ * Add the given horizontal marker to the chart.<b>Note:</b> the marker is
+ * added to the chart only if it is not null and if <i>visible</i> is true.
+ * @param marker The marker that should be added to the chart.
+ * @param visible The visibility of the marker.
+ */
+ public void addValueMarker(Marker marker, boolean visible) {
+ if (visible && marker != null) {
+ valueMarkers.add(marker);
+ }
+ }
+
+
+ protected void addMarkers(XYPlot plot) {
+ for(Marker marker : domainMarkers) {
+ plot.addDomainMarker(marker);
+ }
+ for(Marker marker : valueMarkers) {
+ plot.addRangeMarker(marker);
+ }
+ }
+
+
+ /**
+ * Effect: extend range of x axis to include given limits.
+ *
+ * @param bounds the given ("minimal") bounds.
+ * @param index index of axis to be merged.
+ */
+ @Override
+ protected void combineXBounds(Bounds bounds, int index) {
+ if (!(bounds instanceof DoubleBounds)) {
+ logger.warn("Unsupported Bounds type: " + bounds.getClass());
+ return;
+ }
+
+ DoubleBounds dBounds = (DoubleBounds) bounds;
+
+ if (dBounds == null
+ || Double.isNaN((Double) dBounds.getLower())
+ || Double.isNaN((Double) dBounds.getUpper())) {
+ return;
+ }
+
+ Bounds old = getXBounds(index);
+
+ if (old != null) {
+ dBounds = (DoubleBounds) dBounds.combine(old);
+ }
+
+ setXBounds(index, dBounds);
+ }
+
+
+ @Override
+ protected void combineYBounds(Bounds bounds, int index) {
+ if (!(bounds instanceof DoubleBounds)) {
+ logger.warn("Unsupported Bounds type: " + bounds.getClass());
+ return;
+ }
+
+ DoubleBounds dBounds = (DoubleBounds) bounds;
+
+ if (dBounds == null
+ || Double.isNaN((Double) dBounds.getLower())
+ || Double.isNaN((Double) dBounds.getUpper())) {
+ return;
+ }
+
+ Bounds old = getYBounds(index);
+
+ if (old != null) {
+ dBounds = (DoubleBounds) dBounds.combine(old);
+ }
+
+ setYBounds(index, dBounds);
+ }
+
+
+ /**
+ * If no data is visible, draw at least empty axis.
+ */
+ private void recoverEmptyPlot(XYPlot plot) {
+ if (plot.getRangeAxis() == null) {
+ logger.debug("debug: No range axis");
+ plot.setRangeAxis(createYAxis(0));
+ }
+ }
+
+
+ /**
+ * Expands X axes if only a point is shown.
+ */
+ private void preparePointRanges(XYPlot plot) {
+ for (int i = 0, num = plot.getDomainAxisCount(); i < num; i++) {
+
+ Integer key = Integer.valueOf(i);
+ Bounds b = getXBounds(key);
+
+
+ if (b != null && b.getLower().equals(b.getUpper())) {
+ logger.debug("Check whether to expand a x axis.i ("+b.getLower() + "-" + b.getUpper()+")");
+ setXBounds(key, ChartHelper.expandBounds(b, 5));
+ }
+ }
+ }
+
+
+ /**
+ * This method zooms the plot to the specified ranges in the attribute
+ * document or to the ranges specified by the min/max values in the
+ * datasets. <b>Note:</b> We determine the range manually if no zoom ranges
+ * are given, because JFreeCharts auto-zoom adds a margin to the left and
+ * right of the data area.
+ *
+ * @param plot The XYPlot.
+ */
+ protected void autoZoom(XYPlot plot) {
+ logger.debug("Zoom to specified ranges.");
+
+ Range xrange = getDomainAxisRange();
+ Range yrange = getValueAxisRange();
+
+ ValueAxis xAxis = plot.getDomainAxis();
+
+ Range fixedXRange = getRangeForAxisFromSettings("X");
+ if (fixedXRange != null) {
+ xAxis.setRange(fixedXRange);
+ }
+ else {
+ zoomX(plot, xAxis, getXBounds(0), xrange);
+ }
+
+ for (int i = 0, num = plot.getRangeAxisCount(); i < num; i++) {
+ ValueAxis yaxis = plot.getRangeAxis(i);
+
+ if (yaxis instanceof IdentifiableNumberAxis) {
+ IdentifiableNumberAxis idAxis = (IdentifiableNumberAxis) yaxis;
+
+ Range fixedRange = getRangeForAxisFromSettings(idAxis.getId());
+ if (fixedRange != null) {
+ yaxis.setRange(fixedRange);
+ continue;
+ }
+ }
+
+ if (yaxis == null) {
+ logger.debug("Zoom problem: no Y Axis for index: " + i);
+ continue;
+ }
+
+ logger.debug("Prepare zoom settings for y axis at index: " + i);
+ zoomY(plot, yaxis, getYBounds(Integer.valueOf(i)), yrange);
+ }
+ }
+
+
+ protected Range getDomainAxisRange() {
+ String[] ranges = getDomainAxisRangeFromRequest();
+
+ if (ranges == null || ranges.length < 2) {
+ logger.debug("No zoom range for domain axis specified.");
+ return null;
+ }
+
+ if (ranges[0].length() > 0 && ranges[1].length() > 0) {
+ try {
+ double from = Double.parseDouble(ranges[0]);
+ double to = Double.parseDouble(ranges[1]);
+
+ if (from == 0 && to == 0) {
+ logger.debug("No range specified. Lower and upper X == 0");
+ return null;
+ }
+
+ if (from > to) {
+ double tmp = to;
+ to = from;
+ from = tmp;
+ }
+
+ return new Range(from, to);
+ }
+ catch (NumberFormatException nfe) {
+ logger.warn("Wrong values for domain axis range.");
+ }
+ }
+
+ return null;
+ }
+
+
+ protected Range getValueAxisRange() {
+ String[] ranges = getValueAxisRangeFromRequest();
+
+ if (ranges == null || ranges.length < 2) {
+ logger.debug("No range specified. Lower and upper Y == 0");
+ return null;
+ }
+
+ if (ranges[0].length() > 0 && ranges[1].length() > 0) {
+ try {
+ double from = Double.parseDouble(ranges[0]);
+ double to = Double.parseDouble(ranges[1]);
+
+ if (from == 0 && to == 0) {
+ logger.debug("No range specified. Lower and upper Y == 0");
+ return null;
+ }
+
+ return from > to
+ ? new Range(to, from)
+ : new Range(from, to);
+ }
+ catch (NumberFormatException nfe) {
+ logger.warn("Wrong values for value axis range.");
+ }
+ }
+
+ return null;
+ }
+
+
+ protected boolean zoomX(XYPlot plot, ValueAxis axis, Bounds bounds, Range x) {
+ return zoom(plot, axis, bounds, x);
+ }
+
+
+ protected boolean zoomY(XYPlot plot, ValueAxis axis, Bounds bounds, Range x) {
+ return zoom(plot, axis, bounds, x);
+ }
+
+
+ /**
+ * Zooms the x axis to the range specified in the attribute document.
+ *
+ * @param plot The XYPlot.
+ * @param axis The axis the shoud be modified.
+ * @param bounds The whole range specified by a dataset.
+ * @param x A user defined range (null permitted).
+ *
+ * @return true, if a zoom range was specified, otherwise false.
+ */
+ protected boolean zoom(XYPlot plot, ValueAxis axis, Bounds bounds, Range x) {
+
+ if (bounds == null) {
+ return false;
+ }
+
+ if (x != null) {
+ Bounds computed = calculateZoom(bounds, x);
+ computed.applyBounds(axis, AXIS_SPACE);
+
+ logger.debug("Zoom axis to: " + computed);
+
+ return true;
+ }
+
+ bounds.applyBounds(axis, AXIS_SPACE);
+ return false;
+ }
+
+ /**
+ * Calculates the start and end km for zoomed charts.
+ * @param bounds The given total bounds (unzoomed).
+ * @param range The range specifying the zoom.
+ *
+ * @return The start and end km for the zoomed chart.
+ */
+ protected Bounds calculateZoom(Bounds bounds, Range range) {
+ double min = bounds.getLower().doubleValue();
+ double max = bounds.getUpper().doubleValue();
+
+ if (logger.isDebugEnabled()) {
+ logger.debug("Minimum is: " + min);
+ logger.debug("Maximum is: " + max);
+ logger.debug("Lower zoom is: " + range.getLowerBound());
+ logger.debug("Upper zoom is: " + range.getUpperBound());
+ }
+
+ double diff = max > min ? max - min : min - max;
+
+ DoubleBounds computed = new DoubleBounds(
+ min + range.getLowerBound() * diff,
+ min + range.getUpperBound() * diff);
+ return computed;
+ }
+
+ /**
+ * Extract the minimum and maximum values for x and y axes
+ * which are stored in <i>xRanges</i> and <i>yRanges</i>.
+ *
+ * @param index The index of the y-Axis.
+ *
+ * @return a Range[] as follows: [x-Range, y-Range].
+ */
+ @Override
+ public Range[] getRangesForAxis(int index) {
+ logger.debug("getRangesForAxis " + index);
+
+ Bounds rx = getXBounds(Integer.valueOf(0));
+ Bounds ry = getYBounds(Integer.valueOf(index));
+
+ if (rx == null) {
+ logger.warn("Range for x axis not set." +
+ " Using default values: 0 - 1.");
+ rx = new DoubleBounds(0, 1);
+ }
+ if (ry == null) {
+ logger.warn("Range for y" + index +
+ " axis not set. Using default values: 0 - 1.");
+ ry = new DoubleBounds(0, 1);
+ }
+
+ return new Range[] {
+ new Range(rx.getLower().doubleValue(), rx.getUpper().doubleValue()),
+ new Range(ry.getLower().doubleValue(), ry.getUpper().doubleValue())
+ };
+ }
+
+
+ /** Get X (usually horizontal) extent for given axis. */
+ @Override
+ public Bounds getXBounds(int axis) {
+ return xBounds.get(axis);
+ }
+
+
+ /** Set X (usually horizontal) extent for given axis. */
+ @Override
+ protected void setXBounds(int axis, Bounds bounds) {
+ if (bounds.getLower() == bounds.getUpper()) {
+ xBounds.put(axis, ChartHelper.expandBounds(bounds, 5d));
+ }
+ else {
+ xBounds.put(axis, bounds);
+ }
+ }
+
+
+ /** Get Y (usually vertical) extent for given axis. */
+ @Override
+ public Bounds getYBounds(int axis) {
+ return yBounds.get(axis);
+ }
+
+
+ /** Set Y (usually vertical) extent for given axis. */
+ @Override
+ protected void setYBounds(int axis, Bounds bounds) {
+ yBounds.put(axis, bounds);
+ }
+
+
+ /**
+ * Adjusts the axes of a plot. This method sets the <i>labelFont</i> of the
+ * X axis and applies the inversion if inverted is true.
+ *
+ * (Duplicate in TimeseriesChartGenerator)
+ *
+ * @param plot The XYPlot of the chart.
+ */
+ protected void adjustAxes(XYPlot plot) {
+ ValueAxis xaxis = plot.getDomainAxis();
+
+ ChartSettings chartSettings = getChartSettings();
+ if (chartSettings == null) {
+ return;
+ }
+
+ Font labelFont = new Font(
+ DEFAULT_FONT_NAME,
+ Font.BOLD,
+ getXAxisLabelFontSize());
+
+ xaxis.setLabelFont(labelFont);
+ xaxis.setTickLabelFont(labelFont);
+
+ logger.debug("Adjusting xAxis. Inverted?: " + inverted);
+ if (inverted) {
+ xaxis.setInverted(true);
+ }
+ }
+
+
+ /**
+ * This method walks over all axes (domain and range) of <i>plot</i> and
+ * calls localizeDomainAxis() for domain axes or localizeRangeAxis() for
+ * range axes.
+ *
+ * @param plot The XYPlot.
+ */
+ private void localizeAxes(XYPlot plot) {
+ for (int i = 0, num = plot.getDomainAxisCount(); i < num; i++) {
+ ValueAxis axis = plot.getDomainAxis(i);
+
+ if (axis != null) {
+ localizeDomainAxis(axis);
+ }
+ else {
+ logger.warn("Domain axis at " + i + " is null.");
+ }
+ }
+
+ for (int i = 0, num = plot.getRangeAxisCount(); i < num; i++) {
+ ValueAxis axis = plot.getRangeAxis(i);
+
+ if (axis != null) {
+ localizeRangeAxis(axis);
+ }
+ else {
+ logger.warn("Range axis at " + i + " is null.");
+ }
+ }
+ }
+
+
+ /**
+ * Overrides the NumberFormat with the NumberFormat for the current locale
+ * that is provided by getLocale().
+ *
+ * @param domainAxis The domain axis that needs localization.
+ */
+ protected void localizeDomainAxis(ValueAxis domainAxis) {
+ NumberFormat nf = NumberFormat.getInstance(getLocale());
+ ((NumberAxis) domainAxis).setNumberFormatOverride(nf);
+ }
+
+
+ /**
+ * Overrides the NumberFormat with the NumberFormat for the current locale
+ * that is provided by getLocale().
+ *
+ * @param rangeAxis The domain axis that needs localization.
+ */
+ protected void localizeRangeAxis(ValueAxis rangeAxis) {
+ NumberFormat nf = NumberFormat.getInstance(getLocale());
+ ((NumberAxis) rangeAxis).setNumberFormatOverride(nf);
+ }
+
+
+ /**
+ * Create a hash from a legenditem.
+ * This hash can then be used to merge legend items labels.
+ * @return hash for given legenditem to identify mergeables.
+ */
+ public static String legendItemHash(LegendItem li) {
+ // TODO Do proper implementation. Ensure that only mergable sets are created.
+ // getFillPaint()
+ // getFillPaintTransformer()
+ // getLabel()
+ // getLine()
+ // getLinePaint()
+ // getLineStroke()
+ // getOutlinePaint()
+ // getOutlineStroke()
+ // Shape getShape()
+ // String getToolTipText()
+ // String getURLText()
+ // boolean isLineVisible()
+ // boolean isShapeFilled()
+ // boolean isShapeOutlineVisible()
+ // boolean isShapeVisible()
+ String hash = li.getLinePaint().toString();
+ String label = li.getLabel();
+ if (label.startsWith("W (") || label.startsWith("W(")) {
+ hash += "-W-";
+ }
+ else if (label.startsWith("Q(") || label.startsWith("Q (")) {
+ hash += "-Q-";
+ }
+
+ // WQ.java holds example of using regex Matcher/Pattern.
+
+ return hash;
+ }
+
+ /** True if x axis has been inverted. */
+ public boolean isInverted() {
+ return inverted;
+ }
+
+
+ /** Set to true if x axis should be inverted.
+ * This can not be set to false afterwards. */
+ public void setInverted(boolean value) {
+ /* One request to invert dominates. */
+ if (!inverted) {
+ inverted = value;
+ }
+ }
+
+ @Override
+ public String getDefaultChartTitle() {
+ DiagramAttributes.Title dTitle = diagramAttributes.getTitle();
+ if (dTitle == null) {
+ return "Title not configured in conf.xml";
+ }
+
+ return dTitle.evaluate((D4EArtifact)getMaster(), context);
+ }
+
+ @Override
+ public String getDefaultChartSubtitle() {
+ DiagramAttributes.Title dTitle = diagramAttributes.getSubtitle();
+ if (dTitle == null) {
+ return "Subtitle not configured in conf.xml";
+ }
+
+ return dTitle.evaluate((D4EArtifact)getMaster(), context);
+ }
+
+ /**
+ * Get internationalized label for the x axis.
+ */
+ @Override
+ protected String getDefaultXAxisLabel() {
+ DiagramAttributes.Title dTitle = diagramAttributes.getDomainAxisTitle();
+ if (dTitle == null) {
+ return "Domain Axis Title not configured in conf.xml";
+ }
+
+ return dTitle.evaluate((D4EArtifact)getMaster(), context);
+ }
+
+ @Override
+ protected String getDefaultYAxisLabel(String axisName) {
+ Processor pr = diagramAttributes.getProcessorForAxisName(axisName);
+ return pr == null ? "" : pr.getAxisLabel(this);
+ }
+
+
+ /**
+ * Creates a list of Section for the chart's Y axes.
+ *
+ * @return a list of Y axis sections.
+ */
+ protected List<AxisSection> buildYAxisSections() {
+ List<AxisSection> axisSections = new ArrayList<AxisSection>();
+
+ List<DiagramAttributes.AxisAttributes> axesAttrs = diagramAttributes.getAxesAttributes();
+
+ for (int i = 0, n = axesAttrs.size(); i < n; i++) {
+ AxisSection ySection = new AxisSection();
+ String axisName = diagramAttributes.getAxisName(i);
+ ySection.setIdentifier(axisName);
+ ySection.setLabel(getYAxisLabel(axisName));
+ ySection.setFontSize(14);
+ ySection.setFixed(false);
+
+ // XXX We are able to find better default ranges that [0,0], the
+ // only problem is, that we do NOT have a better range than [0,0]
+ // for each axis, because the initial chart will not have a dataset
+ // for each axis set!
+ ySection.setUpperRange(0d);
+ ySection.setLowerRange(0d);
+
+ axisSections.add(ySection);
+ }
+
+ return axisSections;
+ }
+
+ /**
+ * Returns the Y-Axis label of a chart at position <i>pos</i>.
+ *
+ * @return the Y-Axis label of a chart at position <i>0</i>.
+ */
+ protected String getYAxisLabel(String axisName) {
+ ChartSettings chartSettings = getChartSettings();
+ if (chartSettings == null) {
+ return getDefaultYAxisLabel(axisName);
+ }
+ AxisSection as = chartSettings.getAxisSection(axisName);
+ if (as != null) {
+ String label = as.getLabel();
+ if (label != null) {
+ return label;
+ }
+ }
+
+ return getDefaultYAxisLabel(axisName);
+ }
+
+ protected String axisIndexToName(int index) {
+ return diagramAttributes.getAxisName(index);
+ }
+
+ /** Add the acutal data to the diagram according to the processors.
+ * For every outable facets, this function is
+ * called and handles the data accordingly. */
+ @Override
+ public void doOut(
+ ArtifactAndFacet bundle,
+ ThemeDocument theme,
+ boolean visible
+ ) {
+ String facetName = bundle.getFacetName();
+ Facet facet = bundle.getFacet();
+
+ /* A conservative security check */
+ if (facetName == null || facet == null) {
+ /* Can't happen,.. */
+ logger.error("doOut called with null facet.");
+ return;
+ }
+
+ logger.debug("DoOut for facet: " + facetName);
+
+ boolean found = false;
+ List<Processor> prL = diagramAttributes.getProcessors();
+ for (Processor pr: prL) {
+ if (pr.canHandle(facetName)) {
+ found = true;
+ pr.doOut(this, bundle, theme, visible);
+ }
+ }
+ if (!found) {
+ logger.warn("No processor found for: " + facetName);
+ if (logger.isDebugEnabled()) {
+ logger.debug("Configured processors for this diagram are:");
+ for (Processor pr: prL) {
+ logger.debug(pr.getClass().getName());
+ }
+ }
+ }
+ }
+
+ @Override
+ protected NumberAxis createYAxis(int index) {
+ NumberAxis axis = super.createYAxis(index);
+
+ if (diagramAttributes.getAxesAttributes().get(index).includeZero()) {
+ axis.setAutoRangeIncludesZero(true);
+ }
+ return axis;
+ }
+}
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/exports/DischargeLongitudinalSectionGenerator.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/DischargeLongitudinalSectionGenerator.java Mon Sep 23 11:37:13 2013 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,129 +0,0 @@
-/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde
- * Software engineering by Intevation GmbH
- *
- * This file is Free Software under the GNU AGPL (>=v3)
- * and comes with ABSOLUTELY NO WARRANTY! Check out the
- * documentation coming with Dive4Elements River for details.
- */
-
-package org.dive4elements.river.exports;
-
-import org.apache.log4j.Logger;
-
-import org.jfree.data.xy.XYSeries;
-
-import org.dive4elements.artifactdatabase.state.ArtifactAndFacet;
-import org.dive4elements.artifactdatabase.state.Facet;
-
-import org.dive4elements.river.artifacts.model.FacetTypes;
-import org.dive4elements.river.artifacts.model.WQCKms;
-import org.dive4elements.river.exports.process.Processor;
-import org.dive4elements.river.exports.process.QOutProcessor;
-import org.dive4elements.river.exports.process.WOutProcessor;
-
-import org.dive4elements.river.jfree.RiverAnnotation;
-import org.dive4elements.river.jfree.StyledXYSeries;
-import org.dive4elements.river.themes.ThemeDocument;
-
-
-
-/**
- * An OutGenerator that generates discharge longitudinal section curves.
- *
- * @author <a href="mailto:ingo.weinzierl at intevation.de">Ingo Weinzierl</a>
- */
-public class DischargeLongitudinalSectionGenerator
-extends LongitudinalSectionGenerator
-implements FacetTypes
-{
- private static Logger logger =
- Logger.getLogger(DischargeLongitudinalSectionGenerator.class);
-
-
- public DischargeLongitudinalSectionGenerator() {
- super();
- }
-
-
- @Override
- public void doOut(
- ArtifactAndFacet artifactFacet,
- ThemeDocument attr,
- boolean visible
- ) {
- logger.debug("DischargeLongitudinalSectionGenerator.doOut");
-
- String name = artifactFacet.getFacetName();
-
- if (name == null) {
- return;
- }
-
- Facet facet = artifactFacet.getFacet();
-
- if (name.equals(DISCHARGE_LONGITUDINAL_C)) {
- doCorrectedWOut(
- (WQCKms) artifactFacet.getData(context),
- facet,
- attr,
- visible);
- }
- else if (name.equals(LONGITUDINAL_ANNOTATION)) {
- doAnnotations((RiverAnnotation) artifactFacet.getData(context),
- artifactFacet, attr, visible);
- }
- else if (FacetTypes.IS.MANUALPOINTS(name)) {
- doPoints(artifactFacet.getData(context),
- artifactFacet,
- attr, visible, YAXIS.W.idx);
- }
- else {
- Processor processor = new WOutProcessor();
- Processor qProcessor = new QOutProcessor();
- if (processor.canHandle(name)) {
- processor.doOut(this, artifactFacet, attr, visible, YAXIS.W.idx);
- }
- else if (qProcessor.canHandle(name)) {
- qProcessor.doOut(this, artifactFacet, attr, visible, YAXIS.Q.idx);
- }
- else {
- logger.warn("Unknown facet name: " + name);
- }
- }
- }
-
-
- /**
- * Adds a new series for the corrected W curve.
- *
- * @param wqckms The object that contains the corrected W values.
- * @param theme The theme that contains styling information.
- */
- protected void doCorrectedWOut(
- WQCKms wqckms,
- Facet facet,
- ThemeDocument theme,
- boolean visible
- ) {
- logger.debug("DischargeLongitudinalSectionGenerator.doCorrectedWOut");
-
- int size = wqckms.size();
-
- if (size > 0) {
- XYSeries series = new StyledXYSeries(
- facet.getDescription(),
- theme);
-
- for (int i = 0; i < size; i++) {
- series.add(wqckms.getKm(i), wqckms.getC(i));
- }
-
- addAxisSeries(series, YAXIS.W.idx, visible);
- }
-
- if (wqckms.guessWaterIncreasing()) {
- setInverted(true);
- }
- }
-}
-// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/exports/DischargeLongitudinalSectionInfoGenerator.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/DischargeLongitudinalSectionInfoGenerator.java Mon Sep 23 11:37:13 2013 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +0,0 @@
-/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde
- * Software engineering by Intevation GmbH
- *
- * This file is Free Software under the GNU AGPL (>=v3)
- * and comes with ABSOLUTELY NO WARRANTY! Check out the
- * documentation coming with Dive4Elements River for details.
- */
-
-package org.dive4elements.river.exports;
-
-
-/**
- * A ChartInfoGenerator that generates meta information for specific discharge
- * longitudinal section curves.
- *
- * @author <a href="mailto:ingo.weinzierl at intevation.de">Ingo Weinzierl</a>
- */
-public class DischargeLongitudinalSectionInfoGenerator
-extends ChartInfoGenerator
-{
- public DischargeLongitudinalSectionInfoGenerator() {
- super(new DischargeLongitudinalSectionGenerator());
- }
-}
-// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/exports/DurationCurveExporter.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/DurationCurveExporter.java Mon Sep 23 11:37:13 2013 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/DurationCurveExporter.java Tue Sep 24 12:29:44 2013 +0200
@@ -18,8 +18,6 @@
import java.text.DateFormat;
import java.util.Locale;
-import org.w3c.dom.Document;
-
import org.apache.log4j.Logger;
import au.com.bytecode.opencsv.CSVWriter;
@@ -29,7 +27,6 @@
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JRException;
-import org.dive4elements.artifacts.CallContext;
import org.dive4elements.artifacts.CallMeta;
import org.dive4elements.artifacts.common.utils.Config;
@@ -73,16 +70,10 @@
/** The storage that contains all WQKms objects for the different facets. */
protected List<WQDay> data;
-
- public void init(Document request, OutputStream out, CallContext context) {
- logger.debug("DurationCurveExporter.init");
-
- super.init(request, out, context);
-
- this.data = new ArrayList<WQDay>();
+ public DurationCurveExporter() {
+ data = new ArrayList<WQDay>();
}
-
@Override
protected void addData(Object d) {
if (d instanceof CalculationResult) {
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/exports/FlowVelocityExporter.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/FlowVelocityExporter.java Mon Sep 23 11:37:13 2013 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/FlowVelocityExporter.java Tue Sep 24 12:29:44 2013 +0200
@@ -13,14 +13,10 @@
import java.util.ArrayList;
import java.util.List;
-import org.w3c.dom.Document;
-
import org.apache.log4j.Logger;
import au.com.bytecode.opencsv.CSVWriter;
-import org.dive4elements.artifacts.CallContext;
-
import org.dive4elements.river.artifacts.D4EArtifact;
import org.dive4elements.river.artifacts.model.CalculationResult;
import org.dive4elements.river.artifacts.model.FlowVelocityData;
@@ -58,13 +54,10 @@
protected List<FlowVelocityData[]> data;
-
- public void init(Document request, OutputStream out, CallContext cc) {
- super.init(request, out, cc);
+ public FlowVelocityExporter() {
data = new ArrayList<FlowVelocityData[]>();
}
-
@Override
protected void addData(Object d) {
if (d instanceof CalculationResult) {
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/exports/HistoricalDischargeCurveExporter.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/HistoricalDischargeCurveExporter.java Mon Sep 23 11:37:13 2013 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/HistoricalDischargeCurveExporter.java Tue Sep 24 12:29:44 2013 +0200
@@ -18,8 +18,6 @@
import java.util.HashMap;
import java.util.Locale;
-import org.w3c.dom.Document;
-
import org.apache.log4j.Logger;
import au.com.bytecode.opencsv.CSVWriter;
@@ -31,7 +29,6 @@
import org.dive4elements.artifacts.common.utils.Config;
-import org.dive4elements.artifacts.CallContext;
import org.dive4elements.artifacts.CallMeta;
import org.dive4elements.river.artifacts.D4EArtifact;
@@ -77,14 +74,10 @@
protected List<WQTimerange[]> data;
-
- public void init(Document request, OutputStream out, CallContext cc) {
- super.init(request, out, cc);
-
+ public HistoricalDischargeCurveExporter() {
data = new ArrayList<WQTimerange[]>();
}
-
@Override
protected void addData(Object d) {
logger.debug("Add data of class: " + d.getClass());
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/exports/InfoGeneratorHelper.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/InfoGeneratorHelper.java Mon Sep 23 11:37:13 2013 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/InfoGeneratorHelper.java Tue Sep 24 12:29:44 2013 +0200
@@ -48,12 +48,10 @@
protected ChartGenerator generator;
-
public InfoGeneratorHelper(ChartGenerator generator) {
this.generator = generator;
}
-
/**
* Triggers the creation of the chart info document.
*
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/exports/InfoGeneratorHelper2.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/InfoGeneratorHelper2.java Tue Sep 24 12:29:44 2013 +0200
@@ -0,0 +1,409 @@
+/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde
+ * Software engineering by Intevation GmbH
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+
+package org.dive4elements.river.exports;
+
+import java.awt.geom.AffineTransform;
+import java.awt.geom.NoninvertibleTransformException;
+import java.awt.geom.Rectangle2D;
+
+import java.util.Date;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import org.apache.log4j.Logger;
+
+import org.jfree.chart.ChartRenderingInfo;
+import org.jfree.chart.JFreeChart;
+import org.jfree.chart.axis.DateAxis;
+import org.jfree.chart.axis.NumberAxis;
+import org.jfree.chart.axis.ValueAxis;
+import org.jfree.chart.plot.XYPlot;
+import org.jfree.data.Range;
+import org.jfree.data.xy.XYDataset;
+
+import org.dive4elements.artifacts.common.ArtifactNamespaceContext;
+import org.dive4elements.artifacts.common.utils.XMLUtils;
+import org.dive4elements.artifacts.common.utils.XMLUtils.ElementCreator;
+
+import org.dive4elements.river.jfree.Bounds;
+
+
+/**
+ * This class helps generating chart info documents.
+ */
+public class InfoGeneratorHelper2 {
+
+ /** Private logging instance. */
+ private static final Logger logger =
+ Logger.getLogger(InfoGeneratorHelper2.class);
+
+ protected ChartGenerator2 generator;
+
+ public InfoGeneratorHelper2(ChartGenerator2 generator) {
+ this.generator = generator;
+ }
+
+ /**
+ * Triggers the creation of the chart info document.
+ *
+ * @param chart The JFreeChart chart.
+ * @param info An info object that has been created while chart creation.
+ *
+ * @return the info document.
+ */
+ public Document createInfoDocument(
+ JFreeChart chart,
+ ChartRenderingInfo info)
+ {
+ logger.debug("InfoGeneratorHelper.createInfoDocument");
+
+ Document doc = XMLUtils.newDocument();
+
+ ElementCreator cr = new ElementCreator(
+ doc,
+ ArtifactNamespaceContext.NAMESPACE_URI,
+ ArtifactNamespaceContext.NAMESPACE_PREFIX);
+
+ Element chartinfo = cr.create("chartinfo");
+
+ chartinfo.appendChild(createAxesElements(cr, chart));
+ chartinfo.appendChild(createTransformationElements(cr, chart, info));
+
+ doc.appendChild(chartinfo);
+
+ return doc;
+ }
+
+
+ /**
+ * This method create a axes element that contains all domain and range
+ * axes of the given chart.
+ *
+ * @param cr The ElementCreator.
+ * @param chart The chart that provides range information of its axes.
+ *
+ * @return an element with axes information.
+ */
+ protected Element createAxesElements(
+ ElementCreator cr,
+ JFreeChart chart)
+ {
+ logger.debug("InfoGeneratorHelper.createRangeElements");
+
+ Element axes = cr.create("axes");
+
+ XYPlot plot = (XYPlot) chart.getPlot();
+
+ int dAxisCount = plot.getDomainAxisCount();
+ for (int i = 0; i < dAxisCount; i++) {
+ ValueAxis axis = plot.getDomainAxis(i);
+ XYDataset data = plot.getDataset(i);
+
+ if (axis != null) {
+ Element e = createAxisElement(cr, axis, data, "domain", i);
+ axes.appendChild(e);
+ }
+ }
+
+ int rAxisCount = plot.getRangeAxisCount();
+ for (int i = 0; i < rAxisCount; i++) {
+ ValueAxis axis = plot.getRangeAxis(i);
+ XYDataset data = plot.getDataset(i);
+
+ if (axis == null || data == null) {
+ logger.warn("Axis or dataset is empty at pos: " + i);
+ continue;
+ }
+
+ Element e = createAxisElement(cr, axis, data, "range", i);
+ axes.appendChild(e);
+ }
+
+ return axes;
+ }
+
+
+ /**
+ * This method create a axis element for a given <i>axis</i> and
+ * <i>type</i>. Type can be one of 'domain' or 'range'.
+ *
+ * @param cr The ElementCreator
+ * @param axis The axis that provides range information.
+ * @param dataset The dataset for min/max determination.
+ * @param type The axis type ('domain' or 'range').
+ * @param pos The position in the chart.
+ *
+ * @return An element that contains range information of a given axis.
+ */
+ protected Element createAxisElement(
+ ElementCreator cr,
+ ValueAxis axis,
+ XYDataset dataset,
+ String type,
+ int pos)
+ {
+ logger.debug("createAxisElement " + pos);
+ logger.debug("Axis is from type: " + axis.getClass());
+
+ Element e = cr.create(type);
+ cr.addAttr(e, "pos", String.valueOf(pos), true);
+
+ if (axis instanceof DateAxis) {
+ prepareDateAxisElement(
+ e, cr, (DateAxis) axis, dataset, type, pos);
+ }
+ else {
+ prepareNumberAxisElement(
+ e, cr, (NumberAxis) axis, dataset, type, pos);
+ }
+
+ return e;
+ }
+
+
+ protected Element prepareNumberAxisElement(
+ Element e,
+ ElementCreator cr,
+ NumberAxis axis,
+ XYDataset dataset,
+ String type,
+ int pos
+ ) {
+ Range range = axis.getRange();
+
+ cr.addAttr(e, "from", String.valueOf(range.getLowerBound()), true);
+ cr.addAttr(e, "to", String.valueOf(range.getUpperBound()), true);
+ cr.addAttr(e, "axistype", "number", true);
+
+ Range[] rs = generator.getRangesForAxis(pos);
+ Range r = null;
+
+ if (type.equals("range")) {
+ r = rs[1];
+ }
+ else {
+ r = rs[0];
+ }
+
+ cr.addAttr(e, "min", String.valueOf(r.getLowerBound()), true);
+ cr.addAttr(e, "max", String.valueOf(r.getUpperBound()), true);
+
+ return e;
+ }
+
+
+ protected Element prepareDateAxisElement(
+ Element e,
+ ElementCreator cr,
+ DateAxis axis,
+ XYDataset dataset,
+ String type,
+ int pos
+ ) {
+ Date from = axis.getMinimumDate();
+ Date to = axis.getMaximumDate();
+
+ Bounds bounds = null;
+ if (type.equals("range")) {
+ bounds = generator.getYBounds(pos);
+ }
+ else {
+ bounds = generator.getXBounds(pos);
+ }
+
+ cr.addAttr(e, "axistype", "date", true);
+ cr.addAttr(e, "from", String.valueOf(from.getTime()), true);
+ cr.addAttr(e, "to", String.valueOf(to.getTime()), true);
+
+ cr.addAttr(e, "min", bounds.getLower().toString(), true);
+ cr.addAttr(e, "max", bounds.getUpper().toString(), true);
+
+ return e;
+ }
+
+
+ /**
+ * This method appends the values of a transformation matrix to transform
+ * image pixel coordinates into chart coordinates.
+ *
+ * @param cr The ElementCreator.
+ * @param chart The chart object.
+ * @param info The ChartRenderingInfo that is filled while chart creation.
+ *
+ * @return an element that contains one or more transformation matrix.
+ */
+ protected Element createTransformationElements(
+ ElementCreator cr,
+ JFreeChart chart,
+ ChartRenderingInfo info)
+ {
+ logger.debug("InfoGeneratorHelper.createTransformationElements");
+
+ Element tf = cr.create("transformation-matrix");
+
+ Rectangle2D dataArea = info.getPlotInfo().getDataArea();
+
+ XYPlot plot = (XYPlot) chart.getPlot();
+ ValueAxis xAxis = plot.getDomainAxis();
+
+ if (xAxis == null) {
+ logger.error("There is no x axis in the chart!");
+ return null;
+ }
+
+ for (int i = 0, num = plot.getRangeAxisCount(); i < num; i++) {
+ ValueAxis yAxis = plot.getRangeAxis(i);
+
+ if (yAxis == null) {
+ logger.warn("No y axis at pos " + i + " existing.");
+ continue;
+ }
+
+ Element matrix = createTransformationElement(
+ cr, xAxis, yAxis, dataArea, i);
+
+ tf.appendChild(matrix);
+ }
+
+ return tf;
+ }
+
+
+ /**
+ * Creates an element that contains values used to transform coordinates
+ * of a coordinate system A into a coordinate system B.
+ *
+ * @param cr The ElementCreator.
+ * @param xAxis The x axis of the target coordinate system.
+ * @param yAxis The y axis of the target coordinate system.
+ * @param dataArea The pixel coordinates of the chart image.
+ * @param pos The dataset position.
+ *
+ * @return an element that contains transformation matrix values.
+ */
+ protected Element createTransformationElement(
+ ElementCreator cr,
+ ValueAxis xAxis,
+ ValueAxis yAxis,
+ Rectangle2D dataArea,
+ int pos)
+ {
+ double[] tm = createTransformationMatrix(dataArea, xAxis, yAxis);
+
+ Element matrix = cr.create("matrix");
+
+ cr.addAttr(matrix, "pos", String.valueOf(pos), true);
+ cr.addAttr(matrix, "sx", String.valueOf(tm[0]), true);
+ cr.addAttr(matrix, "sy", String.valueOf(tm[1]), true);
+ cr.addAttr(matrix, "tx", String.valueOf(tm[2]), true);
+ cr.addAttr(matrix, "ty", String.valueOf(tm[3]), true);
+
+ if (xAxis instanceof DateAxis) {
+ cr.addAttr(matrix, "xtype", "date", true);
+ }
+ else {
+ cr.addAttr(matrix, "xtype", "number", true);
+ }
+
+ if (yAxis instanceof DateAxis) {
+ cr.addAttr(matrix, "ytype", "date", true);
+ }
+ else {
+ cr.addAttr(matrix, "ytype", "number", true);
+ }
+
+ return matrix;
+ }
+
+
+ /**
+ * This method determines a transformation matrix to transform pixel
+ * coordinates of the chart image into chart coordinates.
+ *
+ * @param dataArea The rectangle that contains the data points of the chart.
+ * @param xAxis The x axis.
+ * @param yAxis The y axis.
+ *
+ * @return a double array as follows: [sx, sy, tx, ty].
+ */
+ protected static double[] createTransformationMatrix(
+ Rectangle2D dataArea,
+ ValueAxis xAxis,
+ ValueAxis yAxis)
+ {
+ logger.debug("InfoGeneratorHelper.createTransformationMatrix");
+
+ double offsetX = dataArea.getX();
+ double width = dataArea.getWidth();
+ double offsetY = dataArea.getY();
+ double height = dataArea.getHeight();
+
+ Range xRange = getRangeFromAxis(xAxis);
+ Range yRange = getRangeFromAxis(yAxis);
+
+ double lowerX = xRange.getLowerBound();
+ double upperX = xRange.getUpperBound();
+ double lowerY = yRange.getLowerBound();
+ double upperY = yRange.getUpperBound();
+
+ if (xAxis.isInverted()) {
+ logger.info("X-Axis is inverted!");
+
+ double tmp = upperX;
+ upperX = lowerX;
+ lowerX = tmp;
+ }
+
+ double dMoveX = upperX - lowerX;
+ double fMoveX = width * lowerX;
+ double dMoveY = lowerY - upperY;
+ double fMoveY = height * upperY;
+
+ AffineTransform t1 = AffineTransform.getTranslateInstance(
+ offsetX - ( fMoveX / dMoveX ),
+ offsetY - ( fMoveY / dMoveY ) );
+
+ AffineTransform t2 = AffineTransform.getScaleInstance(
+ width / (upperX - lowerX),
+ height / (lowerY - upperY));
+
+ t1.concatenate(t2);
+
+ try {
+ t1.invert();
+
+ double[] c = new double[6];
+ t1.getMatrix(c);
+
+ return new double[] { c[0], c[3], c[4], c[5] };
+ }
+ catch (NoninvertibleTransformException e) {
+ // do nothing
+ logger.warn("Matrix is not invertible.");
+ }
+
+ return new double[] { 1d, 1d, 0d, 0d };
+ }
+
+
+ protected static Range getRangeFromAxis(ValueAxis axis) {
+ if (axis instanceof DateAxis) {
+ DateAxis dAxis = (DateAxis) axis;
+ Date min = dAxis.getMinimumDate();
+ Date max = dAxis.getMaximumDate();
+
+ return new Range(min.getTime(), max.getTime());
+ }
+ else {
+ return axis.getRange();
+ }
+ }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/exports/LongitudinalSectionGenerator.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/LongitudinalSectionGenerator.java Mon Sep 23 11:37:13 2013 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/LongitudinalSectionGenerator.java Tue Sep 24 12:29:44 2013 +0200
@@ -23,12 +23,11 @@
import org.dive4elements.river.exports.process.BedheightProcessor;
import org.dive4elements.river.exports.process.QOutProcessor;
import org.dive4elements.river.exports.process.WOutProcessor;
+import org.dive4elements.river.exports.process.AnnotationProcessor;
-import org.dive4elements.river.jfree.RiverAnnotation;
import org.dive4elements.river.jfree.StyledAreaSeriesCollection;
import org.dive4elements.river.jfree.StyledXYSeries;
import org.dive4elements.river.themes.ThemeDocument;
-import org.dive4elements.river.utils.DataUtil;
import org.dive4elements.river.utils.RiverUtils;
import org.apache.log4j.Logger;
import org.jfree.chart.axis.NumberAxis;
@@ -340,11 +339,12 @@
return;
}
- WOutProcessor wProcessor = new WOutProcessor();
- QOutProcessor qProcessor = new QOutProcessor();
+ Processor wProcessor = new WOutProcessor();
+ Processor qProcessor = new QOutProcessor();
Processor bedp = new BedheightProcessor();
Processor bdyProcessor = new BedDiffYearProcessor();
Processor bdhyProcessor = new BedDiffHeightYearProcessor();
+ Processor annotationProcessor = new AnnotationProcessor();
if (wProcessor.canHandle(name)) {
wProcessor.doOut(this, artifactAndFacet, attr, visible, YAXIS.W.idx);
@@ -361,12 +361,8 @@
else if (bdhyProcessor.canHandle(name)) {
bdhyProcessor.doOut(this, artifactAndFacet, attr, visible, YAXIS.W.idx);
}
- else if (name.equals(LONGITUDINAL_ANNOTATION)) {
- doAnnotations(
- (RiverAnnotation) artifactAndFacet.getData(context),
- artifactAndFacet,
- attr,
- visible);
+ else if (annotationProcessor.canHandle(name)) {
+ annotationProcessor.doOut(this, artifactAndFacet, attr, visible, 0);
}
else if (name.equals(W_DIFFERENCES)) {
doWDifferencesOut(
@@ -429,36 +425,6 @@
/**
- * This method determines - taking JFreeCharts auto x value ordering into
- * account - if the x axis need to be inverted. Waterlines in these charts
- * should decrease.
- *
- * @param wkms The data object that stores the x and y values used for this
- * chart.
- */
- public boolean needInvertAxis(WKms wkms) {
- boolean wsUp = wkms.guessWaterIncreasing();
- boolean kmUp = DataUtil.guessWaterIncreasing(wkms.allKms());
- boolean inv = (wsUp && kmUp) || (!wsUp && !kmUp);
-
- int size = wkms.size();
-
- if (logger.isDebugEnabled()) {
- logger.debug("(Wkms)Values : " + size);
- if (size > 0) {
- logger.debug("Start km: " + wkms.getKm(0));
- logger.debug("End km: " + wkms.getKm(size-1));
- }
- logger.debug("wsUp: " + wsUp);
- logger.debug("kmUp: " + kmUp);
- logger.debug("inv: " + inv);
- }
-
- return inv;
- }
-
-
- /**
* Get name of series (displayed in legend).
* @return name of the series.
*/
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/exports/LongitudinalSectionGenerator2.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/LongitudinalSectionGenerator2.java Tue Sep 24 12:29:44 2013 +0200
@@ -0,0 +1,42 @@
+/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde
+ * Software engineering by Intevation GmbH
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+
+package org.dive4elements.river.exports;
+
+import org.apache.log4j.Logger;
+import org.jfree.chart.axis.NumberAxis;
+
+
+public class LongitudinalSectionGenerator2 extends DiagramGenerator
+{
+ public static final String I18N_CHART_SHORT_SUBTITLE =
+ "chart.longitudinal.section.shortsubtitle";
+
+ public static final String I18N_CHART_LOCATION_SUBTITLE =
+ "chart.longitudinal.section.locsubtitle";
+
+ private static Logger logger =
+ Logger.getLogger(LongitudinalSectionGenerator.class);
+
+ @Override
+ public String getDefaultChartSubtitle() {
+ double[] dist = getRange();
+
+ Object[] args = null;
+ if (dist == null || dist.length != 2 ||
+ Double.isNaN(dist[0]) || Double.isNaN(dist[1])) {
+ args = new Object[] {getRiverName()};
+ return msg(I18N_CHART_SHORT_SUBTITLE, "", args);
+ } else if (Math.abs(dist[0] - dist[1]) < 1E-5) {
+ args = new Object[] {getRiverName(), dist[1]};
+ return msg(I18N_CHART_LOCATION_SUBTITLE, "", args);
+ }
+ return super.getDefaultChartSubtitle();
+ }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/exports/LongitudinalSectionInfoGenerator.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/LongitudinalSectionInfoGenerator.java Mon Sep 23 11:37:13 2013 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +0,0 @@
-/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde
- * Software engineering by Intevation GmbH
- *
- * This file is Free Software under the GNU AGPL (>=v3)
- * and comes with ABSOLUTELY NO WARRANTY! Check out the
- * documentation coming with Dive4Elements River for details.
- */
-
-package org.dive4elements.river.exports;
-
-
-/**
- * A ChartInfoGenerator that generates meta information for specific
- * longitudinal section curves.
- *
- * @author <a href="mailto:ingo.weinzierl at intevation.de">Ingo Weinzierl</a>
- */
-public class LongitudinalSectionInfoGenerator
-extends ChartInfoGenerator
-{
- public LongitudinalSectionInfoGenerator() {
- super(new LongitudinalSectionGenerator());
- }
-}
-// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/exports/MapGenerator.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/MapGenerator.java Mon Sep 23 11:37:13 2013 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/MapGenerator.java Tue Sep 24 12:29:44 2013 +0200
@@ -65,12 +65,18 @@
protected String srid;
-
+ protected String outName;
@Override
- public void init(Document request, OutputStream out, CallContext context) {
+ public void setup(Object config) {
+ logger.debug("MapGenerator.setup");
+ }
+
+ @Override
+ public void init(String outName, Document request, OutputStream out, CallContext context) {
logger.debug("MapGenerator.init");
+ this.outName = outName;
this.request = request;
this.out = out;
this.context = context;
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/exports/MiddleBedHeightExporter.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/MiddleBedHeightExporter.java Mon Sep 23 11:37:13 2013 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/MiddleBedHeightExporter.java Tue Sep 24 12:29:44 2013 +0200
@@ -13,14 +13,10 @@
import java.util.ArrayList;
import java.util.List;
-import org.w3c.dom.Document;
-
import org.apache.log4j.Logger;
import au.com.bytecode.opencsv.CSVWriter;
-import org.dive4elements.artifacts.CallContext;
-
import org.dive4elements.river.artifacts.D4EArtifact;
import org.dive4elements.river.artifacts.model.CalculationResult;
import org.dive4elements.river.artifacts.model.MiddleBedHeightData;
@@ -64,13 +60,10 @@
protected List<MiddleBedHeightData[]> data;
-
- public void init(Document request, OutputStream out, CallContext cc) {
- super.init(request, out, cc);
+ public MiddleBedHeightExporter() {
data = new ArrayList<MiddleBedHeightData[]>();
}
-
@Override
protected void addData(Object d) {
if (d instanceof CalculationResult) {
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/exports/OutGenerator.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/OutGenerator.java Mon Sep 23 11:37:13 2013 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/OutGenerator.java Tue Sep 24 12:29:44 2013 +0200
@@ -29,15 +29,21 @@
public interface OutGenerator {
/**
+ * Pre-initialize generator from configuration.
+ */
+ void setup(Object config);
+
+ /**
* Initializes the OutGenerator with meta information which are necessary
* for the output generation.
*
+ * @param outName The name of the out to serve.
* @param request The incomding request document.
* @param out The output stream.
* @param context The CallContext that provides further information and
* objects used for the output generation.
*/
- void init(Document request, OutputStream out, CallContext context);
+ void init(String outName, Document request, OutputStream out, CallContext context);
/**
* This method is used to tell the OutGenerator which artifact is the master
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/exports/ReferenceCurveExporter.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/ReferenceCurveExporter.java Mon Sep 23 11:37:13 2013 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/ReferenceCurveExporter.java Tue Sep 24 12:29:44 2013 +0200
@@ -10,7 +10,6 @@
import au.com.bytecode.opencsv.CSVWriter;
-import org.dive4elements.artifacts.CallContext;
import org.dive4elements.artifacts.CallMeta;
import org.dive4elements.artifacts.common.utils.Config;
@@ -46,8 +45,6 @@
import org.apache.log4j.Logger;
-import org.w3c.dom.Document;
-
/**
* (CSV)Exporter for Reference Curves.
*/
@@ -91,17 +88,10 @@
protected boolean endAtGauge = false;
-
- @Override
- public void init(Document request, OutputStream out, CallContext context) {
- logger.debug("ReferenceCurveExporter.init");
-
- super.init(request, out, context);
-
+ public ReferenceCurveExporter() {
this.data = new ArrayList<WWQQ[]>();
}
-
/**
* Genereate data in csv format.
*/
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/exports/ReportGenerator.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/ReportGenerator.java Mon Sep 23 11:37:13 2013 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/ReportGenerator.java Tue Sep 24 12:29:44 2013 +0200
@@ -36,13 +36,20 @@
protected Document result;
protected OutputStream out;
protected CallContext context;
+ protected String outName;
public ReportGenerator() {
}
@Override
- public void init(Document request, OutputStream out, CallContext context) {
+ public void setup(Object config) {
+ logger.debug("ReportGenerator.setup");
+ }
+
+ @Override
+ public void init(String outName, Document request, OutputStream out, CallContext context) {
logger.debug("init");
+ this.outName = outName;
this.out = out;
this.context = context;
result = null;
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/exports/ShapeExporter.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/ShapeExporter.java Mon Sep 23 11:37:13 2013 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/ShapeExporter.java Tue Sep 24 12:29:44 2013 +0200
@@ -29,9 +29,16 @@
private D4EArtifactCollection collection;
private String facet;
private File dir;
+ private String outName;
@Override
- public void init(Document request, OutputStream out, CallContext context) {
+ public void setup(Object config) {
+ logger.debug("ShapeExporter.setup");
+ }
+
+ @Override
+ public void init(String outName, Document request, OutputStream out, CallContext context) {
+ this.outName = outName;
this.request = request;
this.out = out;
this.context = context;
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/exports/TimeseriesChartGenerator.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/TimeseriesChartGenerator.java Mon Sep 23 11:37:13 2013 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/TimeseriesChartGenerator.java Tue Sep 24 12:29:44 2013 +0200
@@ -16,6 +16,7 @@
import org.dive4elements.river.jfree.RiverAnnotation;
import org.dive4elements.river.jfree.StyledTimeSeries;
import org.dive4elements.river.jfree.TimeBounds;
+import org.dive4elements.river.jfree.AxisDataset;
import org.dive4elements.river.themes.ThemeDocument;
import java.awt.Color;
@@ -60,126 +61,6 @@
public abstract class TimeseriesChartGenerator
extends ChartGenerator {
- /**
- * Inner class TimeseriesAxisDataset stores TimeSeriesCollection.
- */
- public class TimeseriesAxisDataset implements AxisDataset {
-
- protected int axisSymbol;
-
- protected List<TimeSeriesCollection> datasets;
-
- protected Range range;
-
- protected int plotAxisIndex;
-
- public TimeseriesAxisDataset(int axisSymbol) {
- this.axisSymbol = axisSymbol;
- this.datasets = new ArrayList<TimeSeriesCollection>();
- }
-
-
- @Override
- public void addDataset(XYDataset dataset) {
- if (!(dataset instanceof TimeSeriesCollection)) {
- logger.warn("Skip non TimeSeriesCollection dataset.");
- return;
- }
-
- TimeSeriesCollection tsc = (TimeSeriesCollection) dataset;
-
- datasets.add(tsc);
- mergeRanges(tsc);
- }
-
-
- @Override
- public XYDataset[] getDatasets() {
- return datasets.toArray(new XYDataset[datasets.size()]);
- }
-
-
- @Override
- public boolean isEmpty() {
- return datasets.isEmpty();
- }
-
-
- @Override
- public void setRange(Range range) {
- this.range = range;
- }
-
-
- @Override
- public Range getRange() {
- return range;
- }
-
-
- @Override
- public void setPlotAxisIndex(int plotAxisIndex) {
- this.plotAxisIndex = plotAxisIndex;
- }
-
-
- @Override
- public int getPlotAxisIndex() {
- return plotAxisIndex;
- }
-
-
- @Override
- public boolean isArea(XYDataset dataset) {
- logger.warn("This AxisDataset doesn't support Areas yet!");
- return false;
- }
-
-
- protected void mergeRanges(TimeSeriesCollection dataset) {
- logger.debug("Range before merging: " + range);
- Range subRange = null;
-
- // Determine min/max of range axis.
- for (int i = 0; i < dataset.getSeriesCount(); i++) {
- if (dataset.getSeries(i).getItemCount() == 0) {
- continue;
- }
- double min = Double.MAX_VALUE;
- double max = -Double.MAX_VALUE;
- TimeSeries series = dataset.getSeries(i);
- for (int j = 0; j < series.getItemCount(); j++) {
- double tmp = series.getValue(j).doubleValue();
- min = tmp < min ? tmp : min;
- max = tmp > max ? tmp : max;
- }
- if (subRange != null) {
- subRange = new Range(
- min < subRange.getLowerBound() ?
- min : subRange.getLowerBound(),
- max > subRange.getUpperBound() ?
- max : subRange.getUpperBound());
- }
- else {
- subRange = new Range(min, max);
- }
- }
-
- // Avoid merging NaNs, as they take min/max place forever.
- if (subRange == null ||
- Double.isNaN(subRange.getLowerBound()) ||
- Double.isNaN(subRange.getUpperBound())) {
- return;
- }
- if (range == null) {
- range = subRange;
- return;
- }
- range = Range.combine(range, subRange);
- }
-
- } // end of TimeseriesAxisDataset class
-
protected List<Marker> domainMarker;
protected List<Marker> valueMarker;
@@ -389,14 +270,14 @@
/**
- * This method creates new instances of TimeseriesAxisDataset.
+ * This method creates new instances of AxisDataset.
*
- * @param idx The symbol for the new TimeseriesAxisDataset.
+ * @param idx The symbol for the new AxisDataset.
*/
@Override
protected AxisDataset createAxisDataset(int idx) {
logger.debug("Create a new AxisDataset for index: " + idx);
- return new TimeseriesAxisDataset(idx);
+ return new AxisDataset(idx);
}
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/exports/WDifferencesCurveGenerator.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/WDifferencesCurveGenerator.java Mon Sep 23 11:37:13 2013 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,169 +0,0 @@
-/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde
- * Software engineering by Intevation GmbH
- *
- * This file is Free Software under the GNU AGPL (>=v3)
- * and comes with ABSOLUTELY NO WARRANTY! Check out the
- * documentation coming with Dive4Elements River for details.
- */
-
-package org.dive4elements.river.exports;
-
-import org.apache.log4j.Logger;
-
-import org.dive4elements.artifactdatabase.state.ArtifactAndFacet;
-import org.dive4elements.artifactdatabase.state.Facet;
-
-import org.dive4elements.river.artifacts.model.FacetTypes;
-import org.dive4elements.river.artifacts.model.WKms;
-
-import org.dive4elements.river.exports.process.BedDiffYearProcessor;
-import org.dive4elements.river.exports.process.BedDiffHeightYearProcessor;
-import org.dive4elements.river.exports.process.BedheightProcessor;
-import org.dive4elements.river.exports.process.Processor;
-import org.dive4elements.river.themes.ThemeDocument;
-
-import org.jfree.chart.JFreeChart;
-import org.jfree.chart.plot.XYPlot;
-
-
-/**
- * An OutGenerator that generates w differences curves.
- */
-public class WDifferencesCurveGenerator
-extends LongitudinalSectionGenerator
-implements FacetTypes
-{
- /** The logger that is used in this generator. */
- private static Logger logger = Logger.getLogger(WDifferencesCurveGenerator.class);
-
- public enum YAXIS {
- W(0),
- D(1),
- Q(2);
- protected int idx;
- private YAXIS(int c) {
- idx = c;
- }
- }
-
- /** Key for internationalized title of WDiff charts. */
- public final static String I18N_WDIFF_TITLE = "chart.w_differences.title";
-
- /** Default for internationalized title (when no translation found). */
- public final static String I18N_WDIFF_TITLE_DEFAULT = "Differences";
-
- public final static String I18N_WDIFF_SUBTITLE =
- "chart.w_differences.subtitle";
-
-
- @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();
- }
- };
- }
-
-
- /**
- * Get internationalized title for chart.
- * @return internationalized Chart title.
- */
- @Override
- public String getDefaultChartTitle() {
- return msg(I18N_WDIFF_TITLE, I18N_WDIFF_TITLE_DEFAULT);
- }
-
-
- @Override
- protected String getDefaultChartSubtitle() {
- return getRiverName();
- }
-
-
- /**
- * Gets key to look up internationalized String for the charts subtitle.
- * @return key to look up translated subtitle.
- */
- @Override
- protected String getChartSubtitleKey() {
- return I18N_WDIFF_SUBTITLE;
- }
-
-
- /** Handle additional facets (beddifferences). */
- @Override
- public void doOut(ArtifactAndFacet bundle, ThemeDocument attr, boolean visible) {
- super.doOut(bundle, attr, 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;
- }
-
- Processor bedp = new BedheightProcessor();
- Processor bdyProcessor = new BedDiffYearProcessor();
- Processor bdhyProcessor = new BedDiffHeightYearProcessor();
-
- if (bedp.canHandle(name)) {
- bedp.doOut(this, bundle, attr, visible, YAXIS.W.idx);
- }
- else if (bdyProcessor.canHandle(name)) {
- bdyProcessor.doOut(this, bundle, attr, visible, YAXIS.W.idx);
- }
- else if (bdhyProcessor.canHandle(name)) {
- bdhyProcessor.doOut(this, bundle, attr, visible, YAXIS.W.idx);
- }
- else {
- logger.warn("WDifferencesCurveGenerator.doOut: unknown facet type " + name);
- }
- }
-
-
- /**
- * Sets the zero base line visible.
- */
- @Override
- public JFreeChart generateChart() {
- JFreeChart chart = super.generateChart();
- if (chart != null && chart.getPlot() != null) {
- XYPlot plot = (XYPlot) chart.getPlot();
- plot.setRangeZeroBaselineVisible(true);
- }
- return chart;
- }
-
-
- /**
- * Get name of series (displayed in legend).
- * @return name of the series.
- */
- protected String getSeriesName(WKms wqkms, String mode) {
- String name = wqkms.getName();
- String prefix = (name != null && name.indexOf(mode) >= 0)
- ? null
- : mode;
-
- return (prefix != null && prefix.length() > 0)
- ? prefix + "(" + name +")"
- : name;
- }
-}
-// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/exports/WDifferencesCurveInfoGenerator.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/WDifferencesCurveInfoGenerator.java Mon Sep 23 11:37:13 2013 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,23 +0,0 @@
-/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde
- * Software engineering by Intevation GmbH
- *
- * This file is Free Software under the GNU AGPL (>=v3)
- * and comes with ABSOLUTELY NO WARRANTY! Check out the
- * documentation coming with Dive4Elements River for details.
- */
-
-package org.dive4elements.river.exports;
-
-
-/**
- * A ChartInfoGenerator that generates meta information for specific
- * w differences.
- */
-public class WDifferencesCurveInfoGenerator
-extends ChartInfoGenerator
-{
- public WDifferencesCurveInfoGenerator() {
- super(new WDifferencesCurveGenerator());
- }
-}
-// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/exports/WDifferencesExporter.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/WDifferencesExporter.java Mon Sep 23 11:37:13 2013 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/WDifferencesExporter.java Tue Sep 24 12:29:44 2013 +0200
@@ -19,8 +19,6 @@
import java.text.DateFormat;
import java.util.Locale;
-import org.w3c.dom.Document;
-
import org.apache.log4j.Logger;
import au.com.bytecode.opencsv.CSVWriter;
@@ -30,7 +28,6 @@
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JRException;
-import org.dive4elements.artifacts.CallContext;
import org.dive4elements.artifacts.CallMeta;
import org.dive4elements.artifacts.common.utils.Config;
@@ -68,16 +65,10 @@
/** The storage that contains all WKms objects for the different facets. */
protected List<WKms[]> data;
-
- public void init(Document request, OutputStream out, CallContext context) {
- logger.debug("WDifferencesExporter.init");
-
- super.init(request, out, context);
-
- this.data = new ArrayList<WKms[]>();
+ public WDifferencesExporter() {
+ data = new ArrayList<WKms[]>();
}
-
/**
* Genereate data in csv format.
*/
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/exports/WaterlevelExporter.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/WaterlevelExporter.java Mon Sep 23 11:37:13 2013 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/WaterlevelExporter.java Tue Sep 24 12:29:44 2013 +0200
@@ -21,8 +21,6 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import org.w3c.dom.Document;
-
import org.apache.log4j.Logger;
import au.com.bytecode.opencsv.CSVWriter;
@@ -35,7 +33,6 @@
import net.sf.jasperreports.engine.JRException;
import org.dive4elements.artifacts.Artifact;
-import org.dive4elements.artifacts.CallContext;
import org.dive4elements.artifacts.CallMeta;
import org.dive4elements.artifacts.common.utils.Config;
@@ -145,15 +142,10 @@
/** The storage that contains official fixings if available.*/
protected List<WQKms> officalFixings;
- public void init(Document request, OutputStream out, CallContext context) {
- logger.debug("WaterlevelExporter.init");
-
- super.init(request, out, context);
-
+ public WaterlevelExporter() {
data = new ArrayList<WQKms[]>();
}
-
@Override
public void generate()
throws IOException
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/exports/XYChartGenerator.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/XYChartGenerator.java Mon Sep 23 11:37:13 2013 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/XYChartGenerator.java Tue Sep 24 12:29:44 2013 +0200
@@ -46,6 +46,8 @@
import org.dive4elements.river.jfree.RiverAnnotation;
import org.dive4elements.river.jfree.StyledAreaSeriesCollection;
import org.dive4elements.river.jfree.StyledXYSeries;
+import org.dive4elements.river.jfree.AxisDataset;
+import org.dive4elements.river.jfree.AnnotationHelper;
import org.dive4elements.river.themes.ThemeDocument;
@@ -66,115 +68,6 @@
*/
public abstract class XYChartGenerator extends ChartGenerator {
- public static class XYAxisDataset implements AxisDataset {
- /** Symbolic integer, but also coding the priority (0 goes first). */
- protected int axisSymbol;
-
- /** List of assigned datasets (in order). */
- protected List<XYDataset> datasets;
-
- /** Range to use to include all given datasets. */
- protected Range range;
-
- /** Index of axis in plot. */
- protected int plotAxisIndex;
-
- /** Create AxisDataset. */
- public XYAxisDataset(int symb) {
- this.axisSymbol = symb;
- datasets = new ArrayList<XYDataset>();
- }
-
- /** Merge (or create given range with range so far (if any). */
- private void mergeRanges(Range subRange) {
- // Avoid merging NaNs, as they take min/max place forever.
- if (subRange == null ||
- Double.isNaN(subRange.getLowerBound()) ||
- Double.isNaN(subRange.getUpperBound())) {
- return;
- }
- if (range == null) {
- range = subRange;
- return;
- }
- range = Range.combine(range, subRange);
- }
-
-
- /** Add a dataset to internal list for this axis. */
- @Override
- public void addDataset(XYDataset dataset) {
- datasets.add(dataset);
- includeYRange(((XYSeriesCollection) dataset).getSeries(0));
- }
-
- /** Add a dataset, include its range. */
- public void addDataset(XYSeries series) {
- addDataset(new XYSeriesCollection(series));
- }
-
-
- /** Set Range for this axis. */
- @Override
- public void setRange(Range range) {
- this.range = range;
- }
-
-
- /** Get Range for this axis. */
- @Override
- public Range getRange() {
- return range;
- }
-
-
- /** Get Array of Datasets. */
- @Override
- public XYDataset[] getDatasets() {
- return datasets.toArray(new XYDataset[datasets.size()]);
- }
-
-
- /** Add a Dataset that describes an area. */
- public void addArea(StyledAreaSeriesCollection series) {
- this.datasets.add(series);
- List<?> allSeries = series.getSeries();
- /* We do not include the bounds/ranges, if the area includes
- * points at "infinity"/BIG_DOUBLE_VALUE, the charts extents are
- * expanded to include these very small/big value.
- * This is especially used when showing "area above axis". */
- }
-
- /** True if to be rendered as area. */
- @Override
- public boolean isArea(XYDataset series) {
- return (series instanceof StyledAreaSeriesCollection);
- }
-
- /** Adjust range to include given dataset. */
- public void includeYRange(XYSeries dataset) {
- mergeRanges(new Range(dataset.getMinY(), dataset.getMaxY()));
- }
-
- /** True if no datasets given. */
- @Override
- public boolean isEmpty() {
- return this.datasets.isEmpty();
- }
-
- /** Set the 'real' axis index that this axis is mapped to. */
- @Override
- public void setPlotAxisIndex(int axisIndex) {
- this.plotAxisIndex = axisIndex;
- }
-
- /** Get the 'real' axis index that this axis is mapped to. */
- @Override
- public int getPlotAxisIndex() {
- return this.plotAxisIndex;
- }
- } // class AxisDataset
-
/** Enumerator over existing axes. */
@Override
protected abstract YAxisWalker getYAxisWalker();
@@ -258,7 +151,8 @@
//debugAxis(plot);
// These have to go after the autozoom.
- addAnnotationsToRenderer(plot);
+ AnnotationHelper.addAnnotationsToRenderer(annotations, plot,
+ getChartSettings(), datasets);
// Add a logo (maybe).
addLogo(plot);
@@ -415,8 +309,8 @@
@Override
protected AxisDataset createAxisDataset(int idx) {
- logger.debug("Create new XYAxisDataset for index: " + idx);
- return new XYAxisDataset(idx);
+ logger.debug("Create new AxisDataset for index: " + idx);
+ return new AxisDataset(idx);
}
@@ -481,7 +375,7 @@
return;
}
- XYAxisDataset axisDataset = (XYAxisDataset) getAxisDataset(index);
+ AxisDataset axisDataset = (AxisDataset) getAxisDataset(index);
if (visible) {
axisDataset.addArea(area);
@@ -510,13 +404,6 @@
addAxisDataset(new XYSeriesCollection(series), index, visible);
- XYAxisDataset axisDataset = (XYAxisDataset) getAxisDataset(index);
-
- if (!visible) {
- // Do this also when not visible to have axis scaled by default such
- // that every data-point could be seen (except for annotations).
- axisDataset.includeYRange(series);
- }
}
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/exports/fixings/DeltaWtExporter.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/fixings/DeltaWtExporter.java Mon Sep 23 11:37:13 2013 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/fixings/DeltaWtExporter.java Tue Sep 24 12:29:44 2013 +0200
@@ -10,7 +10,6 @@
import au.com.bytecode.opencsv.CSVWriter;
-import org.dive4elements.artifacts.CallContext;
import org.dive4elements.artifacts.CallMeta;
import org.dive4elements.river.artifacts.model.CalculationResult;
@@ -39,8 +38,6 @@
import org.apache.log4j.Logger;
-import org.w3c.dom.Document;
-
/** Exports fixation analysis deltaw(t) computation results to csv. */
public class DeltaWtExporter
extends AbstractExporter
@@ -101,10 +98,7 @@
protected List<KMIndex<QWD[]>> referenceEvents;
- @Override
- public void init(Document request, OutputStream out, CallContext context) {
- log.debug("DeltaWtExporter.init");
- super.init(request, out, context);
+ public DeltaWtExporter() {
analysisPeriods = new ArrayList<KMIndex<AnalysisPeriod []>>();
referenceEvents = new ArrayList<KMIndex<QWD[]>>();
}
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/exports/fixings/FixChartGenerator.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/fixings/FixChartGenerator.java Mon Sep 23 11:37:13 2013 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/fixings/FixChartGenerator.java Tue Sep 24 12:29:44 2013 +0200
@@ -33,8 +33,8 @@
"/art:action/art:attributes/art:currentKm/@art:km";
@Override
- public void init(Document request, OutputStream out, CallContext context) {
- super.init(request, out, context);
+ public void init(String outName, Document request, OutputStream out, CallContext context) {
+ super.init(outName, request, out, context);
Double currentKm = getCurrentKmFromRequest(request);
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/exports/fixings/FixDeltaWtGenerator.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/fixings/FixDeltaWtGenerator.java Mon Sep 23 11:37:13 2013 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/fixings/FixDeltaWtGenerator.java Tue Sep 24 12:29:44 2013 +0200
@@ -462,8 +462,8 @@
@Override
- public void init(Document request, OutputStream out, CallContext context) {
- super.init(request, out, context);
+ public void init(String outName, Document request, OutputStream out, CallContext context) {
+ super.init(outName, request, out, context);
Double currentKm = FixChartGenerator.getCurrentKmFromRequest(request);
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/exports/fixings/FixLongitudinalSectionGenerator.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/fixings/FixLongitudinalSectionGenerator.java Mon Sep 23 11:37:13 2013 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/fixings/FixLongitudinalSectionGenerator.java Tue Sep 24 12:29:44 2013 +0200
@@ -15,7 +15,6 @@
import org.dive4elements.artifactdatabase.state.ArtifactAndFacet;
import org.dive4elements.river.artifacts.D4EArtifact;
import org.dive4elements.river.artifacts.model.FacetTypes;
-import org.dive4elements.river.artifacts.model.WKms;
import org.dive4elements.river.artifacts.model.WQKms;
import org.dive4elements.river.artifacts.model.fixings.AnalysisPeriod;
import org.dive4elements.river.artifacts.model.fixings.QWD;
@@ -28,7 +27,6 @@
import org.dive4elements.river.jfree.StyledAreaSeriesCollection;
import org.dive4elements.river.jfree.StyledXYSeries;
import org.dive4elements.river.themes.ThemeDocument;
-import org.dive4elements.river.utils.DataUtil;
import org.dive4elements.river.utils.KMIndex;
import org.dive4elements.river.utils.RiverUtils;
import org.jfree.chart.plot.Marker;
@@ -147,38 +145,7 @@
addAxisSeries(series, YAXIS.Q.idx, visible);
- if (needInvertAxis(wqkms)) {
- setInverted(true);
- }
- }
-
- /**
- * This method determines - taking JFreeCharts auto x value ordering into
- * account - if the x axis need to be inverted. Waterlines in these charts
- * should decrease.
- *
- * @param wkms The data object that stores the x and y values used for this
- * chart.
- */
- public boolean needInvertAxis(WKms wkms) {
- boolean wsUp = wkms.guessWaterIncreasing();
- boolean kmUp = DataUtil.guessWaterIncreasing(wkms.allKms());
- boolean inv = (wsUp && kmUp) || (!wsUp && !kmUp);
-
- int size = wkms.size();
-
- if (logger.isDebugEnabled()) {
- logger.debug("(Wkms)Values : " + size);
- if (size > 0) {
- logger.debug("Start km: " + wkms.getKm(0));
- logger.debug("End km: " + wkms.getKm(size-1));
- }
- logger.debug("wsUp: " + wsUp);
- logger.debug("kmUp: " + kmUp);
- logger.debug("inv: " + inv);
- }
-
- return inv;
+ setInverted(wqkms.guessRTLData());
}
@SuppressWarnings("unchecked")
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/exports/fixings/ParametersExporter.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/fixings/ParametersExporter.java Mon Sep 23 11:37:13 2013 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/fixings/ParametersExporter.java Tue Sep 24 12:29:44 2013 +0200
@@ -10,8 +10,6 @@
import au.com.bytecode.opencsv.CSVWriter;
-import org.dive4elements.artifacts.CallContext;
-
import org.dive4elements.river.artifacts.model.CalculationResult;
import org.dive4elements.river.artifacts.model.Parameters;
@@ -31,8 +29,6 @@
import org.apache.log4j.Logger;
-import org.w3c.dom.Document;
-
public class ParametersExporter
extends AbstractExporter
{
@@ -40,10 +36,7 @@
protected List<Parameters> parametersList;
- @Override
- public void init(Document request, OutputStream out, CallContext context) {
- log.debug("ParametersExporter.init");
- super.init(request, out, context);
+ public ParametersExporter() {
parametersList = new ArrayList<Parameters>();
}
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/exports/minfo/BedDifferenceEpochGenerator.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/minfo/BedDifferenceEpochGenerator.java Mon Sep 23 11:37:13 2013 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/minfo/BedDifferenceEpochGenerator.java Tue Sep 24 12:29:44 2013 +0200
@@ -28,7 +28,6 @@
import org.dive4elements.river.jfree.RiverAnnotation;
import org.dive4elements.river.jfree.StyledXYSeries;
import org.dive4elements.river.themes.ThemeDocument;
-import org.dive4elements.river.utils.DataUtil;
import org.dive4elements.river.utils.RiverUtils;
@@ -257,7 +256,7 @@
StyledSeriesBuilder.addPoints(series, wkms);
addAxisSeries(series, YAXIS.D.idx, visible);
- if (DataUtil.guessWaterIncreasing(wkms.allWs())) {
+ if (wkms.guessWaterIncreasing()) {
setInverted(true);
}
}
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/exports/minfo/BedDifferenceExporter.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/minfo/BedDifferenceExporter.java Mon Sep 23 11:37:13 2013 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/minfo/BedDifferenceExporter.java Tue Sep 24 12:29:44 2013 +0200
@@ -27,7 +27,6 @@
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JRException;
-import org.dive4elements.artifacts.CallContext;
import org.dive4elements.artifacts.CallMeta;
import org.dive4elements.river.artifacts.D4EArtifact;
import org.dive4elements.river.artifacts.access.BedDifferencesAccess;
@@ -40,11 +39,8 @@
import org.dive4elements.river.utils.Formatter;
import org.dive4elements.river.utils.RiverUtils;
-import org.w3c.dom.Document;
-
import au.com.bytecode.opencsv.CSVWriter;
-
public class BedDifferenceExporter
extends AbstractExporter
{
@@ -70,10 +66,7 @@
private BedDifferencesResult[] results;
- @Override
- public void init(Document request, OutputStream out, CallContext context) {
- logger.debug("init");
- super.init(request, out, context);
+ public BedDifferenceExporter() {
results = new BedDifferencesResult[0];
}
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/exports/minfo/BedDifferenceYearGenerator.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/minfo/BedDifferenceYearGenerator.java Mon Sep 23 11:37:13 2013 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/minfo/BedDifferenceYearGenerator.java Tue Sep 24 12:29:44 2013 +0200
@@ -28,7 +28,6 @@
import org.dive4elements.river.jfree.RiverAnnotation;
import org.dive4elements.river.jfree.StyledXYSeries;
import org.dive4elements.river.themes.ThemeDocument;
-import org.dive4elements.river.utils.DataUtil;
import org.dive4elements.river.utils.RiverUtils;
@@ -234,7 +233,7 @@
StyledSeriesBuilder.addPoints(series, wkms);
addAxisSeries(series, YAXIS.D.idx, visible);
- if (DataUtil.guessWaterIncreasing(wkms.allWs())) {
+ if (wkms.guessWaterIncreasing()) {
setInverted(true);
}
}
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/exports/minfo/BedQualityExporter.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/minfo/BedQualityExporter.java Mon Sep 23 11:37:13 2013 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/minfo/BedQualityExporter.java Tue Sep 24 12:29:44 2013 +0200
@@ -19,10 +19,8 @@
import java.util.List;
import org.apache.log4j.Logger;
-import org.w3c.dom.Document;
import au.com.bytecode.opencsv.CSVWriter;
-import org.dive4elements.artifacts.CallContext;
import org.dive4elements.river.artifacts.model.CalculationResult;
import org.dive4elements.river.artifacts.model.minfo.BedDiameterResult;
import org.dive4elements.river.artifacts.model.minfo.BedParametersResult;
@@ -56,10 +54,7 @@
private BedQualityResult[] results;
- @Override
- public void init(Document request, OutputStream out, CallContext context) {
- logger.debug("BedQualityExporter.init");
- super.init(request, out, context);
+ public BedQualityExporter() {
results = new BedQualityResult[0];
}
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/exports/minfo/SedimentLoadExporter.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/minfo/SedimentLoadExporter.java Mon Sep 23 11:37:13 2013 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/minfo/SedimentLoadExporter.java Tue Sep 24 12:29:44 2013 +0200
@@ -17,12 +17,8 @@
import java.text.NumberFormat;
-import org.w3c.dom.Document;
-
import org.apache.log4j.Logger;
-import org.dive4elements.artifacts.CallContext;
-
import org.dive4elements.river.artifacts.model.CalculationResult;
import org.dive4elements.river.artifacts.model.minfo.SedimentLoad;
import org.dive4elements.river.artifacts.model.minfo.SedimentLoadFraction;
@@ -78,17 +74,9 @@
/** Empty constructor. */
public SedimentLoadExporter() {
- }
-
- /** Trivial init. */
- @Override
- public void init(Document request, OutputStream out, CallContext context) {
- super.init(request, out, context);
- logger.debug("init");
results = new SedimentLoadResult[0];
}
-
/** Process all stored data and write csv. */
@Override
protected void writeCSVData(CSVWriter writer) throws IOException {
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/exports/minfo/SedimentLoadLSGenerator.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/minfo/SedimentLoadLSGenerator.java Mon Sep 23 11:37:13 2013 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/minfo/SedimentLoadLSGenerator.java Tue Sep 24 12:29:44 2013 +0200
@@ -33,7 +33,6 @@
import org.dive4elements.river.jfree.RiverAnnotation;
import org.dive4elements.river.jfree.StyledXYSeries;
import org.dive4elements.river.themes.ThemeDocument;
-import org.dive4elements.river.utils.DataUtil;
/** Generator for Longitudinal Sections of SedimentLoad-Calculations. */
@@ -355,7 +354,7 @@
StyledSeriesBuilder.addPoints(series, wkms);
addAxisSeries(series, YAXIS.D.idx, visible);
- if (DataUtil.guessWaterIncreasing(wkms.allWs())) {
+ if (wkms.guessWaterIncreasing()) {
setInverted(true);
}
}
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/exports/process/AnnotationProcessor.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/process/AnnotationProcessor.java Tue Sep 24 12:29:44 2013 +0200
@@ -0,0 +1,84 @@
+/* Copyright (C) 2013 by Bundesanstalt für Gewässerkunde
+ * Software engineering by Intevation GmbH
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+
+package org.dive4elements.river.exports.process;
+
+import org.apache.log4j.Logger;
+
+import org.dive4elements.artifactdatabase.state.ArtifactAndFacet;
+import org.dive4elements.artifacts.CallContext;
+import org.dive4elements.river.artifacts.model.FacetTypes;
+import org.dive4elements.river.exports.DiagramGenerator;
+import org.dive4elements.river.exports.XYChartGenerator;
+import org.dive4elements.river.jfree.RiverAnnotation;
+import org.dive4elements.river.themes.ThemeDocument;
+
+/**
+ * Add data to chart/generator.
+ *
+ */
+public class AnnotationProcessor extends DefaultProcessor {
+
+ /** Private logger. */
+ private static final Logger logger =
+ Logger.getLogger(AnnotationProcessor.class);
+
+ @Override
+ public void doOut(
+ DiagramGenerator generator,
+ ArtifactAndFacet bundle,
+ ThemeDocument theme,
+ boolean visible) {
+ if (!visible) {
+ // Nothing to do
+ return;
+ }
+ CallContext context = generator.getCallContext();
+ if (!(bundle.getData(context) instanceof RiverAnnotation)) {
+ // Just a bit defensive should not happen
+ logger.error("Incompatible facet in doOut");
+ return;
+ }
+ RiverAnnotation ra = (RiverAnnotation)bundle.getData(context);
+ ra.setTheme(theme);
+ ra.setLabel(bundle.getFacetDescription());
+ generator.addAnnotations(ra);
+ }
+
+ @Override
+ public void doOut(
+ XYChartGenerator generator,
+ ArtifactAndFacet bundle,
+ ThemeDocument theme,
+ boolean visible,
+ int index)
+ {
+ if (!visible) {
+ // Nothing to do
+ return;
+ }
+ CallContext context = generator.getCallContext();
+ if (!(bundle.getData(context) instanceof RiverAnnotation)) {
+ // Just a bit defensive should not happen
+ logger.error("Incompatible facet in doOut");
+ return;
+ }
+ RiverAnnotation ra = (RiverAnnotation)bundle.getData(context);
+ ra.setTheme(theme);
+ ra.setLabel(bundle.getFacetDescription());
+ generator.addAnnotations(ra);
+ }
+
+ @Override
+ public boolean canHandle(String facetType) {
+ if (facetType == null) {
+ return false;
+ }
+ return facetType.equals(FacetTypes.LONGITUDINAL_ANNOTATION);
+ }
+}
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/exports/process/AreaProcessor.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/process/AreaProcessor.java Tue Sep 24 12:29:44 2013 +0200
@@ -0,0 +1,154 @@
+/* Copyright (C) 2013 by Bundesanstalt für Gewässerkunde
+ * Software engineering by Intevation GmbH
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+
+
+package org.dive4elements.river.exports.process;
+
+import org.apache.log4j.Logger;
+
+
+import org.dive4elements.artifactdatabase.state.ArtifactAndFacet;
+import org.dive4elements.artifacts.CallContext;
+
+import org.dive4elements.river.artifacts.geom.Lines;
+import org.dive4elements.river.artifacts.model.WKms;
+import org.dive4elements.river.artifacts.model.WQKms;
+import org.dive4elements.river.artifacts.model.AreaFacet;
+import org.dive4elements.river.artifacts.model.FacetTypes;
+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;
+
+import org.jfree.data.xy.XYSeries;
+
+public class AreaProcessor extends DefaultProcessor {
+
+ private static final Logger logger = Logger.getLogger(ManualPointsProcessor.class);
+
+ @Override
+ public void doOut(
+ DiagramGenerator generator,
+ ArtifactAndFacet bundle,
+ ThemeDocument theme,
+ boolean visible) {
+ CallContext context = generator.getCallContext();
+ String seriesName = bundle.getFacetDescription();
+ StyledAreaSeriesCollection area = new StyledAreaSeriesCollection(theme);
+
+ logger.debug("Area Processor processing: " + seriesName);
+
+ AreaFacet.Data data = (AreaFacet.Data) bundle.getData(context);
+
+ XYSeries up = null;
+ XYSeries down = null;
+
+ if (data.getUpperData() != null) {
+ up = new StyledXYSeries(seriesName, false, theme);
+ if (data.getUpperData() instanceof WQKms) {
+ if (FacetTypes.IS.Q(data.getRootFacetName())) {
+ StyledSeriesBuilder.addPointsKmQ(up, (WQKms) data.getUpperData());
+ }
+ else {
+ StyledSeriesBuilder.addPoints(up, (WKms) data.getUpperData());
+ }
+ }
+ else if (data.getUpperData() instanceof double[][]) {
+ StyledSeriesBuilder.addPoints(up, (double [][]) data.getUpperData(), false);
+ }
+ else if (data.getUpperData() instanceof WKms) {
+ StyledSeriesBuilder.addPoints(up, (WKms) data.getUpperData());
+ }
+ else if (data.getUpperData() instanceof Lines.LineData) {
+ StyledSeriesBuilder.addPoints(up, ((Lines.LineData) data.getUpperData()).points, false);
+ }
+ else {
+ logger.error("Do not know how to deal with (up) area info from: "
+ + data.getUpperData());
+ }
+ }
+
+ // TODO Depending on style, the area (e.g. 20m^2) should be added as annotation.
+
+ if (data.getLowerData() != null) {
+ // TODO: Sort this out: when the two series have the same name,
+ // the renderer (or anything in between) will not work correctly.
+ down = new StyledXYSeries(seriesName + " ", false, theme);
+ if (data.getLowerData() instanceof WQKms) {
+ if (FacetTypes.IS.Q(data.getRootFacetName())) {
+ StyledSeriesBuilder.addPointsKmQ(down, (WQKms) data.getLowerData());
+ }
+ else {
+ StyledSeriesBuilder.addPoints(down, (WQKms) data.getLowerData());
+ }
+ }
+ else if (data.getLowerData() instanceof double[][]) {
+ StyledSeriesBuilder.addPoints(down, (double[][]) data.getLowerData(), false);
+ }
+ else if (data.getLowerData() instanceof WKms) {
+ StyledSeriesBuilder.addPoints(down, (WKms) data.getLowerData());
+ }
+ else if (data.getLowerData() instanceof Lines.LineData) {
+ StyledSeriesBuilder.addPoints(down, ((Lines.LineData) data.getLowerData()).points, false);
+ }
+ else {
+ logger.error("Do not know how to deal with (down) area info from: "
+ + data.getLowerData());
+ }
+ }
+
+ if (up == null && down != null) {
+ area.setMode(StyledAreaSeriesCollection.FILL_MODE.ABOVE);
+ down.setKey(seriesName);
+ area.addSeries(down);
+ area.addSeries(StyledSeriesBuilder.createGroundAtInfinity(down));
+ }
+ else if (up != null && down == null) {
+ area.setMode(StyledAreaSeriesCollection.FILL_MODE.UNDER);
+ area.addSeries(up);
+ area.addSeries(StyledSeriesBuilder.createGroundAtInfinity(up));
+ }
+ else if (up != null && down != null) {
+ if (data.doPaintBetween()) {
+ area.setMode(StyledAreaSeriesCollection.FILL_MODE.BETWEEN);
+ }
+ else {
+ area.setMode(StyledAreaSeriesCollection.FILL_MODE.ABOVE);
+ }
+ area.addSeries(up);
+ area.addSeries(down);
+ }
+
+ /* Decide axis name based on facet name */
+ generator.addAreaSeries(area,
+ axisNameForFacet(data.getRootFacetName()), visible);
+ }
+
+ /** Look up the axis identifier for a given facet type. */
+ private String axisNameForFacet(String facetName) {
+ if (FacetTypes.IS.W(facetName)) {
+ return "W";
+ }
+ else if (FacetTypes.IS.Q(facetName)) {
+ return "Q";
+ }
+ else {
+ logger.warn("Could not find axis for facet " + facetName);
+ return "W";
+ }
+ }
+
+ @Override
+ public boolean canHandle(String facetType) {
+ if (facetType == null) {
+ return false;
+ }
+ return FacetTypes.IS.AREA(facetType);
+ }
+}
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/exports/process/BedDiffHeightYearProcessor.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/process/BedDiffHeightYearProcessor.java Mon Sep 23 11:37:13 2013 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/process/BedDiffHeightYearProcessor.java Tue Sep 24 12:29:44 2013 +0200
@@ -16,12 +16,14 @@
import org.dive4elements.river.artifacts.model.FacetTypes;
import org.dive4elements.river.artifacts.model.minfo.BedDiffYearResult;
import org.dive4elements.river.exports.StyledSeriesBuilder;
+import org.dive4elements.river.exports.DiagramGenerator;
import org.dive4elements.river.exports.XYChartGenerator;
import org.dive4elements.river.jfree.StyledXYSeries;
import org.dive4elements.river.themes.ThemeDocument;
-public class BedDiffHeightYearProcessor implements Processor, FacetTypes {
+public class BedDiffHeightYearProcessor
+extends DefaultProcessor implements FacetTypes {
private final static Logger logger =
Logger.getLogger(BedDiffHeightYearProcessor.class);
@@ -30,21 +32,43 @@
@Override
public void doOut(
+ DiagramGenerator generator,
+ ArtifactAndFacet bundle,
+ ThemeDocument theme,
+ boolean visible) {
+ CallContext context = generator.getCallContext();
+ Object data = bundle.getData(context);
+ if (data instanceof BedDiffYearResult) {
+ BedDiffYearResult bData = (BedDiffYearResult) data;
+ XYSeries series = new StyledXYSeries(bundle.getFacetDescription(), theme);
+ StyledSeriesBuilder.addPoints(series, bData.getHeightPerYearData(), false, GAP_TOLERANCE);
+
+ generator.addAxisSeries(series, axisName, visible);
+ return;
+ }
+ // Should not happen if canHandle is correct
+ logger.error("Can't process " + data.getClass().getName() + " objects");
+ }
+
+ @Override
+ public void doOut(
XYChartGenerator generator,
- ArtifactAndFacet aandf,
+ ArtifactAndFacet bundle,
ThemeDocument theme,
boolean visible,
int index
) {
CallContext context = generator.getCallContext();
- Object data = aandf.getData(context);
+ Object data = bundle.getData(context);
if (data instanceof BedDiffYearResult) {
- doBedDifferenceYearOut(
- generator,
- (BedDiffYearResult) data,
- aandf, theme, visible, index);
+ BedDiffYearResult bData = (BedDiffYearResult) data;
+ XYSeries series = new StyledXYSeries(bundle.getFacetDescription(), theme);
+ StyledSeriesBuilder.addPoints(series, bData.getHeightPerYearData(), false, GAP_TOLERANCE);
+
+ generator.addAxisSeries(series, index, visible);
return;
}
+ // Should not happen if canHandle is correct
logger.error("Can't process " + data.getClass().getName() + " objects");
}
@@ -58,12 +82,12 @@
protected void doBedDifferenceYearOut(XYChartGenerator generator,
BedDiffYearResult data,
- ArtifactAndFacet aandf,
+ ArtifactAndFacet bundle,
ThemeDocument theme,
boolean visible,
int axidx) {
- XYSeries series = new StyledXYSeries(aandf.getFacetDescription(), theme);
+ XYSeries series = new StyledXYSeries(bundle.getFacetDescription(), theme);
StyledSeriesBuilder.addPoints(series, data.getHeightPerYearData(), false, GAP_TOLERANCE);
generator.addAxisSeries(series, axidx, visible);
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/exports/process/BedDiffYearProcessor.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/process/BedDiffYearProcessor.java Mon Sep 23 11:37:13 2013 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/process/BedDiffYearProcessor.java Tue Sep 24 12:29:44 2013 +0200
@@ -17,11 +17,13 @@
import org.dive4elements.river.artifacts.model.minfo.BedDiffYearResult;
import org.dive4elements.river.exports.StyledSeriesBuilder;
import org.dive4elements.river.exports.XYChartGenerator;
+import org.dive4elements.river.exports.DiagramGenerator;
import org.dive4elements.river.jfree.StyledXYSeries;
import org.dive4elements.river.themes.ThemeDocument;
-public class BedDiffYearProcessor implements Processor, FacetTypes {
+public class BedDiffYearProcessor
+extends DefaultProcessor implements FacetTypes {
private final static Logger logger =
Logger.getLogger(BedDiffYearProcessor.class);
@@ -30,23 +32,65 @@
@Override
public void doOut(
+ DiagramGenerator generator,
+ ArtifactAndFacet bundle,
+ ThemeDocument theme,
+ boolean visible) {
+ CallContext context = generator.getCallContext();
+ Object data = bundle.getData(context);
+ if (data instanceof BedDiffYearResult) {
+ String facetType = bundle.getFacetName();
+ BedDiffYearResult bData = (BedDiffYearResult) data;
+
+ double[][] points;
+ if (BED_DIFFERENCE_YEAR_HEIGHT1.equals(facetType)) {
+ points = bData.getHeights1Data();
+ } else {
+ points = bData.getHeights2Data();
+ }
+ XYSeries series = new StyledXYSeries(bundle.getFacetDescription(), theme);
+ StyledSeriesBuilder.addPointsFactorY(series,
+ points,
+ false,
+ GAP_TOLERANCE,
+ 100d);
+
+ generator.addAxisSeries(series, axisName, visible);
+
+ return;
+ }
+ logger.error("Can't process " + data.getClass().getName() + " objects");
+ }
+
+ @Override
+ public void doOut(
XYChartGenerator generator,
- ArtifactAndFacet aandf,
+ ArtifactAndFacet bundle,
ThemeDocument theme,
boolean visible,
int axidx
) {
CallContext context = generator.getCallContext();
- Object data = aandf.getData(context);
+ Object data = bundle.getData(context);
if (data instanceof BedDiffYearResult) {
- String facetType = aandf.getFacetName();
- int index =
- (BED_DIFFERENCE_YEAR_HEIGHT1.equals(facetType)
- || BED_DIFFERENCE_YEAR_HEIGHT1_FILTERED.equals(facetType))?0:1;
- doBedDifferenceHeightsOut(
- generator,
- (BedDiffYearResult) data,
- aandf, theme, visible, index, axidx);
+ String facetType = bundle.getFacetName();
+ BedDiffYearResult bData = (BedDiffYearResult) data;
+
+ double[][] points;
+ if (BED_DIFFERENCE_YEAR_HEIGHT1.equals(facetType)) {
+ points = bData.getHeights1Data();
+ } else {
+ points = bData.getHeights2Data();
+ }
+ XYSeries series = new StyledXYSeries(bundle.getFacetDescription(), theme);
+ StyledSeriesBuilder.addPointsFactorY(series,
+ points,
+ false,
+ GAP_TOLERANCE,
+ 100d);
+
+ generator.addAxisSeries(series, axidx, visible);
+
return;
}
logger.error("Can't process " + data.getClass().getName() + " objects");
@@ -60,33 +104,5 @@
|| BED_DIFFERENCE_YEAR_HEIGHT1_FILTERED.equals(facetType)
|| BED_DIFFERENCE_YEAR_HEIGHT2_FILTERED.equals(facetType);
}
-
- private void doBedDifferenceHeightsOut(
- XYChartGenerator generator,
- BedDiffYearResult data,
- ArtifactAndFacet bundle,
- ThemeDocument attr,
- boolean visible,
- int idx,
- int axidx) {
- logger.debug("doBedDifferenceHeightsOut()");
-
- XYSeries series = new StyledXYSeries(bundle.getFacetDescription(), attr);
- double[][] points;
- if (idx == 0) {
- points = data.getHeights1Data();
- }
- else {
- points = data.getHeights2Data();
- }
-
- StyledSeriesBuilder.addPointsFactorY(series,
- points,
- false,
- GAP_TOLERANCE,
- 100d);
-
- generator.addAxisSeries(series, axidx, visible);
- }
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/exports/process/BedheightProcessor.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/process/BedheightProcessor.java Mon Sep 23 11:37:13 2013 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/process/BedheightProcessor.java Tue Sep 24 12:29:44 2013 +0200
@@ -17,11 +17,12 @@
import org.dive4elements.artifacts.CallContext;
import org.dive4elements.river.artifacts.model.minfo.BedHeightSingle;
import org.dive4elements.river.exports.XYChartGenerator;
+import org.dive4elements.river.exports.DiagramGenerator;
import org.dive4elements.river.jfree.StyledXYSeries;
import org.dive4elements.river.model.BedHeightSingleValue;
import org.dive4elements.river.themes.ThemeDocument;
-public class BedheightProcessor implements Processor {
+public class BedheightProcessor extends DefaultProcessor {
private final static Logger logger =
Logger.getLogger(BedheightProcessor.class);
@@ -30,34 +31,66 @@
@Override
public void doOut(
+ DiagramGenerator generator,
+ ArtifactAndFacet bundle,
+ ThemeDocument theme,
+ boolean visible) {
+ CallContext context = generator.getCallContext();
+ Object data = bundle.getData(context);
+ XYSeries series = new StyledXYSeries(bundle.getFacetDescription(),
+ theme);
+ if (data instanceof BedHeightSingle) {
+ BedHeightSingle bData = (BedHeightSingle)data;
+ double[] width = bData.getMorphWidths();
+ double[] stations = bData.getStations().toNativeArray();
+
+ logger.debug("doBedheightSingleOut");
+
+ for (int i = 0; i < width.length; i++) {
+ series.add(stations[i], width[i], false);
+ }
+ } else if (data instanceof List<?>) {
+ List<BedHeightSingleValue> bData = (List<BedHeightSingleValue>)data;
+
+ logger.debug("doBedheightSingleValueOut");
+
+ for(BedHeightSingleValue bvalue: bData) {
+ series.add(bvalue.getStation(), bvalue.getSoundingWidth());
+ }
+ }
+ generator.addAxisSeries(series, axisName, visible);
+ }
+
+ @Override
+ public void doOut(
XYChartGenerator generator,
- ArtifactAndFacet aandf,
+ ArtifactAndFacet bundle,
ThemeDocument theme,
boolean visible,
int index
) {
CallContext context = generator.getCallContext();
- Object data = aandf.getData(context);
+ Object data = bundle.getData(context);
+ XYSeries series = new StyledXYSeries(bundle.getFacetDescription(),
+ theme);
if (data instanceof BedHeightSingle) {
- doBedheightSingleOut(generator, aandf, theme, index, visible,
- (BedHeightSingle)data);
- }
- else if (data instanceof List<?>) {
- doBedheightSingeValuesOut(generator, aandf, theme, index, visible,
- (List<BedHeightSingleValue>)data);
- }
- logger.error("Can't process " + data.getClass().getName() + " objects");
- }
+ BedHeightSingle bData = (BedHeightSingle)data;
+ double[] width = bData.getMorphWidths();
+ double[] stations = bData.getStations().toNativeArray();
- private void doBedheightSingeValuesOut(XYChartGenerator generator,
- ArtifactAndFacet aandf, ThemeDocument theme, int index, boolean visible,
- List<BedHeightSingleValue> data) {
- logger.debug("doBedheightSingeValuesOut");
+ logger.debug("doBedheightSingleOut");
- XYSeries series = new StyledXYSeries(aandf.getFacetDescription(),
- theme);
- for(BedHeightSingleValue bvalue: data) {
- series.add(bvalue.getStation(), bvalue.getSoundingWidth());
+ for (int i = 0; i < width.length; i++) {
+ series.add(stations[i], width[i], false);
+ }
+ } else if (data instanceof List<?>) {
+ List<BedHeightSingleValue> bData = (List<BedHeightSingleValue>)data;
+
+ logger.debug("doBedheightSingleValueOut");
+
+ for(BedHeightSingleValue bvalue: bData) {
+ series.add(bvalue.getStation(), bvalue.getSoundingWidth());
+ }
}
generator.addAxisSeries(series, index, visible);
}
@@ -66,22 +99,4 @@
public boolean canHandle(String facettype) {
return BEDHEIGHT.equals(facettype);
}
-
- public void doBedheightSingleOut(XYChartGenerator generator,
- ArtifactAndFacet aandf, ThemeDocument theme, int index, boolean visible,
- BedHeightSingle data) {
- double[] width = data.getMorphWidths();
- double[] stations = data.getStations().toNativeArray();
-
- logger.debug("doBedheightSingleOut");
-
- XYSeries series = new StyledXYSeries(aandf.getFacetDescription(),
- theme);
-
- for (int i = 0; i < width.length; i++) {
- series.add(stations[i], width[i], false);
- }
-
- generator.addAxisSeries(series, index, visible);
- }
}
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/exports/process/DefaultProcessor.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/process/DefaultProcessor.java Tue Sep 24 12:29:44 2013 +0200
@@ -0,0 +1,75 @@
+/* Copyright (C) 2013 by Bundesanstalt für Gewässerkunde
+ * Software engineering by Intevation GmbH
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+
+package org.dive4elements.river.exports.process;
+
+import org.dive4elements.artifactdatabase.state.ArtifactAndFacet;
+import org.dive4elements.river.exports.XYChartGenerator;
+import org.dive4elements.river.exports.DiagramGenerator;
+import org.dive4elements.river.themes.ThemeDocument;
+
+/** Dummy implementation for the Processor interface.
+ */
+public class DefaultProcessor implements Processor {
+
+ protected String axisName;
+
+ public void setAxisName(String axisName) {
+ this.axisName = axisName;
+ }
+
+ public String getAxisName() {
+ return axisName;
+ }
+
+ /**
+ * Processes data to generate e.g. a chart.
+ *
+ * @param generator XYChartGenerator to add output on.
+ * @param bundle The artifact and facet
+ * @param theme The theme that contains styling information.
+ * @param visible The visibility of the curve.
+ * @param index The index of the curve
+ */
+ @Override
+ public void doOut(
+ XYChartGenerator generator,
+ ArtifactAndFacet bundle,
+ ThemeDocument theme,
+ boolean visible,
+ int index) {
+ return;
+ }
+
+ @Override
+ public void doOut(
+ DiagramGenerator generator,
+ ArtifactAndFacet bundle,
+ ThemeDocument theme,
+ boolean visible) {
+ return;
+ }
+
+ @Override
+ public String getAxisLabel(DiagramGenerator generator) {
+ return "Please overwrite me in the implementation";
+ }
+
+
+ /**
+ * Returns true if the Processor class is able to generate output for a facet type
+ *
+ * @param facettype Name of the facet type
+ * @return true if the facettype can be processed
+ */
+ @Override
+ public boolean canHandle(String facettype)
+ {
+ return false;
+ }
+}
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/exports/process/DischargeProcessor.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/process/DischargeProcessor.java Mon Sep 23 11:37:13 2013 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/process/DischargeProcessor.java Tue Sep 24 12:29:44 2013 +0200
@@ -31,7 +31,7 @@
/** Helper for data handling in discharge diagrams. */
public class DischargeProcessor
-implements Processor, FacetTypes {
+extends DefaultProcessor implements FacetTypes {
private final static Logger logger =
Logger.getLogger(DischargeProcessor.class);
@@ -58,32 +58,32 @@
@Override
public void doOut(
XYChartGenerator generator,
- ArtifactAndFacet aandf,
+ ArtifactAndFacet bundle,
ThemeDocument theme,
boolean visible,
int axisIndex
) {
CallContext context = generator.getCallContext();
- Object data = aandf.getData(context);
+ Object data = bundle.getData(context);
if (false && data instanceof WQKms) {
doWQKmsPointOut(
- generator, (WQKms) data, aandf, theme, visible, axisIndex);
+ generator, (WQKms) data, bundle, theme, visible, axisIndex);
return;
}
else if (data instanceof RiverAnnotation) {
doRiverAnnotationOut(
- generator, (RiverAnnotation) data, aandf, theme, visible);
+ generator, (RiverAnnotation) data, bundle, theme, visible);
return;
}
else if (data instanceof double[][]) {
doMarksOut(
- generator, (double[][]) data, aandf, theme, visible);
+ generator, (double[][]) data, bundle, theme, visible);
return;
}
else {
logger.error("Can't process "
+ data.getClass().getName() + " objects of facet "
- + aandf.getFacetName());
+ + bundle.getFacetName());
}
}
@@ -109,13 +109,13 @@
/** Handle WQKms data by finding w/q values at given km. */
protected void doWQKmsPointOut(XYChartGenerator generator,
WQKms wqkms,
- ArtifactAndFacet aandf,
+ ArtifactAndFacet bundle,
ThemeDocument theme,
boolean visible,
int axidx
) {
logger.debug("doWQKmsPointOut");
- String title = aandf.getFacetDescription();
+ String title = bundle.getFacetDescription();
XYSeries series = new StyledXYSeries(
title,
theme);
@@ -147,7 +147,7 @@
protected void doRiverAnnotationOut(XYChartGenerator generator,
RiverAnnotation annotations,
- ArtifactAndFacet aandf,
+ ArtifactAndFacet bundle,
ThemeDocument theme,
boolean visible
) {
@@ -163,7 +163,7 @@
dGenerator.translateRiverAnnotation(annotations);
dGenerator.doAnnotations(
annotations,
- aandf, theme, visible);
+ bundle, theme, visible);
}
@@ -173,7 +173,7 @@
*/
protected void doMarksOut(XYChartGenerator generator,
double[][] data,
- ArtifactAndFacet aandf,
+ ArtifactAndFacet bundle,
ThemeDocument theme,
boolean visible
) {
@@ -184,7 +184,7 @@
}
// TODO subtract gauge null point if at gauge.
- String title = aandf.getFacetDescription();
+ String title = bundle.getFacetDescription();
List<StickyAxisAnnotation> yMarks = new ArrayList<StickyAxisAnnotation>();
for (double yPos: data[1]) {
@@ -195,7 +195,7 @@
}
generator.doAnnotations(new RiverAnnotation(title, yMarks),
- aandf, theme, visible);
+ bundle, theme, visible);
}
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/exports/process/KMIndexProcessor.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/process/KMIndexProcessor.java Mon Sep 23 11:37:13 2013 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/process/KMIndexProcessor.java Tue Sep 24 12:29:44 2013 +0200
@@ -22,22 +22,22 @@
import org.dive4elements.river.themes.ThemeDocument;
import org.dive4elements.river.utils.KMIndex;
-public class KMIndexProcessor implements Processor {
+public class KMIndexProcessor extends DefaultProcessor {
private static final Logger logger = Logger.getLogger(KMIndexProcessor.class);
@Override
- public void doOut(XYChartGenerator generator, ArtifactAndFacet aandf,
+ public void doOut(XYChartGenerator generator, ArtifactAndFacet bundle,
ThemeDocument theme, boolean visible, int index) {
- String facettype = aandf.getFacetName();
+ String facettype = bundle.getFacetName();
if (facettype.contains(FacetTypes.FIX_SECTOR_AVERAGE_LS)) {
- doSectorAverageOut(generator, aandf, theme, visible, index);
+ doSectorAverageOut(generator, bundle, theme, visible, index);
}
else if (facettype.equals(FacetTypes.FIX_REFERENCE_EVENTS_LS)) {
- doReferenceEventsOut(generator, aandf, theme, visible, index);
+ doReferenceEventsOut(generator, bundle, theme, visible, index);
}
else if (facettype.equals(FacetTypes.FIX_ANALYSIS_EVENTS_LS)) {
- doAnalysisEventsOut(generator, aandf, theme, visible, index);
+ doAnalysisEventsOut(generator, bundle, theme, visible, index);
}
}
@@ -57,23 +57,23 @@
return false;
}
- private void doSectorAverageOut(XYChartGenerator generator, ArtifactAndFacet aaf,
+ private void doSectorAverageOut(XYChartGenerator generator, ArtifactAndFacet bundle,
ThemeDocument doc, boolean visible, int idx) {
- logger.debug("doSectorAverageOut" + aaf.getFacet().getIndex());
+ logger.debug("doSectorAverageOut" + bundle.getFacet().getIndex());
CallContext context = generator.getCallContext();
- int index = aaf.getFacet().getIndex();
+ int index = bundle.getFacet().getIndex();
int sectorNdx = index & 3;
@SuppressWarnings("unchecked")
KMIndex<AnalysisPeriod> kms =
- (KMIndex<AnalysisPeriod>)aaf.getData(context);
+ (KMIndex<AnalysisPeriod>)bundle.getData(context);
if(kms == null) {
return;
}
- XYSeries series = new StyledXYSeries(aaf.getFacetDescription(), doc);
+ XYSeries series = new StyledXYSeries(bundle.getFacetDescription(), doc);
for (KMIndex.Entry<AnalysisPeriod> entry: kms) {
double km = entry.getKm();
@@ -90,14 +90,14 @@
}
private void doReferenceEventsOut(XYChartGenerator generator,
- ArtifactAndFacet aaf, ThemeDocument doc, boolean visible, int idx) {
+ ArtifactAndFacet bundle, ThemeDocument doc, boolean visible, int idx) {
logger.debug("doReferenceEventOut");
CallContext context = generator.getCallContext();
@SuppressWarnings("unchecked")
KMIndex<QWD> kms =
- (KMIndex<QWD>)aaf.getData(context);
+ (KMIndex<QWD>)bundle.getData(context);
if(kms == null) {
return;
@@ -105,7 +105,7 @@
XYSeriesCollection col = new XYSeriesCollection();
- StyledXYSeries series = new StyledXYSeries(aaf.getFacetDescription(), false,
+ StyledXYSeries series = new StyledXYSeries(bundle.getFacetDescription(), false,
doc);
for (KMIndex.Entry<QWD> entry: kms) {
@@ -120,14 +120,14 @@
}
private void doAnalysisEventsOut(XYChartGenerator generator,
- ArtifactAndFacet aaf, ThemeDocument doc, boolean visible, int idx) {
+ ArtifactAndFacet bundle, ThemeDocument doc, boolean visible, int idx) {
logger.debug("doAnalysisEventsOut");
CallContext context = generator.getCallContext();
@SuppressWarnings("unchecked")
KMIndex<QWD> kms =
- (KMIndex<QWD>)aaf.getData(context);
+ (KMIndex<QWD>)bundle.getData(context);
if(kms == null) {
return;
@@ -135,7 +135,7 @@
XYSeriesCollection col = new XYSeriesCollection();
- StyledXYSeries series = new StyledXYSeries(aaf.getFacetDescription(), false, doc);
+ StyledXYSeries series = new StyledXYSeries(bundle.getFacetDescription(), false, doc);
for (KMIndex.Entry<QWD> entry: kms) {
double km = entry.getKm();
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/exports/process/ManualPointsProcessor.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/process/ManualPointsProcessor.java Tue Sep 24 12:29:44 2013 +0200
@@ -0,0 +1,87 @@
+/* Copyright (C) 2013 by Bundesanstalt für Gewässerkunde
+ * Software engineering by Intevation GmbH
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+
+
+package org.dive4elements.river.exports.process;
+
+import org.apache.log4j.Logger;
+
+import java.util.List;
+import java.util.ArrayList;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+
+import org.jfree.data.xy.XYSeries;
+import org.jfree.chart.annotations.XYTextAnnotation;
+
+import org.dive4elements.artifactdatabase.state.ArtifactAndFacet;
+import org.dive4elements.artifacts.CallContext;
+import org.dive4elements.river.artifacts.model.FacetTypes;
+import org.dive4elements.river.exports.DiagramGenerator;
+import org.dive4elements.river.jfree.RiverAnnotation;
+import org.dive4elements.river.jfree.CollisionFreeXYTextAnnotation;
+import org.dive4elements.river.jfree.StyledXYSeries;
+import org.dive4elements.river.themes.ThemeDocument;
+
+public class ManualPointsProcessor extends DefaultProcessor {
+
+ private static final Logger logger = Logger.getLogger(ManualPointsProcessor.class);
+
+ @Override
+ public void doOut(
+ DiagramGenerator generator,
+ ArtifactAndFacet bundle,
+ ThemeDocument theme,
+ boolean visible) {
+ CallContext context = generator.getCallContext();
+ String seriesName = bundle.getFacetDescription();
+ XYSeries series = new StyledXYSeries(seriesName, theme);
+ String jsonData = (String) bundle.getData(context);
+
+ // Add text annotations for single points.
+ List<XYTextAnnotation> xy = new ArrayList<XYTextAnnotation>();
+
+ try {
+ JSONArray points = new JSONArray(jsonData);
+ for (int i = 0, P = points.length(); i < P; i++) {
+ JSONArray array = points.getJSONArray(i);
+ double x = array.getDouble(0);
+ double y = array.getDouble(1);
+ String name = array.getString(2);
+ boolean act = array.getBoolean(3);
+ if (!act) {
+ continue;
+ }
+ //logger.debug(" x " + x + " y " + y );
+ series.add(x, y, false);
+ xy.add(new CollisionFreeXYTextAnnotation(name, x, y));
+ }
+ }
+ catch(JSONException e){
+ logger.error("Could not decode json.");
+ }
+
+ RiverAnnotation annotation = new RiverAnnotation(null, null, null, theme);
+ annotation.setTextAnnotations(xy);
+
+ if (visible) {
+ generator.addAnnotations(annotation);
+ }
+
+ generator.addAxisSeries(series, axisName, visible);
+ }
+
+ @Override
+ public boolean canHandle(String facetType) {
+ if (facetType == null) {
+ return false;
+ }
+ return FacetTypes.IS.MANUALPOINTS(facetType);
+ }
+}
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/exports/process/Processor.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/process/Processor.java Mon Sep 23 11:37:13 2013 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/process/Processor.java Tue Sep 24 12:29:44 2013 +0200
@@ -11,6 +11,7 @@
import org.dive4elements.artifactdatabase.state.ArtifactAndFacet;
import org.dive4elements.river.exports.XYChartGenerator;
import org.dive4elements.river.themes.ThemeDocument;
+import org.dive4elements.river.exports.DiagramGenerator;
/**
* A processor is intended to generate an output e.g. curve in a chart diagramm from
@@ -19,19 +20,55 @@
* @author <a href="mailto:bjoern.ricks at intevation.de">Björn Ricks</a>
*/
public interface Processor {
+ /**
+ * Set the axis for this processor.
+ * This should be done before doOut is called for the first time.
+ *
+ * @param axisName The name of the Axis this processor should use.
+ */
+ public void setAxisName(String axisName);
+
+ /**
+ * Get the axis for this processor.
+ *
+ * @return The name of the axis that is used.
+ */
+ public String getAxisName();
+
+ /**
+ * Get the axis label for this processor.
+ *
+ * @return The label of the axis.
+ */
+ public String getAxisLabel(DiagramGenerator generator);
/**
* Processes data to generate e.g. a chart.
*
* @param generator XYChartGenerator to add output on.
- * @param aandf The artifact and facet
- * @param theme The theme that contains styling information.
- * @param visible The visibility of the curve.
- * @param index The index of the curve
+ * @param bundle The artifact and facet
+ * @param theme The theme that contains styling information.
+ * @param visible The visibility of the curve.
*/
public void doOut(
+ DiagramGenerator generator,
+ ArtifactAndFacet bundle,
+ ThemeDocument theme,
+ boolean visible);
+
+ /**
+ * Processes data to generate e.g. a chart.
+ *
+ * @param generator DiagramGenerator to add output on.
+ * @param bundle The artifact and facet
+ * @param theme The theme that contains styling information.
+ * @param visible The visibility of the curve.
+ * @param index The index of the curve
+ */
+ @Deprecated
+ public void doOut(
XYChartGenerator generator,
- ArtifactAndFacet aandf,
+ ArtifactAndFacet bundle,
ThemeDocument theme,
boolean visible,
int index);
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/exports/process/QOutProcessor.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/process/QOutProcessor.java Mon Sep 23 11:37:13 2013 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/process/QOutProcessor.java Tue Sep 24 12:29:44 2013 +0200
@@ -14,21 +14,26 @@
import org.dive4elements.artifactdatabase.state.ArtifactAndFacet;
import org.dive4elements.artifacts.CallContext;
import org.dive4elements.river.artifacts.model.FacetTypes;
-import org.dive4elements.river.artifacts.model.WKms;
import org.dive4elements.river.artifacts.model.WQKms;
import org.dive4elements.river.exports.StyledSeriesBuilder;
import org.dive4elements.river.exports.XYChartGenerator;
+import org.dive4elements.river.exports.DiagramGenerator;
import org.dive4elements.river.jfree.StyledXYSeries;
import org.dive4elements.river.themes.ThemeDocument;
-import org.dive4elements.river.utils.DataUtil;
/**
* Add data to chart/generator.
*
* @author <a href="mailto:bjoern.ricks at intevation.de">Björn Ricks</a>
*/
-public class QOutProcessor implements Processor {
+public class QOutProcessor extends DefaultProcessor {
+
+ public static final String I18N_LONGITUDINAL_LABEL =
+ "chart.longitudinal.section.yaxis.second.label";
+
+ public static final String
+ I18N_LONGITUDINAL_LABEL_DEFAULT = "Q [m\u00b3/s]";
/** Private logger. */
private static final Logger logger =
@@ -36,16 +41,48 @@
@Override
public void doOut(
+ DiagramGenerator generator,
+ ArtifactAndFacet bundle,
+ ThemeDocument theme,
+ boolean visible) {
+ CallContext context = generator.getCallContext();
+ WQKms wqkms = (WQKms) bundle.getData(context);
+
+ XYSeries series = new StyledXYSeries(bundle.getFacetDescription(), theme);
+
+ StyledSeriesBuilder.addStepPointsKmQ(series, wqkms);
+
+ generator.addAxisSeries(series, axisName, visible);
+
+ /* Check if the diagram should be inverted*/
+ generator.setInverted(wqkms.guessRTLData());
+ }
+
+ @Override
+ public void doOut(
XYChartGenerator generator,
- ArtifactAndFacet aaf,
+ ArtifactAndFacet bundle,
ThemeDocument theme,
boolean visible,
int index)
{
CallContext context = generator.getCallContext();
- WQKms wqkms = (WQKms) aaf.getData(context);
+ WQKms wqkms = (WQKms) bundle.getData(context);
- doQOut(generator, wqkms, aaf, theme, visible, index);
+ XYSeries series = new StyledXYSeries(bundle.getFacetDescription(), theme);
+
+ StyledSeriesBuilder.addStepPointsKmQ(series, wqkms);
+
+ generator.addAxisSeries(series, index, visible);
+
+ /* Check if the diagram should be inverted*/
+ generator.setInverted(wqkms.guessRTLData());
+ }
+
+ @Override
+ public String getAxisLabel(DiagramGenerator generator) {
+ return generator.msg(I18N_LONGITUDINAL_LABEL,
+ I18N_LONGITUDINAL_LABEL_DEFAULT);
}
/**
@@ -59,73 +96,10 @@
if (facetType.equals(FacetTypes.STATIC_WQKMS_Q)
|| facetType.equals(FacetTypes.LONGITUDINAL_Q)
- || facetType.equals(FacetTypes.DISCHARGE_LONGITUDINAL_Q)) {
+ || facetType.startsWith(FacetTypes.DISCHARGE_LONGITUDINAL_Q)) {
return true;
}
return false;
}
-
-
- /**
- * Process the output for Q facets in a longitudinal section curve.
- *
- * @param generator Generator to use.
- * @param wqkms An array of WQKms values.
- * @param aandf The facet and artifact. This facet does NOT support any data objects. Use
- * D4EArtifact.getNativeFacet() instead to retrieve a Facet which supports
- * data.
- * @param theme The theme that contains styling information.
- * @param visible The visibility of the curve.
- * @param index Axis index to add data to.
- */
- protected void doQOut(
- XYChartGenerator generator,
- WQKms wqkms,
- ArtifactAndFacet aaf,
- ThemeDocument theme,
- boolean visible,
- int index
- ) {
- logger.debug("QProcessor.doOut");
-
- XYSeries series = new StyledXYSeries(aaf.getFacetDescription(), theme);
-
- StyledSeriesBuilder.addStepPointsKmQ(series, wqkms);
-
- generator.addAxisSeries(series, index, visible);
-
- invertAxis(generator, wqkms);
- }
-
- /**
- * This method determines - taking JFreeCharts auto x value ordering into
- * account - if the x axis need to be inverted. Waterlines in these charts
- * should decrease.
- *
- * @param generator the generator to invert the axis or not.
- * @param wkms The data object that stores the x and y values used for this
- * chart.
- */
- public void invertAxis(XYChartGenerator generator, WKms wkms) {
- boolean wsUp = wkms.guessWaterIncreasing();
- boolean kmUp = DataUtil.guessWaterIncreasing(wkms.allKms());
- int size = wkms.size();
- boolean inv = ((wsUp && kmUp) || (!wsUp && !kmUp)) && size > 1;
-
- if (logger.isDebugEnabled()) {
- logger.debug("(Wkms)Values : " + size);
- if (size > 0) {
- logger.debug("Start km: " + wkms.getKm(0));
- logger.debug("End km: " + wkms.getKm(size-1));
- }
- logger.debug("wsUp: " + wsUp);
- logger.debug("kmUp: " + kmUp);
- if (size == 1) {
- logger.debug("InvertAxis not inverting because we have just one km");
- }
- logger.debug("inv: " + inv);
- }
- generator.setInverted(inv);
- }
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/exports/process/WDiffProcessor.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/process/WDiffProcessor.java Tue Sep 24 12:29:44 2013 +0200
@@ -0,0 +1,39 @@
+/* Copyright (C) 2013 by Bundesanstalt für Gewässerkunde
+ * Software engineering by Intevation GmbH
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+
+package org.dive4elements.river.exports.process;
+
+import org.dive4elements.artifactdatabase.state.ArtifactAndFacet;
+import org.dive4elements.river.artifacts.model.FacetTypes;
+import org.dive4elements.river.artifacts.model.WKms;
+import org.dive4elements.river.themes.ThemeDocument;
+import org.dive4elements.river.exports.DiagramGenerator;
+
+public class WDiffProcessor extends WOutProcessor {
+
+ public final static String I18N_WDIFF_YAXIS_LABEL =
+ "chart.w_differences.yaxis.label";
+
+ public final static String I18N_WDIFF_YAXIS_LABEL_DEFAULT = "m";
+
+ @Override
+ public boolean canHandle(String facetType) {
+ if (facetType == null) {
+ return false;
+ }
+ return facetType.equals(FacetTypes.W_DIFFERENCES);
+ }
+
+
+ @Override
+ public String getAxisLabel(DiagramGenerator generator) {
+ return generator.msg(I18N_WDIFF_YAXIS_LABEL,
+ I18N_WDIFF_YAXIS_LABEL_DEFAULT);
+ }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/exports/process/WOutProcessor.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/process/WOutProcessor.java Mon Sep 23 11:37:13 2013 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/process/WOutProcessor.java Tue Sep 24 12:29:44 2013 +0200
@@ -13,40 +13,102 @@
import org.dive4elements.artifactdatabase.state.ArtifactAndFacet;
import org.dive4elements.artifacts.CallContext;
+import org.dive4elements.river.artifacts.D4EArtifact;
import org.dive4elements.river.artifacts.model.FacetTypes;
import org.dive4elements.river.artifacts.model.WKms;
+import org.dive4elements.river.artifacts.model.WQCKms;
import org.dive4elements.river.exports.StyledSeriesBuilder;
import org.dive4elements.river.exports.XYChartGenerator;
+import org.dive4elements.river.exports.DiagramGenerator;
import org.dive4elements.river.jfree.StyledAreaSeriesCollection;
import org.dive4elements.river.jfree.StyledXYSeries;
import org.dive4elements.river.themes.ThemeDocument;
-import org.dive4elements.river.utils.DataUtil;
+import org.dive4elements.river.utils.RiverUtils;
/**
* Add data to chart/generator.
*
* @author <a href="mailto:bjoern.ricks at intevation.de">Björn Ricks</a>
*/
-public class WOutProcessor implements Processor {
+public class WOutProcessor extends DefaultProcessor {
/** Private logger. */
private static final Logger logger =
Logger.getLogger(WOutProcessor.class);
+ public static final String I18N_AXIS_LABEL =
+ "chart.longitudinal.section.yaxis.label";
+
+ public static final String I18N_AXIS_LABEL_DEFAULT = "W [NN + m]";
+
+ @Override
+ public void doOut(
+ DiagramGenerator generator,
+ ArtifactAndFacet bundle,
+ ThemeDocument theme,
+ boolean visible) {
+ CallContext context = generator.getCallContext();
+ Object data = bundle.getData(context);
+ WKms wkms = (WKms) data;
+
+ logger.debug("Processing facet: " + bundle.getFacetName());
+
+ XYSeries series = new StyledXYSeries(bundle.getFacetDescription(), theme);
+
+ if (bundle.getFacetName().equals(FacetTypes.DISCHARGE_LONGITUDINAL_C)) {
+ // Add corrected values
+ WQCKms wqckms = (WQCKms) data;
+ int size = wqckms.size();
+ for (int i = 0; i < size; i++) {
+ series.add(wqckms.getKm(i), wqckms.getC(i), false);
+ }
+ } else {
+ StyledSeriesBuilder.addPoints(series, wkms);
+ }
+ generator.addAxisSeries(series, axisName, visible);
+
+ // If a "band around the curve shall be drawn, add according area.
+ double bandWidth = theme.parseBandWidth();
+ if (bandWidth > 0 ) {
+ XYSeries seriesDown = new StyledXYSeries(
+ "band " + bundle.getFacetDescription(), false, theme);
+ XYSeries seriesUp = new StyledXYSeries(
+ bundle.getFacetDescription()+"+/-"+bandWidth, false, theme);
+ StyledSeriesBuilder.addUpperBand(seriesUp, wkms, bandWidth);
+ StyledSeriesBuilder.addLowerBand(seriesDown, wkms, bandWidth);
+
+ StyledAreaSeriesCollection area = new StyledAreaSeriesCollection(theme);
+ area.addSeries(seriesUp);
+ area.addSeries(seriesDown);
+ area.setMode(StyledAreaSeriesCollection.FILL_MODE.BETWEEN);
+ generator.addAreaSeries(area, axisName, visible);
+ }
+
+ if (bundle.getFacetName().equals(FacetTypes.LONGITUDINAL_W) ||
+ bundle.getFacetName().equals(FacetTypes.DISCHARGE_LONGITUDINAL_W) ||
+ bundle.getFacetName().equals(FacetTypes.STATIC_WQKMS_W) ||
+ bundle.getFacetName().equals(FacetTypes.DISCHARGE_LONGITUDINAL_C)) {
+ /* Only use W values to check if the diagram should be inverted
+ * see flys/issue1290 for details */
+ logger.debug("Check for RTL data: "+ wkms.guessRTLData());
+ generator.setInverted(wkms.guessRTLData());
+ }
+ }
+
@Override
public void doOut(
XYChartGenerator generator,
- ArtifactAndFacet aaf,
+ ArtifactAndFacet bundle,
ThemeDocument theme,
boolean visible,
int index)
{
CallContext context = generator.getCallContext();
- WKms wkms = (WKms) aaf.getData(context);
+ WKms wkms = (WKms) bundle.getData(context);
logger.debug("doOut");
- XYSeries series = new StyledXYSeries(aaf.getFacetDescription(), theme);
+ XYSeries series = new StyledXYSeries(bundle.getFacetDescription(), theme);
StyledSeriesBuilder.addPoints(series, wkms);
generator.addAxisSeries(series, index, visible);
@@ -55,9 +117,9 @@
double bandWidth = theme.parseBandWidth();
if (bandWidth > 0 ) {
XYSeries seriesDown = new StyledXYSeries(
- "band " + aaf.getFacetDescription(), false, theme);
+ "band " + bundle.getFacetDescription(), false, theme);
XYSeries seriesUp = new StyledXYSeries(
- aaf.getFacetDescription()+"+/-"+bandWidth, false, theme);
+ bundle.getFacetDescription()+"+/-"+bandWidth, false, theme);
StyledSeriesBuilder.addUpperBand(seriesUp, wkms, bandWidth);
StyledSeriesBuilder.addLowerBand(seriesDown, wkms, bandWidth);
@@ -68,15 +130,27 @@
generator.addAreaSeries(area, index, visible);
}
- if (aaf.getFacetName().equals(FacetTypes.LONGITUDINAL_W) ||
- aaf.getFacetName().equals(FacetTypes.DISCHARGE_LONGITUDINAL_W) ||
- aaf.getFacetName().equals(FacetTypes.STATIC_WQKMS_W)) {
+ if (bundle.getFacetName().equals(FacetTypes.LONGITUDINAL_W) ||
+ bundle.getFacetName().equals(FacetTypes.DISCHARGE_LONGITUDINAL_W) ||
+ bundle.getFacetName().equals(FacetTypes.STATIC_WQKMS_W)) {
/* Only use W values to check if the diagram should be inverted
* see flys/issue1290 for details */
- invertAxis(generator, wkms);
+ generator.setInverted(wkms.guessRTLData());
}
}
+ @Override
+ public String getAxisLabel(DiagramGenerator generator) {
+ D4EArtifact flys = (D4EArtifact) generator.getMaster();
+
+ String unit = RiverUtils.getRiver(flys).getWstUnit().getName();
+
+ return generator.msg(
+ I18N_AXIS_LABEL,
+ I18N_AXIS_LABEL_DEFAULT,
+ new Object[] { unit });
+ }
+
/**
* Returns true if facettype is longitutinal_section.w .
*/
@@ -91,41 +165,12 @@
|| facetType.equals(FacetTypes.HEIGHTMARKS_POINTS)
|| facetType.equals(FacetTypes.STATIC_WQKMS)
|| facetType.equals(FacetTypes.STATIC_WQKMS_W)
- || facetType.equals(FacetTypes.DISCHARGE_LONGITUDINAL_W))
+ || facetType.equals(FacetTypes.DISCHARGE_LONGITUDINAL_W)
+ || facetType.equals(FacetTypes.DISCHARGE_LONGITUDINAL_C))
{
return true;
}
return false;
}
-
- /**
- * This method determines - taking JFreeCharts auto x value ordering into
- * account - if the x axis need to be inverted. Waterlines in these charts
- * should decrease.
- *
- * @param wkms The data object that stores the x and y values used for this
- * chart.
- */
- public void invertAxis(XYChartGenerator generator, WKms wkms) {
- boolean wsUp = wkms.guessWaterIncreasing();
- boolean kmUp = DataUtil.guessWaterIncreasing(wkms.allKms());
- int size = wkms.size();
- boolean inv = ((wsUp && kmUp) || (!wsUp && !kmUp)) && size > 1;
-
- if (logger.isDebugEnabled()) {
- logger.debug("(Wkms)Values : " + size);
- if (size > 0) {
- logger.debug("Start km: " + wkms.getKm(0));
- logger.debug("End km: " + wkms.getKm(size-1));
- }
- logger.debug("wsUp: " + wsUp);
- logger.debug("kmUp: " + kmUp);
- if (size == 1) {
- logger.debug("InvertAxis not inverting because we have just one km");
- }
- logger.debug("inv: " + inv);
- }
- generator.setInverted(inv);
- }
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/exports/sq/SQOverviewGenerator.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/sq/SQOverviewGenerator.java Mon Sep 23 11:37:13 2013 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/sq/SQOverviewGenerator.java Tue Sep 24 12:29:44 2013 +0200
@@ -62,6 +62,13 @@
protected List<JFreeChart> charts;
+ protected String outName;
+
+ @Override
+ public void setup(Object config) {
+ logger.debug("SQOverviewGenerator.setup");
+ }
+
/**
* Produce output.
* @param artifactAndFacet current facet and artifact.
@@ -75,6 +82,8 @@
) {
logger.debug("doOut()");
+ // TODO: Why not using outName for this.
+
String name = artifactAndFacet.getData(context).toString();
if(name != null) {
logger.debug("name: " + name);
@@ -94,7 +103,7 @@
try {
Document cAttr = getAttribute(context, collectionAttribute, name);
- g.init(request, out, context);
+ g.init(name, request, out, context);
helper.doOut(g, name, name, cAttr, context);
JFreeChart chart = g.generateChart();
@@ -111,7 +120,8 @@
}
@Override
- public void init(Document request, OutputStream out, CallContext context) {
+ public void init(String outName, Document request, OutputStream out, CallContext context) {
+ this.outName = outName;
this.request = request;
this.out = out;
this.context = context;
@@ -153,6 +163,7 @@
if (i > 1) {
vertPos = (size[1] / 3) * (i / 2);
}
+ // TODO: Dispose Graphics object!
result.createGraphics().drawImage(img, horPos, vertPos, null);
}
ImageIO.write(result, "png", out);
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/exports/sq/SQRelationExporter.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/sq/SQRelationExporter.java Mon Sep 23 11:37:13 2013 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/sq/SQRelationExporter.java Tue Sep 24 12:29:44 2013 +0200
@@ -18,8 +18,6 @@
import java.text.DateFormat;
import java.text.NumberFormat;
-import org.w3c.dom.Document;
-
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
@@ -27,7 +25,6 @@
import au.com.bytecode.opencsv.CSVWriter;
-import org.dive4elements.artifacts.CallContext;
import org.dive4elements.artifacts.CallMeta;
import org.dive4elements.river.artifacts.model.CalculationResult;
@@ -117,13 +114,10 @@
protected List<SQResult []> data;
-
- public void init(Document request, OutputStream out, CallContext cc) {
- super.init(request, out, cc);
+ public SQRelationExporter() {
data = new ArrayList<SQResult []>();
}
-
@Override
protected void addData(Object d) {
if (d instanceof CalculationResult) {
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/jfree/AnnotationHelper.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/jfree/AnnotationHelper.java Tue Sep 24 12:29:44 2013 +0200
@@ -0,0 +1,365 @@
+/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde
+ * Software engineering by Intevation GmbH
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+package org.dive4elements.river.jfree;
+
+import org.dive4elements.river.themes.ThemeDocument;
+
+import java.util.List;
+import java.util.Map;
+
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Font;
+
+import org.jfree.ui.TextAnchor;
+import org.jfree.chart.plot.XYPlot;
+import org.jfree.chart.LegendItem;
+import org.jfree.chart.LegendItemCollection;
+import org.jfree.chart.annotations.XYTextAnnotation;
+import org.jfree.chart.annotations.XYLineAnnotation;
+
+import org.dive4elements.river.themes.LineStyle;
+import org.dive4elements.river.themes.TextStyle;
+import org.dive4elements.river.exports.ChartSettings;
+import org.dive4elements.river.exports.LegendSection;
+import org.dive4elements.river.exports.ChartArea;
+
+import org.apache.log4j.Logger;
+
+/** Annotation helper class, handles plotting of annotations. */
+public class AnnotationHelper {
+ private static final Logger logger = Logger.getLogger(AnnotationHelper.class);
+
+ protected static float ANNOTATIONS_AXIS_OFFSET = 0.02f;
+
+ /* arr this would be better in chartsettings */
+ public static final int DEFAULT_FONT_SIZE = 12;
+ public static final String DEFAULT_FONT_NAME = "Tahoma";
+
+ /**
+ * Add annotations (Sticky, Text and hyk zones) to a plot.
+ * @param annotations Annotations to add
+ * @param plot Plot to add annotations to.
+ * @param settings ChartSettings object for settings.
+ */
+ public static void addAnnotationsToRenderer(List<RiverAnnotation> annotations,
+ XYPlot plot, ChartSettings settings, Map<Integer, AxisDataset> datasets) {
+ logger.debug("addAnnotationsToRenderer");
+
+ if (annotations == null || annotations.isEmpty()) {
+ logger.debug("addAnnotationsToRenderer: no annotations.");
+ return;
+ }
+
+ // OPTMIMIZE: Pre-calculate positions
+ ChartArea area = new ChartArea(
+ plot.getDomainAxis(0).getRange(),
+ plot.getRangeAxis().getRange());
+
+ // Walk over all Annotation sets.
+ for (RiverAnnotation fa: annotations) {
+
+ // Access text styling, if any.
+ ThemeDocument theme = fa.getTheme();
+ TextStyle textStyle = null;
+ LineStyle lineStyle = null;
+
+ // Get Themeing information and add legend item.
+ if (theme != null) {
+ textStyle = theme.parseComplexTextStyle();
+ lineStyle = theme.parseComplexLineStyle();
+ if (fa.getLabel() != null) {
+ // Legend handling, maybe misplaced?
+ LegendItemCollection lic = new LegendItemCollection();
+ LegendItemCollection old = plot.getFixedLegendItems();
+
+ Color color = theme.parseLineColorField();
+ if (color == null) {
+ color = Color.BLACK;
+ }
+
+ LegendItem newItem = new LegendItem(fa.getLabel(), color);
+ LegendSection ls = (settings != null ?
+ settings.getLegendSection() : null);
+ newItem.setLabelFont (new Font(
+ DEFAULT_FONT_NAME,
+ Font.PLAIN,
+ ls != null ? ls.getFontSize() : null)
+ );
+
+ lic.add(newItem);
+ // (Re-)Add prior legend entries.
+ if (old != null) {
+ old.addAll(lic);
+ }
+ else {
+ old = lic;
+ }
+ plot.setFixedLegendItems(old);
+ }
+ }
+
+ // The 'Sticky' Annotations (at axis, with line and text).
+ for (StickyAxisAnnotation sta: fa.getAxisTextAnnotations()) {
+ addStickyAnnotation(
+ sta, plot, area, lineStyle, textStyle, theme,
+ datasets.get(new Integer(sta.getAxisSymbol())));
+ }
+
+ // Other Text Annotations (e.g. labels of (manual) points).
+ for (XYTextAnnotation ta: fa.getTextAnnotations()) {
+ // Style the text.
+ if (textStyle != null) {
+ textStyle.apply(ta);
+ }
+ ta.setY(area.above(0.05d, ta.getY()));
+ plot.getRenderer().addAnnotation(ta, org.jfree.ui.Layer.FOREGROUND);
+ }
+ }
+ }
+
+ /**
+ * Add a text and a line annotation.
+ * @param area convenience to determine positions in plot.
+ * @param theme (optional) theme document
+ */
+ public static void addStickyAnnotation(
+ StickyAxisAnnotation annotation,
+ XYPlot plot,
+ ChartArea area,
+ LineStyle lineStyle,
+ TextStyle textStyle,
+ ThemeDocument theme,
+ AxisDataset dataset
+ ) {
+ // OPTIMIZE pre-calculate area-related values
+ final float TEXT_OFF = 0.03f;
+
+ XYLineAnnotation lineAnnotation = null;
+ XYTextAnnotation textAnnotation = null;
+
+ int rendererIndex = 0;
+
+ if (annotation.atX()) {
+ textAnnotation = new CollisionFreeXYTextAnnotation(
+ annotation.getText(), annotation.getPos(), area.ofGround(TEXT_OFF));
+ // OPTIMIZE externalize the calculation involving PI.
+ //textAnnotation.setRotationAngle(270f*Math.PI/180f);
+ lineAnnotation = createGroundStickAnnotation(
+ area, annotation.getPos(), lineStyle);
+ textAnnotation.setRotationAnchor(TextAnchor.CENTER_LEFT);
+ textAnnotation.setTextAnchor(TextAnchor.CENTER_LEFT);
+ }
+ else {
+ // Do the more complicated case where we stick to the Y-Axis.
+ // There is one nasty case (duration curves, where annotations
+ // might stick to the second y-axis).
+ if (dataset == null) {
+ logger.warn("Annotation should stick to unfindable y-axis: "
+ + annotation.getAxisSymbol());
+ rendererIndex = 0;
+ }
+ else {
+ rendererIndex = dataset.getPlotAxisIndex();
+ }
+
+ // Stick to the "right" (opposed to left) Y-Axis.
+ if (rendererIndex != 0) {
+ // OPTIMIZE: Pass a different area to this function,
+ // do the adding to renderer outside (let this
+ // function return the annotations).
+ // Note that this path is travelled rarely.
+ ChartArea area2 = new ChartArea(plot.getDomainAxis(), plot.getRangeAxis(rendererIndex));
+ textAnnotation = new CollisionFreeXYTextAnnotation(
+ annotation.getText(), area2.ofRight(TEXT_OFF), annotation.getPos());
+ textAnnotation.setRotationAnchor(TextAnchor.CENTER_RIGHT);
+ textAnnotation.setTextAnchor(TextAnchor.CENTER_RIGHT);
+ lineAnnotation = createRightStickAnnotation(
+ area2, annotation.getPos(), lineStyle);
+ if (!Float.isNaN(annotation.getHitPoint()) && theme != null) {
+ // New line annotation to hit curve.
+ if (theme.parseShowVerticalLine()) {
+ XYLineAnnotation hitLineAnnotation =
+ createStickyLineAnnotation(
+ StickyAxisAnnotation.SimpleAxis.X_AXIS,
+ annotation.getHitPoint(), annotation.getPos(),// annotation.getHitPoint(),
+ area2, lineStyle);
+ plot.getRenderer(rendererIndex).addAnnotation(hitLineAnnotation,
+ org.jfree.ui.Layer.BACKGROUND);
+ }
+ if (theme.parseShowHorizontalLine()) {
+ XYLineAnnotation lineBackAnnotation =
+ createStickyLineAnnotation(
+ StickyAxisAnnotation.SimpleAxis.Y_AXIS2,
+ annotation.getPos(), annotation.getHitPoint(),
+ area2, lineStyle);
+ plot.getRenderer(rendererIndex).addAnnotation(lineBackAnnotation,
+ org.jfree.ui.Layer.BACKGROUND);
+ }
+ }
+ }
+ else { // Stick to the left y-axis.
+ textAnnotation = new CollisionFreeXYTextAnnotation(
+ annotation.getText(), area.ofLeft(TEXT_OFF), annotation.getPos());
+ textAnnotation.setRotationAnchor(TextAnchor.CENTER_LEFT);
+ textAnnotation.setTextAnchor(TextAnchor.CENTER_LEFT);
+ lineAnnotation = createLeftStickAnnotation(area, annotation.getPos(), lineStyle);
+ if (!Float.isNaN(annotation.getHitPoint()) && theme != null) {
+ // New line annotation to hit curve.
+ if (theme.parseShowHorizontalLine()) {
+ XYLineAnnotation hitLineAnnotation =
+ createStickyLineAnnotation(
+ StickyAxisAnnotation.SimpleAxis.Y_AXIS,
+ annotation.getPos(), annotation.getHitPoint(),
+ area, lineStyle);
+ plot.getRenderer(rendererIndex).addAnnotation(hitLineAnnotation,
+ org.jfree.ui.Layer.BACKGROUND);
+ }
+ if (theme.parseShowVerticalLine()) {
+ XYLineAnnotation lineBackAnnotation =
+ createStickyLineAnnotation(
+ StickyAxisAnnotation.SimpleAxis.X_AXIS,
+ annotation.getHitPoint(), annotation.getPos(),
+ area, lineStyle);
+ plot.getRenderer(rendererIndex).addAnnotation(lineBackAnnotation,
+ org.jfree.ui.Layer.BACKGROUND);
+ }
+ }
+ }
+ }
+
+ // Style the text.
+ if (textStyle != null) {
+ textStyle.apply(textAnnotation);
+ }
+
+ // Add the Annotations to renderer.
+ plot.getRenderer(rendererIndex).addAnnotation(textAnnotation,
+ org.jfree.ui.Layer.FOREGROUND);
+ plot.getRenderer(rendererIndex).addAnnotation(lineAnnotation,
+ org.jfree.ui.Layer.FOREGROUND);
+ }
+
+ /**
+ * Create annotation that sticks to "ground" (X) axis.
+ * @param area helper to calculate coordinates
+ * @param pos one-dimensional position (distance from axis)
+ * @param lineStyle the line style to use for the line.
+ */
+ public static XYLineAnnotation createGroundStickAnnotation(
+ ChartArea area, float pos, LineStyle lineStyle
+ ) {
+ // Style the line.
+ if (lineStyle != null) {
+ return new XYLineAnnotation(
+ pos, area.atGround(),
+ pos, area.ofGround(ANNOTATIONS_AXIS_OFFSET),
+ new BasicStroke(lineStyle.getWidth()),lineStyle.getColor());
+ }
+ else {
+ return new XYLineAnnotation(
+ pos, area.atGround(),
+ pos, area.ofGround(ANNOTATIONS_AXIS_OFFSET));
+ }
+ }
+
+
+ /**
+ * Create annotation that sticks to the second Y axis ("right").
+ * @param area helper to calculate coordinates
+ * @param pos one-dimensional position (distance from axis)
+ * @param lineStyle the line style to use for the line.
+ */
+ public static XYLineAnnotation createRightStickAnnotation(
+ ChartArea area, float pos, LineStyle lineStyle
+ ) {
+ // Style the line.
+ if (lineStyle != null) {
+ return new XYLineAnnotation(
+ area.ofRight(ANNOTATIONS_AXIS_OFFSET), pos,
+ area.atRight(), pos,
+ new BasicStroke(lineStyle.getWidth()), lineStyle.getColor());
+ }
+ else {
+ return new XYLineAnnotation(
+ area.atRight(), pos,
+ area.ofRight(ANNOTATIONS_AXIS_OFFSET), pos);
+ }
+ }
+ /**
+ * Create annotation that sticks to the first Y axis ("left").
+ * @param area helper to calculate coordinates
+ * @param pos one-dimensional position (distance from axis)
+ * @param lineStyle the line style to use for the line.
+ */
+ public static XYLineAnnotation createLeftStickAnnotation(
+ ChartArea area, float pos, LineStyle lineStyle
+ ) {
+ // Style the line.
+ if (lineStyle != null) {
+ return new XYLineAnnotation(
+ area.atLeft(), pos,
+ area.ofLeft(ANNOTATIONS_AXIS_OFFSET), pos,
+ new BasicStroke(lineStyle.getWidth()), lineStyle.getColor());
+ }
+ else {
+ return new XYLineAnnotation(
+ area.atLeft(), pos,
+ area.ofLeft(ANNOTATIONS_AXIS_OFFSET), pos);
+ }
+ }
+
+
+ /**
+ * Create a line from a axis to a given point.
+ * @param axis The "simple" axis.
+ * @param fromD1 from-location in first dimension.
+ * @param toD2 to-location in second dimension.
+ * @param area helper to calculate offsets.
+ * @param lineStyle optional line style.
+ */
+ public static XYLineAnnotation createStickyLineAnnotation(
+ StickyAxisAnnotation.SimpleAxis axis, float fromD1, float toD2,
+ ChartArea area, LineStyle lineStyle
+ ) {
+ double anchorX1 = 0d, anchorX2 = 0d, anchorY1 = 0d, anchorY2 = 0d;
+ switch(axis) {
+ case X_AXIS:
+ anchorX1 = fromD1;
+ anchorX2 = fromD1;
+ anchorY1 = area.atGround();
+ anchorY2 = toD2;
+ break;
+ case Y_AXIS:
+ anchorX1 = area.atLeft();
+ anchorX2 = toD2;
+ anchorY1 = fromD1;
+ anchorY2 = fromD1;
+ break;
+ case Y_AXIS2:
+ anchorX1 = area.atRight();
+ anchorX2 = toD2;
+ anchorY1 = fromD1;
+ anchorY2 = fromD1;
+ break;
+ }
+ // Style the line.
+ if (lineStyle != null) {
+ return new XYLineAnnotation(
+ anchorX1, anchorY1,
+ anchorX2, anchorY2,
+ new BasicStroke(lineStyle.getWidth()), lineStyle.getColor());
+ }
+ else {
+ return new XYLineAnnotation(
+ anchorX1, anchorY1,
+ anchorX2, anchorY2);
+ }
+ }
+
+};
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/jfree/AxisDataset.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/jfree/AxisDataset.java Tue Sep 24 12:29:44 2013 +0200
@@ -0,0 +1,127 @@
+/* Copyright (C) 2013 by Bundesanstalt für Gewässerkunde
+ * Software engineering by Intevation GmbH
+ *
+ * XYDatasethis file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUXYDatasetELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+
+package org.dive4elements.river.jfree;
+
+import java.util.List;
+import java.util.ArrayList;
+
+import org.jfree.data.Range;
+import org.jfree.data.RangeInfo;
+import org.jfree.data.xy.XYDataset;
+import org.jfree.data.xy.XYSeries;
+import org.jfree.data.xy.XYSeriesCollection;
+import org.jfree.data.time.TimeSeriesCollection;
+
+import org.apache.log4j.Logger;
+
+/**
+ * Axis datasets.
+ */
+public class AxisDataset
+{
+ private static Logger logger = Logger.getLogger(AxisDataset.class);
+
+ /** Symbolic integer, but also coding the priority (0 goes first). */
+ protected int axisSymbol;
+
+ /** List of assigned datasets (in order). */
+ protected List<XYDataset> datasets;
+
+ /** Range to use to include all given datasets. */
+ protected Range range;
+
+ /** Index of axis in plot. */
+ protected int plotAxisIndex;
+
+ protected boolean rangeDirty;
+
+ /** Create AxisDataset. */
+ public AxisDataset(int symb) {
+ axisSymbol = symb;
+ datasets = new ArrayList<XYDataset>();
+ }
+
+ /** Add a dataset to internal list for this axis. */
+ public void addDataset(XYDataset dataset) {
+ datasets.add(dataset);
+ rangeDirty = true;
+ }
+
+ /** Add a dataset. */
+ public void addDataset(XYSeries series) {
+ addDataset(new XYSeriesCollection(series));
+ }
+
+ public void setRange(Range val) {
+ range = val;
+ }
+
+ /** Get Range for the range axis of this dataset. */
+ public Range getRange() {
+ if (range != null && !rangeDirty) {
+ return range;
+ }
+ /* Calculate the min / max of all series */
+ for (XYDataset dataset: datasets) {
+ Range newRange = null;
+ if (dataset instanceof StyledAreaSeriesCollection) {
+ /* We do not include areas in the range calculation because
+ * they are used with very large / small values to draw areas
+ * with axis boundaries */
+ continue;
+ } else if (dataset instanceof RangeInfo) {
+ /* The usual case for most series */
+ newRange = ((RangeInfo) dataset).getRangeBounds(false);
+ } else if (dataset instanceof TimeSeriesCollection) {
+ /* Lalala <3 Jfreechart's class hirarchy */
+ newRange = ((TimeSeriesCollection) dataset).getRangeBounds(false);
+ }
+
+ /* Now we only expand as we also only add new data */
+ if (range == null) {
+ range = newRange;
+ } else {
+ range = Range.combine(range, newRange);
+ }
+ }
+ rangeDirty = false;
+ return range;
+ }
+
+ /** Get Array of Datasets. */
+ public XYDataset[] getDatasets() {
+ return datasets.toArray(new XYDataset[datasets.size()]);
+ }
+
+ /** True if to be rendered as area. */
+ public boolean isArea(XYDataset series) {
+ return (series instanceof StyledAreaSeriesCollection);
+ }
+
+ /** True if no datasets given. */
+ public boolean isEmpty() {
+ return datasets.isEmpty();
+ }
+
+ /** Set the 'real' axis index that this axis is mapped to. */
+ public void setPlotAxisIndex(int axisIndex) {
+ plotAxisIndex = axisIndex;
+ }
+
+ /** Get the 'real' axis index that this axis is mapped to. */
+ public int getPlotAxisIndex() {
+ return plotAxisIndex;
+ }
+
+ /** Add a Dataset that describes an area. */
+ public void addArea(StyledAreaSeriesCollection series) {
+ addDataset(series);
+ }
+
+}
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/utils/DataUtil.java
--- a/artifacts/src/main/java/org/dive4elements/river/utils/DataUtil.java Mon Sep 23 11:37:13 2013 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/utils/DataUtil.java Tue Sep 24 12:29:44 2013 +0200
@@ -14,11 +14,20 @@
public class DataUtil
{
- public static boolean guessWaterIncreasing(TDoubleArrayList data) {
- return guessWaterIncreasing(data, 0.05f);
+ public static boolean guessDataIncreasing(TDoubleArrayList data) {
+ return guessDataIncreasing(data, 0.05f);
}
- public static boolean guessWaterIncreasing(TDoubleArrayList data, float factor) {
+ /** Guess if data1 and data2 both grow in the same direction */
+ public static boolean guessSameDirectionData(TDoubleArrayList data1,
+ TDoubleArrayList data2) {
+ boolean d1dir = DataUtil.guessDataIncreasing(data1, 0.05f);
+ boolean d2dir = DataUtil.guessDataIncreasing(data2, 0.05f);
+ int size = data1.size();
+ return ((d1dir && d2dir) || (!d1dir && !d2dir)) && size > 1;
+ }
+
+ public static boolean guessDataIncreasing(TDoubleArrayList data, float factor) {
int N = data.size();
if (N < 2) return false;
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/java/org/dive4elements/river/utils/Pair.java
--- a/artifacts/src/main/java/org/dive4elements/river/utils/Pair.java Mon Sep 23 11:37:13 2013 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/utils/Pair.java Tue Sep 24 12:29:44 2013 +0200
@@ -21,8 +21,7 @@
private A a;
private B b;
- @SuppressWarnings("unused")
- private Pair() {
+ public Pair() {
}
public Pair(A a, B b) {
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/resources/messages.properties
--- a/artifacts/src/main/resources/messages.properties Mon Sep 23 11:37:13 2013 +0200
+++ b/artifacts/src/main/resources/messages.properties Tue Sep 24 12:29:44 2013 +0200
@@ -152,6 +152,7 @@
chart.longitudinal.section.title = W-Longitudinal Section
chart.longitudinal.section.subtitle = Range: {0}-km {1,number,#.###} - {2,number,#.###}
chart.longitudinal.section.shortsubtitle = {0}
+chart.longitudinal.section.locsubtitle = {0} km {1,number,#.###}
chart.longitudinal.section.xaxis.label = {0}-km
chart.longitudinal.section.yaxis.label = W [{0}]
chart.longitudinal.section.yaxis.second.label = Q [m\u00b3/s]
@@ -197,7 +198,7 @@
chart.reference.curve.y.axis.in.m = Target Station(s) [NN + m]
chart.w_differences.title = Differences
-chart.w_differences.subtitle = Range: {0}-km {1,number,#.###} - {2,number,#.###}
+chart.w_differences.subtitle = {0}
chart.w_differences.yaxis.label = m
chart.w_differences.yaxis.second.label = W [NN + m]
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/resources/messages_de.properties
--- a/artifacts/src/main/resources/messages_de.properties Mon Sep 23 11:37:13 2013 +0200
+++ b/artifacts/src/main/resources/messages_de.properties Tue Sep 24 12:29:44 2013 +0200
@@ -158,6 +158,7 @@
chart.longitudinal.section.title = W-L\u00e4ngsschnitt
chart.longitudinal.section.subtitle = Bereich: {0}-km {1,number,#.###} - {2,number,#.###}
chart.longitudinal.section.shortsubtitle = {0}
+chart.longitudinal.section.locsubtitle = {0} km {1,number,#.###}
chart.longitudinal.section.xaxis.label = {0}-km
chart.longitudinal.section.yaxis.label = W [{0}]
chart.longitudinal.section.yaxis.second.label = Q [m\u00b3/s]
@@ -207,7 +208,7 @@
chart.normalized.reference.curve.title = Reduzierte Bezugslinie
chart.w_differences.title = Differenzen
-chart.w_differences.subtitle = Range: {0}-km {1,number,#.###} - {2,number,#.###}
+chart.w_differences.subtitle = {0}
chart.w_differences.yaxis.label = m
chart.w_differences.yaxis.second.label = W [NN + m]
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/resources/messages_de_DE.properties
--- a/artifacts/src/main/resources/messages_de_DE.properties Mon Sep 23 11:37:13 2013 +0200
+++ b/artifacts/src/main/resources/messages_de_DE.properties Tue Sep 24 12:29:44 2013 +0200
@@ -157,6 +157,7 @@
chart.longitudinal.section.title = W-L\u00e4ngsschnitt
chart.longitudinal.section.subtitle = Bereich: {0}-km {1,number,#.###} - {2,number,#.###}
chart.longitudinal.section.shortsubtitle = {0}
+chart.longitudinal.section.locsubtitle = {0} km {1,number,#.###}
chart.longitudinal.section.xaxis.label = {0}-km
chart.longitudinal.section.yaxis.label = W [{0}]
chart.longitudinal.section.yaxis.second.label = Q [m\u00b3/s]
@@ -205,7 +206,7 @@
chart.normalized.reference.curve.title = Reduzierte Bezugslinie
chart.w_differences.title = Differenzen
-chart.w_differences.subtitle = Strecke: {0}-km {1,number,#.###} - {2,number,#.###}
+chart.w_differences.subtitle = {0}
chart.w_differences.yaxis.label = m
chart.w_differences.yaxis.second.label = W [NN + m]
diff -r bdadffad35b1 -r 3c7471b929d1 artifacts/src/main/resources/messages_en.properties
--- a/artifacts/src/main/resources/messages_en.properties Mon Sep 23 11:37:13 2013 +0200
+++ b/artifacts/src/main/resources/messages_en.properties Tue Sep 24 12:29:44 2013 +0200
@@ -157,6 +157,7 @@
chart.longitudinal.section.title = W-Longitudinal Section
chart.longitudinal.section.subtitle = Range: {0}-km {1,number,#.###} - {2,number,#.###}
chart.longitudinal.section.shortsubtitle = {0}
+chart.longitudinal.section.locsubtitle = {0} km {1,number,#.###}
chart.longitudinal.section.xaxis.label = {0}-km
chart.longitudinal.section.yaxis.label = W [{0}]
chart.longitudinal.section.yaxis.second.label = Q [m\u00b3/s]
@@ -210,7 +211,7 @@
chart.normalized.reference.curve.title = Reduced Reference Curve
chart.w_differences.title = Differences
-chart.w_differences.subtitle = Range: {0}-km {1,number,#.###} - {2,number,#.###}
+chart.w_differences.subtitle = {0}
chart.w_differences.yaxis.label = m
chart.w_differences.yaxis.second.label = W [NN + m]
More information about the Dive4elements-commits
mailing list