[PATCH 1 of 2] Cleanup of ChartGenerator and ChartGenerator2 code. Put some of the copy/pasted code into a common abstraction
Wald Commits
scm-commit at wald.intevation.org
Tue Jun 5 19:21:31 CEST 2018
# HG changeset patch
# User gernotbelger
# Date 1528219276 -7200
# Node ID 1cc7653ca84f6c7d7f6959e577c0fc0ffa1c52ac
# Parent b8e7f6becf78f04debf46860348950c941468cea
Cleanup of ChartGenerator and ChartGenerator2 code. Put some of the copy/pasted code into a common abstraction.
diff -r b8e7f6becf78 -r 1cc7653ca84f artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/AbstractSInfoLineProcessor.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/AbstractSInfoLineProcessor.java Tue Jun 05 19:10:38 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/AbstractSInfoLineProcessor.java Tue Jun 05 19:21:16 2018 +0200
@@ -31,6 +31,8 @@
abstract class AbstractSInfoLineProcessor<RESULT extends AbstractSInfoCalculationResult> extends AbstractSInfoProcessor {
+ private static final double GAP_DISTANCE = 0.101;
+
public AbstractSInfoLineProcessor(final String i18nAxisLabel, final Set<String> handledFacetType) {
super(i18nAxisLabel, handledFacetType);
}
@@ -38,7 +40,7 @@
@Override
protected final String generateSeries(final DiagramGenerator generator, final ArtifactAndFacet bundle, final ThemeDocument theme, final boolean visible) {
- final CallContext context = generator.getCallContext();
+ final CallContext context = generator.getContext();
final Map<String, String> metaData = bundle.getFacet().getMetaData();
final Artifact artifact = bundle.getArtifact();
@@ -57,7 +59,7 @@
final double[][] points = generatePoints(context, artifact, data, facetName);
- StyledSeriesBuilder.addPoints(series, points, true);
+ StyledSeriesBuilder.addPoints(series, points, true, GAP_DISTANCE);
generator.addAxisSeries(series, getAxisName(), visible);
return metaData.get("Y");
diff -r b8e7f6becf78 -r 1cc7653ca84f artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/FlowDepthDevelopmentProcessor.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/FlowDepthDevelopmentProcessor.java Tue Jun 05 19:10:38 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/FlowDepthDevelopmentProcessor.java Tue Jun 05 19:21:16 2018 +0200
@@ -22,7 +22,7 @@
private static final String I18N_AXIS_LABEL = "sinfo.chart.flow_depth_development.section.yaxis.label";
- private static final String SINFO_CHART_FLOW_DEPTH_DEVELOPMENT_YAXIS_LABEL = "sinfo.chart.flow_depth.yaxis.label";
+ private static final String SINFO_CHART_FLOW_DEPTH_DEVELOPMENT_YAXIS_LABEL = "sinfo.chart.flow_depth_development.yaxis.label";
/* Theme name, usually defined in 'FacetTypes', but that is soooo bad dependencies... */
// REMARK: these must end with 'filtered' so extra handling happens in chart: point are always recalculated, because
diff -r b8e7f6becf78 -r 1cc7653ca84f artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/InfrastructureHeightProcessor.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/InfrastructureHeightProcessor.java Tue Jun 05 19:10:38 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/InfrastructureHeightProcessor.java Tue Jun 05 19:21:16 2018 +0200
@@ -56,7 +56,7 @@
@Override
protected String generateSeries(final DiagramGenerator generator, final ArtifactAndFacet bundle, final ThemeDocument theme, final boolean visible) {
- final CallContext context = generator.getCallContext();
+ final CallContext context = generator.getContext();
final Map<String, String> metaData = bundle.getFacet().getMetaData();
final Artifact artifact = bundle.getArtifact();
diff -r b8e7f6becf78 -r 1cc7653ca84f artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/PredefinedChannelDepthProcessor.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/PredefinedChannelDepthProcessor.java Tue Jun 05 19:10:38 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/PredefinedChannelDepthProcessor.java Tue Jun 05 19:21:16 2018 +0200
@@ -56,7 +56,7 @@
@Override
protected String generateSeries(final DiagramGenerator generator, final ArtifactAndFacet bundle, final ThemeDocument theme, final boolean visible) {
- final CallContext context = generator.getCallContext();
+ final CallContext context = generator.getContext();
final Map<String, String> metaData = bundle.getFacet().getMetaData();
final Artifact artifact = bundle.getArtifact();
diff -r b8e7f6becf78 -r 1cc7653ca84f artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/PredefinedChannelWidthProcessor.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/PredefinedChannelWidthProcessor.java Tue Jun 05 19:10:38 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/PredefinedChannelWidthProcessor.java Tue Jun 05 19:21:16 2018 +0200
@@ -56,7 +56,7 @@
@Override
protected String generateSeries(final DiagramGenerator generator, final ArtifactAndFacet bundle, final ThemeDocument theme, final boolean visible) {
- final CallContext context = generator.getCallContext();
+ final CallContext context = generator.getContext();
final Map<String, String> metaData = bundle.getFacet().getMetaData();
final Artifact artifact = bundle.getArtifact();
diff -r b8e7f6becf78 -r 1cc7653ca84f artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/PredefinedDepthEvolPerYearProcessor.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/PredefinedDepthEvolPerYearProcessor.java Tue Jun 05 19:10:38 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/PredefinedDepthEvolPerYearProcessor.java Tue Jun 05 19:21:16 2018 +0200
@@ -56,7 +56,7 @@
@Override
protected String generateSeries(final DiagramGenerator generator, final ArtifactAndFacet bundle, final ThemeDocument theme, final boolean visible) {
- final CallContext context = generator.getCallContext();
+ final CallContext context = generator.getContext();
final Map<String, String> metaData = bundle.getFacet().getMetaData();
final Artifact artifact = bundle.getArtifact();
diff -r b8e7f6becf78 -r 1cc7653ca84f artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/PredefinedDepthEvolProcessor.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/PredefinedDepthEvolProcessor.java Tue Jun 05 19:10:38 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/PredefinedDepthEvolProcessor.java Tue Jun 05 19:21:16 2018 +0200
@@ -56,7 +56,7 @@
@Override
protected String generateSeries(final DiagramGenerator generator, final ArtifactAndFacet bundle, final ThemeDocument theme, final boolean visible) {
- final CallContext context = generator.getCallContext();
+ final CallContext context = generator.getContext();
final Map<String, String> metaData = bundle.getFacet().getMetaData();
final Artifact artifact = bundle.getArtifact();
diff -r b8e7f6becf78 -r 1cc7653ca84f artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/PredefinedFlowDepthProcessor.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/PredefinedFlowDepthProcessor.java Tue Jun 05 19:10:38 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/PredefinedFlowDepthProcessor.java Tue Jun 05 19:21:16 2018 +0200
@@ -14,7 +14,6 @@
import java.util.Map;
import java.util.Set;
-import org.apache.log4j.Logger;
import org.dive4elements.artifactdatabase.state.ArtifactAndFacet;
import org.dive4elements.artifacts.Artifact;
import org.dive4elements.artifacts.CallContext;
@@ -32,8 +31,6 @@
*/
public class PredefinedFlowDepthProcessor extends AbstractSInfoProcessor {
- private final static Logger log = Logger.getLogger(PredefinedFlowDepthProcessor.class);
-
public static final String FACET_PREDEFINED_FLOW_DEPTH = "sinfo_facet_predefined_flowdepth";
private static final String I18N_AXIS_LABEL = "sinfo.chart.flow_depth.section.yaxis.label";
@@ -51,7 +48,7 @@
@Override
protected String generateSeries(final DiagramGenerator generator, final ArtifactAndFacet bundle, final ThemeDocument theme, final boolean visible) {
- final CallContext context = generator.getCallContext();
+ final CallContext context = generator.getContext();
final Map<String, String> metaData = bundle.getFacet().getMetaData();
final Artifact artifact = bundle.getArtifact();
diff -r b8e7f6becf78 -r 1cc7653ca84f artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/PredefinedTkhProcessor.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/PredefinedTkhProcessor.java Tue Jun 05 19:10:38 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/PredefinedTkhProcessor.java Tue Jun 05 19:21:16 2018 +0200
@@ -13,7 +13,6 @@
import java.util.HashSet;
import java.util.Set;
-import org.apache.log4j.Logger;
import org.dive4elements.artifactdatabase.state.ArtifactAndFacet;
import org.dive4elements.artifacts.CallContext;
import org.dive4elements.river.exports.DiagramGenerator;
@@ -30,8 +29,6 @@
*/
public class PredefinedTkhProcessor extends AbstractSInfoProcessor {
- private final static Logger log = Logger.getLogger(PredefinedTkhProcessor.class);
-
public static final String FACET_PREDEFINED_TKH = "sinfo_facet_predefined_tkh";
private static final String I18N_AXIS_LABEL = "sinfo.chart.tkh.section.yaxis.label";
@@ -48,7 +45,7 @@
@Override
protected String generateSeries(final DiagramGenerator generator, final ArtifactAndFacet bundle, final ThemeDocument theme, final boolean visible) {
- final CallContext context = generator.getCallContext();
+ final CallContext context = generator.getContext();
final String facetName = bundle.getFacetName();
final AbstractTkhCalculationResult data = (AbstractTkhCalculationResult) bundle.getData(context);
diff -r b8e7f6becf78 -r 1cc7653ca84f artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/TkhProcessor.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/TkhProcessor.java Tue Jun 05 19:10:38 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/TkhProcessor.java Tue Jun 05 19:21:16 2018 +0200
@@ -46,7 +46,7 @@
@Override
protected String generateSeries(final DiagramGenerator generator, final ArtifactAndFacet bundle, final ThemeDocument theme, final boolean visible) {
- final CallContext context = generator.getCallContext();
+ final CallContext context = generator.getContext();
final String facetName = bundle.getFacetName();
final AbstractTkhCalculationResult data = (AbstractTkhCalculationResult) bundle.getData(context);
diff -r b8e7f6becf78 -r 1cc7653ca84f artifacts/src/main/java/org/dive4elements/river/exports/AbstractChartGenerator.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/AbstractChartGenerator.java Tue Jun 05 19:10:38 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/AbstractChartGenerator.java Tue Jun 05 19:21:16 2018 +0200
@@ -9,52 +9,499 @@
*/
package org.dive4elements.river.exports;
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.Paint;
+import java.awt.Stroke;
+import java.awt.TexturePaint;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.BufferedImage;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.text.DateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+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.FLYS;
import org.dive4elements.river.artifacts.D4EArtifact;
import org.dive4elements.river.artifacts.access.RangeAccess;
import org.dive4elements.river.artifacts.access.RiverAccess;
+import org.dive4elements.river.artifacts.resources.Resources;
+import org.dive4elements.river.artifacts.sinfo.util.CalculationUtils;
+import org.dive4elements.river.collections.D4EArtifactCollection;
+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.themes.ThemeDocument;
+import org.dive4elements.river.utils.Formatter;
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;
/**
+ * This class re-unites the tremendous copy/paste code from ChartGenerator and ChartGenerator2. Code is still awful and
+ * encapsulation is broken in too many places.
+ * TODO: instead of deep inheritances, delegate to classes that define the various behaviors.
+ *
* @author Gernot Belger
*/
-// FIXME: this class is intended to contain all duplicate code from ChartGenerator and ChartGenerator2; who will clean
-// up this mess...?
abstract class AbstractChartGenerator implements OutGenerator {
+
+ protected static final Logger log = Logger.getLogger(AbstractChartGenerator.class);
+
+ private static final int DEFAULT_CHART_WIDTH = 600;
+
+ private static final int DEFAULT_CHART_HEIGHT = 400;
+
+ private static final Color DEFAULT_GRID_COLOR = Color.GRAY;
+
+ private static final float DEFAULT_GRID_LINE_WIDTH = 0.3f;
+
+ protected static final String DEFAULT_FONT_NAME = "Tahoma";
+
+ protected static final int DEFAULT_FONT_SIZE = 12;
+
+ private static final String DEFAULT_CHART_FORMAT = "png";
+
private static final String XPATH_CHART_EXPORT = "/art:action/art:attributes/art:export/@art:value";
- // TODO: move real code here
- protected abstract D4EArtifact getArtifact();
+ private static final String XPATH_CHART_SIZE = "/art:action/art:attributes/art:size";
+
+ private static final String XPATH_CHART_FORMAT = "/art:action/art:attributes/art:format/@art:value";
+
+ private static final String XPATH_CHART_X_RANGE = "/art:action/art:attributes/art:xrange";
+
+ private static final String XPATH_CHART_Y_RANGE = "/art:action/art:attributes/art:yrange";
+
+ /** The document of the incoming out() request. */
+ private Document request;
+
+ /** The output stream where the data should be written to. */
+ private OutputStream out;
+
+ /** Artifact that is used to decorate the chart with meta information. */
+ private Artifact master;
+
+ /** Map of datasets ("index"). */
+ private final SortedMap<Integer, AxisDataset> datasets = new TreeMap<>();
+
+ /** List of annotations to insert in plot. */
+ private final List<RiverAnnotation> annotations = new ArrayList<>();
+
+ private String outName;
+
+ /** The settings that should be used during output creation. */
+ private Settings settings;
/** The CallContext object. */
- // TODO: move real code here
- protected abstract CallContext getContext();
+ private CallContext context;
+
+ @Override
+ public void init(final String outName, final Document request, final OutputStream out, final CallContext context) {
+ log.debug("ChartGenerator.init");
+
+ this.outName = outName;
+ this.request = request;
+ this.out = out;
+ this.context = context;
+ }
+
+ @Override
+ public void setup(final Object config) {
+ }
+
+ /** Sets the master artifact. */
+ @Override
+ public void setMasterArtifact(final Artifact master) {
+ this.master = master;
+ }
+
+ /**
+ * Gets the master artifact.
+ *
+ * @return the master artifact.
+ */
+ public Artifact getMaster() {
+ return this.master;
+ }
+
+ protected final Map<Integer, AxisDataset> getDatasets() {
+ return this.datasets;
+ }
+
+ @Override
+ public void setCollection(final D4EArtifactCollection collection) {
+ /* we do not need it */
+ }
+
+ protected final D4EArtifact getArtifact() {
+ // FIXME: should already made sure when this member is set
+ return (D4EArtifact) this.master;
+ }
+
+ public final CallContext getContext() {
+ return this.context;
+ }
/** The document of the incoming out() request. */
- // TODO: move real code here
- protected abstract Document getRequest();
+ protected final Document getRequest() {
+ return this.request;
+ }
+
+ /**
+ * Adds annotations to list. The given annotation will be visible.
+ */
+ public final void addAnnotations(final RiverAnnotation annotation) {
+ this.annotations.add(annotation);
+ }
+
+ /**
+ * This method needs to be implemented by concrete subclasses to create new
+ * instances of JFreeChart.
+ *
+ * @param context2
+ *
+ * @return a new instance of a JFreeChart.
+ */
+ protected abstract JFreeChart generateChart(CallContext context2);
+
+ /**
+ * 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);
+
+ @Override
+ public void generate() throws IOException {
+ doGenerate(this.context, this.out, this.outName);
+ }
+
+ protected abstract void doGenerate(CallContext context, OutputStream out, String outName) throws IOException;
+
+ protected abstract Series getSeriesOf(XYDataset dataset, int idx);
+
+ /**
+ * Returns the default title of a chart.
+ *
+ * @param context2
+ *
+ * @return the default title of a chart.
+ */
+ protected abstract String getDefaultChartTitle(CallContext context);
+
+ /**
+ * 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];
+ */
+ protected abstract Range[] getRangesForAxis(int index);
+
+ protected abstract Bounds getXBounds(int axis);
+
+ protected abstract void setXBounds(int axis, Bounds bounds);
+
+ protected abstract Bounds getYBounds(int axis);
+
+ protected abstract void setYBounds(int axis, Bounds bounds);
+
+ // /**
+ // * Retuns the call context. May be null if init hasn't been called yet.
+ // *
+ // * @return the CallContext instance
+ // */
+ // protected final CallContext getCallContext() {
+ // return this.context;
+ // }
+ //
+
+ @Override
+ public final void setSettings(final Settings settings) {
+ this.settings = settings;
+ }
+
+ /**
+ * 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>.
+ */
+ protected final ChartSettings getChartSettings() {
+ if (this.settings instanceof ChartSettings) {
+ return (ChartSettings) this.settings;
+ }
+
+ return null;
+ }
+
+ /**
+ * Return instance of <i>ChartSettings</i> with a chart specific section
+ * but with no axes settings.
+ *
+ * @return an instance of <i>ChartSettings</i>.
+ */
+ @Override
+ public final Settings getSettings() {
+ if (this.settings != null)
+ return this.settings;
+
+ final ChartSettings settings = new ChartSettings();
+
+ final ChartSection chartSection = buildChartSection(this.context);
+ final LegendSection legendSection = buildLegendSection();
+ final ExportSection exportSection = buildExportSection();
+
+ settings.setChartSection(chartSection);
+ settings.setLegendSection(legendSection);
+ settings.setExportSection(exportSection);
+
+ final List<AxisSection> axisSections = buildAxisSections();
+ for (final AxisSection axisSection : axisSections)
+ settings.addAxisSection(axisSection);
+
+ return settings;
+ }
+
+ protected abstract ChartSection buildChartSection(CallContext context);
+
+ /**
+ * Creates a new <i>LegendSection</i>.
+ *
+ * @return a new <i>LegendSection</i>.
+ */
+ private LegendSection buildLegendSection() {
+ final 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>.
+ */
+ private ExportSection buildExportSection() {
+ final ExportSection exportSection = new ExportSection();
+ exportSection.setWidth(DEFAULT_CHART_WIDTH);
+ exportSection.setHeight(DEFAULT_CHART_HEIGHT);
+ exportSection.setMetadata(true);
+ 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.
+ */
+ private List<AxisSection> buildAxisSections() {
+ final List<AxisSection> axisSections = new ArrayList<>();
+
+ 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() {
+ final List<AxisSection> axisSections = new ArrayList<>();
+
+ final String identifier = "X";
+
+ final 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 X-Axis label of a chart.
+ *
+ * @return the X-Axis label of a chart.
+ */
+ protected final String getXAxisLabel() {
+ final ChartSettings chartSettings = getChartSettings();
+ if (chartSettings == null) {
+ return getDefaultXAxisLabel(this.context);
+ }
+
+ final AxisSection as = chartSettings.getAxisSection("X");
+ if (as != null) {
+ final String label = as.getLabel();
+
+ if (label != null) {
+ return label;
+ }
+ }
+
+ return getDefaultXAxisLabel(this.context);
+ }
+
+ protected abstract List<AxisSection> buildYAxisSections();
+
+ /**
+ * Returns the default X-Axis label of a chart.
+ *
+ * @param context2
+ *
+ * @return the default X-Axis label of a chart.
+ */
+ protected abstract String getDefaultXAxisLabel(final CallContext context2);
+
+ /** Generate the diagram as an image. */
+ protected final void generateImage(final CallContext context) throws IOException {
+ log.debug("ChartGenerator2.generateImage");
+
+ final JFreeChart chart = generateChart(context);
+
+ final String format = getFormat();
+ int[] size = getSize();
+
+ if (size == null)
+ size = getExportDimension();
+
+ this.context.putContextValue("chart.width", size[0]);
+ this.context.putContextValue("chart.height", size[1]);
+
+ if (format.equals(ChartExportHelper.FORMAT_PNG)) {
+ this.context.putContextValue("chart.image.format", "png");
+
+ ChartExportHelper.exportImage(this.out, chart, this.context);
+ } else if (format.equals(ChartExportHelper.FORMAT_PDF)) {
+ preparePDFContext(this.context);
+
+ ChartExportHelper.exportPDF(this.out, chart, this.context);
+ } else if (format.equals(ChartExportHelper.FORMAT_SVG)) {
+ prepareSVGContext(this.context);
+
+ ChartExportHelper.exportSVG(this.out, chart, this.context);
+ } else if (format.equals(ChartExportHelper.FORMAT_CSV)) {
+ this.context.putContextValue("chart.image.format", "csv");
+
+ ChartExportHelper.exportCSV(this.out, chart, this.context);
+ }
+ }
/**
* Adds a metadata sub-title to the chart if it gets exported
*/
- protected final void addMetadataSubtitle(final JFreeChart chart) {
- if (isExport()) {
- final String text = ChartExportHelper.createMetadataSubtitle(getArtifact(), getContext(), getRiverName());
- chart.addSubtitle(new TextTitle(text));
- }
+ protected final void addMetadataSubtitle(final CallContext context, final JFreeChart chart) {
+ if ((!isExport() || !isExportMetadata()))
+ return;
+
+ final String version = FLYS.VERSION;
+ final String user = CalculationUtils.findArtifactUser(context, getArtifact());
+ final Locale locale = Resources.getLocale(context.getMeta());
+ final DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, locale);
+ final String dateText = df.format(new Date());
+
+ final String text = Resources.getMsg(context.getMeta(), "chart.subtitle.metadata", "default", version, user, dateText);
+
+ chart.addSubtitle(new TextTitle(text));
+ }
+
+ private boolean isExportMetadata() {
+ final ChartSettings chartSettings = getChartSettings();
+ if (chartSettings == null)
+ return true;
+
+ final ExportSection exportSection = chartSettings.getExportSection();
+ if (exportSection == null)
+ return true;
+
+ return exportSection.getMetadata();
}
/**
* This method returns the export flag specified in the <i>request</i> document
* or <i>false</i> if no export is specified in <i>request</i>.
*/
- protected final boolean isExport() {
+ private boolean isExport() {
final Boolean export = (Boolean) XMLUtils.xpath(getRequest(), XPATH_CHART_EXPORT, XPathConstants.BOOLEAN, ArtifactNamespaceContext.INSTANCE);
return export == null ? false : export;
@@ -74,4 +521,790 @@
final RangeAccess rangeAccess = new RangeAccess(flys);
return rangeAccess.getKmRange();
}
+
+ /**
+ * 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>,
+ * otherwise 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.
+ */
+ private boolean isGridVisible(final ChartSettings settings) {
+ final ChartSection cs = settings.getChartSection();
+ return cs.getDisplayGrid();
+ }
+
+ /**
+ * 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 final boolean isLegendVisible() {
+ final ChartSettings chartSettings = getChartSettings();
+ if (chartSettings == null)
+ return true;
+
+ final LegendSection ls = chartSettings.getLegendSection();
+ return ls.getVisibility();
+ }
+
+ /**
+ * 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 final int getXAxisLabelFontSize() {
+ final ChartSettings chartSettings = getChartSettings();
+ if (chartSettings == null) {
+ return DEFAULT_FONT_SIZE;
+ }
+
+ final AxisSection as = chartSettings.getAxisSection("X");
+ final Integer fontSize = as.getFontSize();
+
+ return fontSize != null ? fontSize : DEFAULT_FONT_SIZE;
+ }
+
+ /**
+ * 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.
+ */
+ private int getLegendFontSize() {
+
+ final ChartSettings chartSettings = getChartSettings();
+ if (chartSettings == null)
+ return DEFAULT_FONT_SIZE;
+
+ final LegendSection ls = chartSettings.getLegendSection();
+ if (ls == null)
+ return DEFAULT_FONT_SIZE;
+
+ final Integer fontSize = ls.getFontSize();
+ if (fontSize == null)
+ return DEFAULT_FONT_SIZE;
+
+ return fontSize;
+ }
+
+ /**
+ * 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.
+ */
+ protected final LegendItem createLegendItem(final ThemeDocument theme, final String name) {
+ // OPTIMIZE Pass font, parsed Theme items.
+
+ Color color = theme.parseLineColorField();
+ if (color == null)
+ color = Color.BLACK;
+
+ final LegendItem legendItem = new LegendItem(name, color);
+ legendItem.setLabelFont(createLegendLabelFont());
+ return legendItem;
+ }
+
+ /**
+ * Create new legend entries, dependent on settings.
+ *
+ * @param plot
+ * The plot for which to modify the legend.
+ */
+ protected final void aggregateLegendEntries(final XYPlot plot) {
+
+ final ChartSettings chartSettings = getChartSettings();
+ if (chartSettings == null)
+ return;
+
+ final Integer threshold = chartSettings.getLegendSection().getAggregationThreshold();
+
+ final int aggrThreshold = threshold != null ? threshold.intValue() : 0;
+
+ LegendProcessor.aggregateLegendEntries(plot, aggrThreshold);
+ }
+
+ /**
+ * 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>.
+ */
+ private final Font createLegendLabelFont() {
+ return new Font(DEFAULT_FONT_NAME, Font.PLAIN, getLegendFontSize());
+ }
+
+ /**
+ * 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(final XYPlot plot) {
+ final Stroke gridStroke = new BasicStroke(DEFAULT_GRID_LINE_WIDTH, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 3.0f, new float[] { 3.0f }, 0.0f);
+
+ final ChartSettings cs = getChartSettings();
+ final 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 method is used to extract the current locale from instance variable <i>context</i>.
+ *
+ * @return the current locale.
+ */
+ protected final Locale getLocale() {
+ final CallMeta meta = this.context.getMeta();
+ final PreferredLocale[] prefs = meta.getLanguages();
+
+ final int len = prefs != null ? prefs.length : 0;
+
+ final 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 final String msg(final String key, final String def) {
+ return Resources.getMsg(this.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 final String msg(final String key) {
+ return Resources.getMsg(this.context.getMeta(), key, key);
+ }
+
+ public final String msg(final String key, final String def, final Object[] args) {
+ return Resources.getMsg(this.context.getMeta(), key, def, args);
+ }
+
+ /**
+ * 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(final XYPlot plot) {
+ log.debug("addDatasets()");
+
+ // AxisDatasets are sorted, but some might be empty.
+ // Thus, generate numbering on the fly.
+ int axisIndex = 0;
+ int datasetIndex = 0;
+
+ for (final Map.Entry<Integer, AxisDataset> entry : this.datasets.entrySet()) {
+ if (!entry.getValue().isEmpty()) {
+ // Add axis and range information.
+ final AxisDataset axisDataset = entry.getValue();
+ final 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 (final XYDataset dataset : axisDataset.getDatasets()) {
+ try {
+ plot.setDataset(datasetIndex, dataset);
+ plot.mapDatasetToRangeAxis(datasetIndex, axisIndex);
+
+ applyThemes(plot, dataset, datasetIndex, axisDataset.isArea(dataset));
+
+ datasetIndex++;
+ }
+ catch (final RuntimeException re) {
+ log.error(re);
+ }
+ }
+
+ axisDataset.setPlotAxisIndex(axisIndex);
+ axisIndex++;
+ }
+ }
+ }
+
+ /**
+ * Create Y (range) axis for given index.
+ * Shall be implemented by subclasses.
+ */
+ protected abstract NumberAxis createYAxis(final int index);
+
+ /**
+ * @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.
+ */
+ private void applyThemes(final XYPlot plot, final XYDataset series, final int idx, final boolean isArea) {
+ if (isArea) {
+ applyAreaTheme(plot, (StyledAreaSeriesCollection) series, idx);
+ } else {
+ applyLineTheme(plot, series, idx);
+ }
+ }
+
+ /**
+ * 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(final Range range) {
+ if (range == null) {
+ return null;
+ } else if (range.getLowerBound() == range.getUpperBound()) {
+ final 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.
+ */
+ private XYLineAndShapeRenderer createRenderer(final XYPlot plot, final int idx) {
+ log.debug("Create EnhancedLineAndShapeRenderer for idx: " + idx);
+
+ final EnhancedLineAndShapeRenderer r = new EnhancedLineAndShapeRenderer(true, false);
+
+ r.setPlot(plot);
+
+ return r;
+ }
+
+ /**
+ * 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.
+ */
+ private void applyLineTheme(final XYPlot plot, final XYDataset dataset, final int idx) {
+ log.debug("Apply LineTheme for dataset at index: " + idx);
+
+ final LegendItemCollection lic = new LegendItemCollection();
+ final LegendItemCollection anno = plot.getFixedLegendItems();
+
+ final Font legendFont = createLegendLabelFont();
+
+ final XYLineAndShapeRenderer renderer = createRenderer(plot, idx);
+
+ for (int s = 0, num = dataset.getSeriesCount(); s < num; s++) {
+ final Series series = getSeriesOf(dataset, s);
+
+ if (series instanceof StyledSeries) {
+ final 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 {
+ log.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.
+ */
+ private final void applyAreaTheme(final XYPlot plot, final StyledAreaSeriesCollection area, final int idx) {
+ final LegendItemCollection lic = new LegendItemCollection();
+ final LegendItemCollection anno = plot.getFixedLegendItems();
+
+ final Font legendFont = createLegendLabelFont();
+
+ log.debug("Registering an 'area'renderer at idx: " + idx);
+
+ final 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(this.context.getMeta(), 2, 4));
+
+ dRenderer.setAreaLabelTemplate(Resources.getMsg(this.context.getMeta(), "area.label.template", "Area=%sm2"));
+
+ final LegendItem legendItem = dRenderer.getLegendItem(idx, 0);
+ if (legendItem != null) {
+ legendItem.setLabelFont(legendFont);
+ lic.add(legendItem);
+ } else {
+ log.warn("Could not get LegentItem for renderer: " + idx + ", series-idx " + 0);
+ }
+
+ if (anno != null) {
+ lic.addAll(anno);
+ }
+
+ plot.setFixedLegendItems(lic);
+ }
+
+ /**
+ * Returns a transparently textured paint.
+ *
+ * @return a transparently textured paint.
+ */
+ private static Paint createTransparentPaint() {
+ // TODO why not use a transparent color?
+ final BufferedImage texture = new BufferedImage(1, 1, BufferedImage.TYPE_4BYTE_ABGR);
+
+ return new TexturePaint(texture, new Rectangle2D.Double(0d, 0d, 0d, 0d));
+ }
+
+ private void preparePDFContext(final CallContext context) {
+ final 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);
+ }
+
+ private void prepareSVGContext(final CallContext context) {
+ final int[] dimension = getExportDimension();
+
+ context.putContextValue("chart.width", dimension[0]);
+ context.putContextValue("chart.height", dimension[1]);
+ context.putContextValue("chart.encoding", ChartExportHelper.DEFAULT_ENCODING);
+ }
+
+ /**
+ * 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(final CallContext context, final JFreeChart chart) {
+ final String subtitle = getChartSubtitle(this.context);
+
+ if (subtitle != null && subtitle.length() > 0) {
+ chart.addSubtitle(new TextTitle(subtitle));
+ }
+ }
+
+ protected abstract String getChartSubtitle(CallContext context);
+
+ /**
+ * 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.
+ */
+ protected final void addAxisDataset(final XYDataset dataset, final int idx, final boolean visible) {
+ if (dataset == null || idx < 0) {
+ return;
+ }
+
+ final AxisDataset axisDataset = getAxisDataset(idx);
+
+ final Bounds[] xyBounds = ChartHelper.getBounds(dataset);
+
+ if (xyBounds == null) {
+ log.warn("Skip XYDataset for Axis (invalid ranges): " + idx);
+ return;
+ }
+
+ if (visible) {
+ if (log.isDebugEnabled()) {
+ log.debug("Add new AxisDataset at index: " + idx);
+ log.debug("X extent: " + xyBounds[0]);
+ log.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.
+ */
+ protected final AxisDataset getAxisDataset(final int idx) {
+ AxisDataset axisDataset = this.datasets.get(idx);
+
+ if (axisDataset == null) {
+ axisDataset = createAxisDataset(idx);
+ this.datasets.put(idx, axisDataset);
+ }
+
+ return axisDataset;
+ }
+
+ /**
+ * 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 final int[] getSize() {
+ final int[] size = new int[2];
+
+ final Element sizeEl = (Element) XMLUtils.xpath(this.request, XPATH_CHART_SIZE, XPathConstants.NODE, ArtifactNamespaceContext.INSTANCE);
+
+ if (sizeEl != null) {
+ final String uri = ArtifactNamespaceContext.NAMESPACE_URI;
+
+ final String w = sizeEl.getAttributeNS(uri, "width");
+ final 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 (final NumberFormatException nfe) {
+ log.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.
+ */
+ private String getFormat() {
+ final String format = (String) XMLUtils.xpath(this.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 final String[] getDomainAxisRangeFromRequest() {
+ final Element xrange = (Element) XMLUtils.xpath(this.request, XPATH_CHART_X_RANGE, XPathConstants.NODE, ArtifactNamespaceContext.INSTANCE);
+
+ if (xrange == null) {
+ return null;
+ }
+
+ final String uri = ArtifactNamespaceContext.NAMESPACE_URI;
+
+ final String lower = xrange.getAttributeNS(uri, "from");
+ final 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 final String[] getValueAxisRangeFromRequest() {
+ final Element yrange = (Element) XMLUtils.xpath(this.request, XPATH_CHART_Y_RANGE, XPathConstants.NODE, ArtifactNamespaceContext.INSTANCE);
+
+ if (yrange == null) {
+ return null;
+ }
+
+ final String uri = ArtifactNamespaceContext.NAMESPACE_URI;
+
+ final String lower = yrange.getAttributeNS(uri, "from");
+ final 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 final int[] getDefaultSize() {
+ return new int[] { DEFAULT_CHART_WIDTH, DEFAULT_CHART_HEIGHT };
+ }
+
+ /**
+ * This method returns the export dimension specified in ChartSettings as
+ * int array [width,height].
+ *
+ * @return an int array with [width,height].
+ */
+ private int[] getExportDimension() {
+ final ChartSettings chartSettings = getChartSettings();
+ if (chartSettings == null)
+ return new int[] { DEFAULT_CHART_WIDTH, DEFAULT_CHART_HEIGHT };
+
+ final ExportSection export = chartSettings.getExportSection();
+ final Integer width = export.getWidth();
+ final Integer height = export.getHeight();
+
+ if (width != null && height != null) {
+ return new int[] { width, height };
+ }
+
+ return new int[] { 600, 400 };
+ }
+
+ /**
+ * 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.
+ */
+ private String getChartTitle(final ChartSettings settings) {
+ final 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.
+ */
+ protected final String getChartSubtitle(final ChartSettings settings) {
+ final ChartSection cs = settings.getChartSection();
+ return cs != null ? cs.getSubtitle() : 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(final CallContext context) {
+ final ChartSettings chartSettings = getChartSettings();
+
+ if (chartSettings != null) {
+ return getChartTitle(chartSettings);
+ }
+
+ return getDefaultChartTitle(context);
+ }
+
+ /**
+ * This method always returns null. Override it in subclasses that require
+ * subtitles.
+ *
+ * @return null.
+ */
+ protected String getDefaultChartSubtitle(final CallContext context) {
+ // Override this method in subclasses
+ return null;
+ }
+
+ /** Where to place the logo. */
+ protected final String logoHPlace() {
+ final ChartSettings chartSettings = getChartSettings();
+ if (chartSettings != null) {
+ final ChartSection cs = chartSettings.getChartSection();
+ final String place = cs.getLogoHPlacement();
+
+ return place;
+ }
+ return "center";
+ }
+
+ /** Where to place the logo. */
+ protected final String logoVPlace() {
+ final ChartSettings chartSettings = getChartSettings();
+ if (chartSettings != null) {
+ final ChartSection cs = chartSettings.getChartSection();
+ final String place = cs.getLogoVPlacement();
+
+ return place;
+ }
+ return "top";
+ }
+
+ /** Return the logo id from settings. */
+ private String showLogo(final ChartSettings chartSettings) {
+ if (chartSettings != null) {
+ final ChartSection cs = chartSettings.getChartSection();
+ final 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 final String showLogo() {
+ final ChartSettings chartSettings = getChartSettings();
+ return showLogo(chartSettings);
+ }
+
+ /**
+ * 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 final boolean isGridVisible() {
+ return true;
+ }
+
+ protected final void addAnnotationsToRenderer(final XYPlot plot) {
+
+ final AnnotationRenderer annotationRenderer = new AnnotationRenderer(getChartSettings(), this.datasets, DEFAULT_FONT_NAME);
+ annotationRenderer.addAnnotationsToRenderer(plot, this.annotations);
+
+ doAddFurtherAnnotations(plot, this.annotations);
+ }
+
+ /**
+ * Allow further annotation processing, override to implement.
+ *
+ * Does nothing by default.
+ */
+ protected void doAddFurtherAnnotations(final XYPlot plot, final List<RiverAnnotation> annotations) {
+
+ }
}
\ No newline at end of file
diff -r b8e7f6becf78 -r 1cc7653ca84f artifacts/src/main/java/org/dive4elements/river/exports/AnnotationRenderer.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/AnnotationRenderer.java Tue Jun 05 19:21:16 2018 +0200
@@ -0,0 +1,352 @@
+/** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
+ * Software engineering by
+ * Björnsen Beratende Ingenieure GmbH
+ * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+package org.dive4elements.river.exports;
+
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Font;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.SortedMap;
+
+import org.apache.log4j.Logger;
+import org.dive4elements.river.jfree.AxisDataset;
+import org.dive4elements.river.jfree.CollisionFreeXYTextAnnotation;
+import org.dive4elements.river.jfree.RiverAnnotation;
+import org.dive4elements.river.jfree.StickyAxisAnnotation;
+import org.dive4elements.river.themes.LineStyle;
+import org.dive4elements.river.themes.TextStyle;
+import org.dive4elements.river.themes.ThemeDocument;
+import org.jfree.chart.LegendItem;
+import org.jfree.chart.LegendItemCollection;
+import org.jfree.chart.annotations.XYLineAnnotation;
+import org.jfree.chart.annotations.XYTextAnnotation;
+import org.jfree.chart.plot.XYPlot;
+import org.jfree.chart.renderer.xy.XYItemRenderer;
+import org.jfree.ui.TextAnchor;
+
+/**
+ * @author Gernot Belger
+ */
+public final class AnnotationRenderer {
+
+ private static final Logger log = Logger.getLogger(AnnotationRenderer.class);
+
+ private static float ANNOTATIONS_AXIS_OFFSET = 0.02f;
+
+ private final ChartSettings settings;
+
+ private final Map<Integer, AxisDataset> datasets;
+
+ private final String fontName;
+
+ public AnnotationRenderer(final ChartSettings settings, final Map<Integer, AxisDataset> datasets, final String fontName) {
+ this.settings = settings;
+ this.datasets = datasets;
+ this.fontName = fontName;
+ }
+
+ /**
+ * Add annotations (Sticky, Text and hyk zones) to a plot.
+ *
+ * @param annotations
+ * Annotations to add
+ * @param plot
+ * XYPlot to add annotations to.
+ * @param settings
+ * ChartSettings object for settings.
+ * @param datasets
+ * Map of axis index and datasets
+ */
+ public final void addAnnotationsToRenderer(final XYPlot plot, final List<RiverAnnotation> annotations) {
+ if (annotations == null || annotations.isEmpty()) {
+ log.debug("addAnnotationsToRenderer: no annotations.");
+ return;
+ }
+
+ // OPTMIMIZE: Pre-calculate positions
+ final ChartArea area = new ChartArea(plot.getDomainAxis(0), plot.getRangeAxis());
+
+ // Walk over all Annotation sets.
+ for (final RiverAnnotation fa : annotations) {
+
+ // Access text styling, if any.
+ final ThemeDocument theme = fa.getTheme();
+ TextStyle textStyle = null;
+ LineStyle lineStyle = null;
+
+ // Get Theming information and add legend item.
+ if (theme != null) {
+ textStyle = theme.parseComplexTextStyle();
+ lineStyle = theme.parseComplexLineStyle();
+ if (fa.getLabel() != null) {
+ // Legend handling, maybe misplaced?
+ final LegendItemCollection lic = new LegendItemCollection();
+ LegendItemCollection old = plot.getFixedLegendItems();
+
+ Color color = theme.parseLineColorField();
+ if (color == null) {
+ color = Color.BLACK;
+ }
+
+ Color textColor = theme.parseTextColor();
+ if (textColor == null) {
+ textColor = Color.BLACK;
+ }
+
+ final LegendItem newItem = new LegendItem(fa.getLabel(), color);
+
+ final LegendSection ls = this.settings != null ? this.settings.getLegendSection() : null;
+
+ final Integer size = ls != null ? ls.getFontSize() : null;
+
+ newItem.setLabelFont(new Font(this.fontName, Font.PLAIN, size));
+
+ newItem.setLabelPaint(textColor);
+
+ 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 (final StickyAxisAnnotation sta : fa.getAxisTextAnnotations()) {
+ addStickyAnnotation(sta, plot, area, lineStyle, textStyle, theme, this.datasets.get(new Integer(sta.getAxisSymbol())));
+ }
+
+ // Other Text Annotations (e.g. labels of (manual) points).
+ for (final 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
+ */
+ private void addStickyAnnotation(final StickyAxisAnnotation annotation, final XYPlot plot, final ChartArea area, final LineStyle lineStyle,
+ final TextStyle textStyle, final ThemeDocument theme, final AxisDataset dataset) {
+ // OPTIMIZE pre-calculate area-related values
+ final float TEXT_OFF = 0.03f;
+
+ XYLineAnnotation lineAnnotation = null;
+ XYTextAnnotation textAnnotation = null;
+
+ final int axisIndex = annotation.getAxisSymbol();
+ XYItemRenderer renderer = null;
+ if (dataset != null && dataset.getDatasets().length > 0) {
+ renderer = plot.getRendererForDataset(dataset.getDatasets()[0]);
+ } else {
+ renderer = plot.getRenderer();
+ }
+
+ 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 {
+ // Stick to the "right" (opposed to left) Y-Axis.
+ if (axisIndex != 0 && plot.getRangeAxis(axisIndex) != null) {
+ // 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.
+ textAnnotation = new CollisionFreeXYTextAnnotation(annotation.getText(), area.ofRight(TEXT_OFF), annotation.getPos());
+ textAnnotation.setRotationAnchor(TextAnchor.CENTER_RIGHT);
+ textAnnotation.setTextAnchor(TextAnchor.CENTER_RIGHT);
+ lineAnnotation = createRightStickAnnotation(area, annotation.getPos(), lineStyle);
+
+ // hit-lines for duration curve
+ final ChartArea area2 = new ChartArea(plot.getDomainAxis(), plot.getRangeAxis(axisIndex));
+ if (!Float.isNaN(annotation.getHitPoint()) && theme != null) {
+ // New line annotation to hit curve.
+ if (theme.parseShowVerticalLine()) {
+ final XYLineAnnotation hitLineAnnotation = createStickyLineAnnotation(StickyAxisAnnotation.SimpleAxis.X_AXIS, annotation.getHitPoint(),
+ annotation.getPos(),
+ // annotation.getHitPoint(),
+ area2, lineStyle);
+ renderer.addAnnotation(hitLineAnnotation, org.jfree.ui.Layer.BACKGROUND);
+ }
+ if (theme.parseShowHorizontalLine()) {
+ final XYLineAnnotation lineBackAnnotation = createStickyLineAnnotation(StickyAxisAnnotation.SimpleAxis.Y_AXIS2, annotation.getPos(),
+ annotation.getHitPoint(), area2, lineStyle);
+ renderer.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()) {
+ final XYLineAnnotation hitLineAnnotation = createStickyLineAnnotation(StickyAxisAnnotation.SimpleAxis.Y_AXIS, annotation.getPos(),
+ annotation.getHitPoint(), area, lineStyle);
+ renderer.addAnnotation(hitLineAnnotation, org.jfree.ui.Layer.BACKGROUND);
+ }
+ if (theme.parseShowVerticalLine()) {
+ final XYLineAnnotation lineBackAnnotation = createStickyLineAnnotation(StickyAxisAnnotation.SimpleAxis.X_AXIS, annotation.getHitPoint(),
+ annotation.getPos(), area, lineStyle);
+ renderer.addAnnotation(lineBackAnnotation, org.jfree.ui.Layer.BACKGROUND);
+ }
+ }
+ }
+ }
+
+ // Style the text.
+ if (textStyle != null) {
+ textStyle.apply(textAnnotation);
+ }
+
+ // Add the Annotations to renderer.
+ renderer.addAnnotation(textAnnotation, org.jfree.ui.Layer.FOREGROUND);
+ renderer.addAnnotation(lineAnnotation, org.jfree.ui.Layer.FOREGROUND);
+ }
+
+ public final void addYAnnotationsToRenderer(final XYPlot plot, final SortedMap<Integer, RiverAnnotation> yAnnotations) {
+ final List<RiverAnnotation> annotations = new ArrayList<>();
+
+ for (final Map.Entry<Integer, RiverAnnotation> entry : yAnnotations.entrySet()) {
+ final int axis = entry.getKey();
+ final AxisDataset dataset = this.datasets.get(new Integer(axis));
+
+ if (dataset == null || dataset.getRange() == null) {
+ log.warn("No dataset available and active for axis " + axis);
+ } else {
+ final RiverAnnotation ya = entry.getValue();
+ for (final StickyAxisAnnotation sta : ya.getAxisTextAnnotations()) {
+ sta.setAxisSymbol(axis);
+ }
+ annotations.add(ya);
+ }
+ }
+
+ addAnnotationsToRenderer(plot, annotations);
+ }
+
+ /**
+ * 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.
+ */
+ private XYLineAnnotation createGroundStickAnnotation(final ChartArea area, final float pos, final LineStyle lineStyle) {
+ if (lineStyle != null)
+ return new XYLineAnnotation(pos, area.atGround(), pos, area.ofGround(ANNOTATIONS_AXIS_OFFSET), new BasicStroke(lineStyle.getWidth()),
+ lineStyle.getColor());
+
+ 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.
+ */
+ private XYLineAnnotation createRightStickAnnotation(final ChartArea area, final float pos, final LineStyle lineStyle) {
+ if (lineStyle != null)
+ return new XYLineAnnotation(area.atRight(), pos, area.ofRight(ANNOTATIONS_AXIS_OFFSET), pos, new BasicStroke(lineStyle.getWidth()),
+ lineStyle.getColor());
+
+ 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.
+ */
+ private XYLineAnnotation createLeftStickAnnotation(final ChartArea area, final float pos, final LineStyle lineStyle) {
+ if (lineStyle != null)
+ return new XYLineAnnotation(area.atLeft(), pos, area.ofLeft(ANNOTATIONS_AXIS_OFFSET), pos, new BasicStroke(lineStyle.getWidth()),
+ lineStyle.getColor());
+
+ 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(final StickyAxisAnnotation.SimpleAxis axis, final float fromD1, final float toD2,
+ final ChartArea area, final 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;
+ }
+
+ if (lineStyle != null)
+ return new XYLineAnnotation(anchorX1, anchorY1, anchorX2, anchorY2, new BasicStroke(lineStyle.getWidth()), lineStyle.getColor());
+
+ return new XYLineAnnotation(anchorX1, anchorY1, anchorX2, anchorY2);
+ }
+}
\ No newline at end of file
diff -r b8e7f6becf78 -r 1cc7653ca84f artifacts/src/main/java/org/dive4elements/river/exports/AxisSection.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/AxisSection.java Tue Jun 05 19:10:38 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/AxisSection.java Tue Jun 05 19:21:16 2018 +0200
@@ -85,8 +85,8 @@
}
- public Boolean isFixed() {
- return getBooleanValue(FIXATION_ATTR);
+ public boolean isFixed() {
+ return getBooleanValue(FIXATION_ATTR, false);
}
diff -r b8e7f6becf78 -r 1cc7653ca84f artifacts/src/main/java/org/dive4elements/river/exports/ChartExportHelper.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/ChartExportHelper.java Tue Jun 05 19:10:38 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/ChartExportHelper.java Tue Jun 05 19:21:16 2018 +0200
@@ -495,17 +495,4 @@
return origin;
}
-
-
- public static String createMetadataSubtitle(Artifact artifact, final CallContext context, final String riverName) {
-
- final String version = FLYS.VERSION;
- final String user = CalculationUtils.findArtifactUser(context, artifact);
- final Locale locale = Resources.getLocale(context.getMeta());
- final DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, locale);
- final String dateText = df.format(new Date());
-
- return Resources.getMsg(context.getMeta(), "chart.subtitle.metadata", "default", version, user, dateText, riverName);
- }
-}
-// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :
+}
\ No newline at end of file
diff -r b8e7f6becf78 -r 1cc7653ca84f artifacts/src/main/java/org/dive4elements/river/exports/ChartGenerator.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/ChartGenerator.java Tue Jun 05 19:10:38 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/ChartGenerator.java Tue Jun 05 19:21:16 2018 +0200
@@ -8,66 +8,18 @@
package org.dive4elements.river.exports;
-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.access.RiverAccess;
-import org.dive4elements.river.artifacts.access.RangeAccess;
-import org.dive4elements.river.artifacts.D4EArtifact;
-import org.dive4elements.river.artifacts.resources.Resources;
-import org.dive4elements.river.collections.D4EArtifactCollection;
-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.jfree.AxisDataset;
-import org.dive4elements.river.themes.ThemeDocument;
-
-import java.awt.BasicStroke;
-import java.awt.Color;
import java.awt.Font;
-import java.awt.Paint;
-import java.awt.Stroke;
-import java.awt.TexturePaint;
-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.jfree.chart.JFreeChart;
-import org.jfree.chart.LegendItem;
-import org.jfree.chart.LegendItemCollection;
+import org.dive4elements.artifactdatabase.state.ArtifactAndFacet;
+import org.dive4elements.artifacts.CallContext;
+import org.dive4elements.river.jfree.RiverAnnotation;
+import org.dive4elements.river.themes.ThemeDocument;
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;
-
-import org.dive4elements.river.utils.Formatter;
/**
* The base class for chart creation. It should provide some basic things that
@@ -82,57 +34,6 @@
*/
public abstract class ChartGenerator extends AbstractChartGenerator {
- private static Logger log = Logger.getLogger(ChartGenerator.class);
-
- 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";
-
- protected static float ANNOTATIONS_AXIS_OFFSET = 0.02f;
-
- 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;
-
- /** 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 String outName;
-
/**
* A mini interface that allows to walk over the YAXIS enums defined in
* subclasses.
@@ -145,158 +46,8 @@
} // end of YAxisWalker interface
- /**
- * Default constructor that initializes internal data structures.
- */
- public ChartGenerator() {
- datasets = new TreeMap<>();
- }
-
- @Override
- protected final D4EArtifact getArtifact() {
- // FIXME: should already made sure when this member is set
- return (D4EArtifact) this.master;
- }
-
- @Override
- protected final CallContext getContext() {
- return this.context;
- }
-
- @Override
- protected final Document getRequest() {
- return this.request;
- }
-
- @Override
- public void setup(Object config) {
- log.debug("ChartGenerator.setup");
- }
-
- /**
- * 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 YAxisWalker getYAxisWalker();
-
- 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();
-
-
- /**
- * 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 called to retrieve the default label for an Y axis at
- * position <i>pos</i>.
- *
- * @param pos The position of an Y axis.
- *
- * @return the default Y axis label at position <i>pos</i>.
- */
- protected abstract String getDefaultYAxisLabel(int pos);
-
-
- /**
- * 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));
- }
- }
-
-
/**
* Register annotations like MainValues for later plotting
*
@@ -329,148 +80,21 @@
}
}
-
- /**
- * Generate chart.
- */
@Override
- public void generate()
- throws IOException
- {
- log.debug("ChartGenerator.generate");
-
- 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);
- }
+ protected void doGenerate(CallContext context, OutputStream out, String outName) throws IOException {
+ generateImage(context);
}
-
- @Override
- public void init(
- String outName,
- Document request,
- OutputStream out,
- CallContext context
- ) {
- log.debug("ChartGenerator.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 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() {
+ @Override
+ protected ChartSection buildChartSection(final CallContext context) {
ChartSection chartSection = new ChartSection();
- chartSection.setTitle(getChartTitle());
- chartSection.setSubtitle(getChartSubtitle());
+ chartSection.setTitle(getChartTitle(context));
+ chartSection.setSubtitle(getChartSubtitle(context));
chartSection.setDisplayGrid(isGridVisible());
chartSection.setDisplayLogo(showLogo());
chartSection.setLogoVPlacement(logoVPlace());
@@ -478,78 +102,6 @@
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;
- }
-
-
- /**
- * Create 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;
- }
-
-
/**
* Creates a list of Section for the chart's Y axes. This method makes use
* of <i>getYAxisWalker</i> to be able to access all Y axes defined in
@@ -557,8 +109,9 @@
*
* @return a list of Y axis sections.
*/
- protected List<AxisSection> buildYAxisSections() {
- List<AxisSection> axisSections = new ArrayList<AxisSection>();
+ @Override
+ protected final List<AxisSection> buildYAxisSections() {
+ List<AxisSection> axisSections = new ArrayList<>();
YAxisWalker walker = getYAxisWalker();
for (int i = 0, n = walker.length(); i < n; i++) {
@@ -581,127 +134,6 @@
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
@@ -710,171 +142,16 @@
*
* @return the subtitle of a chart.
*/
- protected String getChartSubtitle() {
+ @Override
+ protected String getChartSubtitle(final CallContext context) {
ChartSettings chartSettings = getChartSettings();
- if (chartSettings != null) {
+ if (chartSettings != null)
return getChartSubtitle(chartSettings);
- }
- return getDefaultChartSubtitle();
+ return getDefaultChartSubtitle(context);
}
-
- /**
- * 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;
- }
-
-
/**
* 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
@@ -899,31 +176,6 @@
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 };
- }
-
-
/**
* Returns the Y-Axis label of a chart at position <i>pos</i>.
*
@@ -947,7 +199,17 @@
return getDefaultYAxisLabel(pos);
}
-
+
+ /**
+ * This method is called to retrieve the default label for an Y axis at
+ * position <i>pos</i>.
+ *
+ * @param pos
+ * The position of an Y axis.
+ *
+ * @return the default Y axis label at position <i>pos</i>.
+ */
+ protected abstract String getDefaultYAxisLabel(int pos);
/**
* This method searches for a specific axis in the <i>settings</i> if
@@ -972,9 +234,7 @@
return null;
}
- Boolean fixed = as.isFixed();
-
- if (fixed != null && fixed) {
+ if (as.isFixed()) {
/* Only time series charts have time ranges so prefer those. */
if (axisId.equals("X")) {
@@ -1002,486 +262,6 @@
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) {
- log.warn("Skip XYDataset for Axis (invalid ranges): " + idx);
- return;
- }
-
- if (visible) {
- if (log.isDebugEnabled()) {
- log.debug("Add new AxisDataset at index: " + idx);
- log.debug("X extent: " + xyBounds[0]);
- log.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.
- */
- protected 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.
- */
- protected String msg(String key) {
- return Resources.getMsg(context.getMeta(), key, key);
- }
-
- protected String msg(String key, Object[] args) {
- return Resources.getMsg(context.getMeta(), key, key, args);
- }
-
- protected String msg(String key, String def, Object[] args) {
- return Resources.getMsg(context.getMeta(), key, def, args);
- }
-
- /**
- * 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) {
- log.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) {
- log.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) {
- log.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 {
- log.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();
-
- log.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 {
- log.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) {
- log.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>.
*
@@ -1490,17 +270,17 @@
*
* @return an instance of IdentifiableNumberAxis.
*/
- protected NumberAxis createNumberAxis(int idx, String label) {
+ protected final NumberAxis createNumberAxis(int idx, String label) {
YAxisWalker walker = getYAxisWalker();
return new IdentifiableNumberAxis(walker.getId(idx), label);
}
-
/**
* Create Y (range) axis for given index.
* Shall be overriden by subclasses.
*/
+ @Override
protected NumberAxis createYAxis(int index) {
YAxisWalker walker = getYAxisWalker();
@@ -1523,113 +303,5 @@
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;
- }
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
diff -r b8e7f6becf78 -r 1cc7653ca84f artifacts/src/main/java/org/dive4elements/river/exports/ChartGenerator2.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/ChartGenerator2.java Tue Jun 05 19:10:38 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/ChartGenerator2.java Tue Jun 05 19:21:16 2018 +0200
@@ -8,302 +8,69 @@
package org.dive4elements.river.exports;
-import java.awt.BasicStroke;
-import java.awt.Color;
+import static org.dive4elements.river.exports.injector.InjectorConstants.CURRENT_KM;
+
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.text.NumberFormat;
-import java.util.ArrayList;
import java.util.HashMap;
-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;
-
-import static org.dive4elements.river.exports.injector.InjectorConstants.CURRENT_KM;
/**
* Implementation of the OutGenerator interface for charts.
* It should provide some basic things that equal in all chart types.
*
*/
-// FIXME: copy/paste of ChartGenerator with LOTS of duplicate code... move duplicates to AbstractChartGenrator!
public abstract class ChartGenerator2 extends AbstractChartGenerator {
- private static Logger log = 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;
-
- /** 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;
+ private static final boolean USE_NOP_GRAPHICS = Boolean.getBoolean("info.rendering.nop.graphics");
/** Map of annotations to add at specific Y-axis. */
- protected SortedMap<Integer, RiverAnnotation> yAnnotations;
-
- /** List of annotations to insert in plot. */
- protected List<RiverAnnotation> annotations =
- new ArrayList<RiverAnnotation>();
-
- protected abstract List<AxisSection> buildYAxisSections();
-
- protected String outName;
+ protected SortedMap<Integer, RiverAnnotation> yAnnotations = new TreeMap<>();
private Map<String, IdentifiableNumberAxis> axisNameToAxis = new HashMap<>();
- /**
- * Default constructor that initializes internal data structures.
- */
- public ChartGenerator2() {
- datasets = new TreeMap<>();
- yAnnotations = new TreeMap<>();
- }
-
- @Override
- protected final D4EArtifact getArtifact() {
- // FIXME: should already made sure when this member is set
- return (D4EArtifact) this.master;
- }
-
- @Override
- protected final CallContext getContext() {
- return this.context;
- }
-
- @Override
- protected final Document getRequest() {
- return this.request;
- }
-
- /**
- * Adds annotations to list. The given annotation will be visible.
- */
- public void addAnnotations(RiverAnnotation annotation) {
- annotations.add(annotation);
- }
-
public void addYAnnotation(RiverAnnotation annotation, int axisIndex) {
yAnnotations.put(axisIndex, 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 {
-
+ protected void doGenerate(final CallContext context, final OutputStream out, final String outName) throws IOException {
log.debug("ChartGenerator2.generate");
- if (outName.indexOf("chartinfo") > 0) {
- generateInfo();
- }
- else {
- generateImage();
- }
+ if (outName.indexOf("chartinfo") > 0)
+ generateInfo(context, out);
+ else
+ generateImage(context);
}
-
- /** Generate only meta infos */
- private void generateInfo() throws IOException {
+ /**
+ * Generate only meta infos
+ */
+ private void generateInfo(final CallContext context, final OutputStream out) {
log.debug("ChartInfoGenerator2.generateInfo");
- JFreeChart chart = generateChart();
+ JFreeChart chart = generateChart(context);
int[] size = getSize();
if (size == null) {
@@ -348,142 +115,16 @@
XMLUtils.toStream(doc, out);
}
- /** Generate the diagram as an image. */
- private void generateImage() throws IOException {
- log.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
- ) {
- log.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;
- }
-
-
- /**
- * Return 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() {
+ @Override
+ protected ChartSection buildChartSection(final CallContext context) {
ChartSection chartSection = new ChartSection();
- chartSection.setTitle(getChartTitle());
- chartSection.setSubtitle(getChartSubtitlePure());
+ chartSection.setTitle(getChartTitle(context));
+ chartSection.setSubtitle(getChartSubtitlePure(context));
chartSection.setDisplayGrid(isGridVisible());
chartSection.setDisplayLogo(showLogo());
chartSection.setLogoVPlacement(logoVPlace());
@@ -491,198 +132,7 @@
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();
- }
-
- protected String interpolateVariables(String s) {
+ protected String interpolateVariables(final CallContext context, String s) {
log.debug("Interpolate variables in string '" + s + "'");
Object radius = context.getContextValue("radius");
if (radius instanceof Double) {
@@ -707,17 +157,18 @@
* existence of ChartSettings: if there are ChartSettings set, this method
* returns the chart title provided by those settings. Otherwise, this
* method returns getDefaultChartSubtitle().
+ * @param context
*
* @return the subtitle of a chart.
*/
- protected String getChartSubtitlePure() {
+ protected String getChartSubtitlePure(CallContext context) {
ChartSettings chartSettings = getChartSettings();
String subTitle = chartSettings != null
? getChartSubtitle(chartSettings)
- : getDefaultChartSubtitle();
+ : getDefaultChartSubtitle(context);
- String defSubTitle = getDefaultChartSubtitle();
+ String defSubTitle = getDefaultChartSubtitle(context);
if (subTitle == null) {
subTitle = defSubTitle != null ? defSubTitle : "";
@@ -726,162 +177,9 @@
return subTitle;
}
- protected String getChartSubtitle() {
- return interpolateVariables(getChartSubtitlePure());
- }
-
-
- /**
- * 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;
+ @Override
+ protected String getChartSubtitle(CallContext context) {
+ return interpolateVariables(context, getChartSubtitlePure(context));
}
/**
@@ -911,29 +209,6 @@
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);
/**
@@ -959,9 +234,7 @@
return null;
}
- Boolean fixed = as.isFixed();
-
- if (fixed != null && fixed) {
+ if (as.isFixed()) {
Double upper = as.getUpperRange();
Double lower = as.getLowerRange();
@@ -975,486 +248,6 @@
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) {
- log.warn("Skip XYDataset for Axis (invalid ranges): " + idx);
- return;
- }
-
- if (visible) {
- if (log.isDebugEnabled()) {
- log.debug("Add new AxisDataset at index: " + idx);
- log.debug("X extent: " + xyBounds[0]);
- log.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);
- }
-
- /**
- * 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) {
- log.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) {
- log.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()) {
- try {
- plot.setDataset(datasetIndex, dataset);
- plot.mapDatasetToRangeAxis(datasetIndex, axisIndex);
-
- applyThemes(plot, dataset,
- datasetIndex,
- axisDataset.isArea(dataset));
-
- datasetIndex++;
- }
- catch (RuntimeException re) {
- log.error(re);
- }
- }
-
- 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) {
- log.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 {
- log.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();
-
- log.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 {
- log.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) {
- log.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>.
*
@@ -1463,15 +256,15 @@
*
* @return an instance of IdentifiableNumberAxis.
*/
- protected NumberAxis createNumberAxis(int idx, String label) {
+ protected final NumberAxis createNumberAxis(int idx, String label) {
return new IdentifiableNumberAxis(axisIndexToName(idx), label);
}
-
/**
* Create Y (range) axis for given index.
* Shall be overriden by subclasses.
*/
+ @Override
protected NumberAxis createYAxis(int index) {
Font labelFont = new Font(
@@ -1496,114 +289,6 @@
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;
- }
-
public final IdentifiableNumberAxis getAxis(final String axisName) {
return axisNameToAxis.get(axisName);
}
@@ -1612,4 +297,9 @@
public final int getNumYAxes() {
return axisNameToAxis.size();
}
+
+ protected final void addYAnnotationsToRenderer(final XYPlot plot) {
+ final AnnotationRenderer annotationRenderer = new AnnotationRenderer(getChartSettings(), getDatasets(), DEFAULT_FONT_NAME);
+ annotationRenderer.addYAnnotationsToRenderer(plot, this.yAnnotations);
+ }
}
\ No newline at end of file
diff -r b8e7f6becf78 -r 1cc7653ca84f artifacts/src/main/java/org/dive4elements/river/exports/ChartInfoGenerator.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/ChartInfoGenerator.java Tue Jun 05 19:10:38 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/ChartInfoGenerator.java Tue Jun 05 19:21:16 2018 +0200
@@ -69,6 +69,7 @@
this.generator = generator;
}
+ @Override
public void setup(Object config) {
log.debug("ChartInfoGenerator.setup");
}
@@ -81,6 +82,7 @@
* @param out
* @param context
*/
+ @Override
public void init(
String outName,
Document request,
@@ -98,21 +100,21 @@
*
* @param master The master artifact
*/
+ @Override
public void setMasterArtifact(Artifact master) {
generator.setMasterArtifact(master);
}
-
/**
* Dispatches the operation to the instantiated generator.
*
* @param collection The collection.
*/
+ @Override
public void setCollection(D4EArtifactCollection collection) {
generator.setCollection(collection);
}
-
-
+
/**
* Dispatches the operation to the instantiated generator.
*/
@@ -137,7 +139,7 @@
{
log.debug("ChartInfoGenerator.generate");
- JFreeChart chart = generator.generateChart();
+ JFreeChart chart = generator.generateChart(generator.getContext());
int[] size = generator.getSize();
if (size == null) {
diff -r b8e7f6becf78 -r 1cc7653ca84f artifacts/src/main/java/org/dive4elements/river/exports/ChartSection.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/ChartSection.java Tue Jun 05 19:10:38 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/ChartSection.java Tue Jun 05 19:21:16 2018 +0200
@@ -93,8 +93,8 @@
}
- public Boolean getDisplayGrid() {
- return getBooleanValue(DISPLAYGRID_ATTR);
+ public boolean getDisplayGrid() {
+ return getBooleanValue(DISPLAYGRID_ATTR, true);
}
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
diff -r b8e7f6becf78 -r 1cc7653ca84f artifacts/src/main/java/org/dive4elements/river/exports/CrossSectionGenerator.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/CrossSectionGenerator.java Tue Jun 05 19:10:38 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/CrossSectionGenerator.java Tue Jun 05 19:21:16 2018 +0200
@@ -16,13 +16,8 @@
import java.util.List;
import org.apache.log4j.Logger;
-import org.jfree.chart.LegendItemCollection;
-import org.jfree.chart.annotations.XYBoxAnnotation;
-import org.jfree.chart.annotations.XYTextAnnotation;
-import org.jfree.chart.plot.XYPlot;
-import org.jfree.data.xy.XYSeries;
-
import org.dive4elements.artifactdatabase.state.ArtifactAndFacet;
+import org.dive4elements.artifacts.CallContext;
import org.dive4elements.artifacts.DataProvider;
import org.dive4elements.river.artifacts.D4EArtifact;
import org.dive4elements.river.artifacts.geom.Lines;
@@ -35,8 +30,13 @@
import org.dive4elements.river.model.FastCrossSectionLine;
import org.dive4elements.river.themes.TextStyle;
import org.dive4elements.river.themes.ThemeDocument;
+import org.dive4elements.river.utils.Formatter;
import org.dive4elements.river.utils.RiverUtils;
-import org.dive4elements.river.utils.Formatter;
+import org.jfree.chart.LegendItemCollection;
+import org.jfree.chart.annotations.XYBoxAnnotation;
+import org.jfree.chart.annotations.XYTextAnnotation;
+import org.jfree.chart.plot.XYPlot;
+import org.jfree.data.xy.XYSeries;
/**
@@ -93,7 +93,7 @@
* Get localized chart title.
*/
@Override
- public String getDefaultChartTitle() {
+ public String getDefaultChartTitle(final CallContext context) {
Object[] i18n_msg_args = new Object[] {
getRiverName()
};
@@ -103,19 +103,19 @@
/** Always return default subtitle. */
@Override
- protected String getChartSubtitle() {
+ protected String getChartSubtitle(CallContext context) {
// XXX NOTE: overriding this method disables ChartSettings subtitle!
// The default implementation of this method in ChartGenerator returns
// the subtitle changed via the chart settings dialog. This method
// always returns the subtitle containing river and km, NEVER the
// ChartSettings subtitle!
- return getDefaultChartSubtitle();
+ return getDefaultChartSubtitle(context);
}
-
+
/** Get Charts default subtitle. */
@Override
- protected String getDefaultChartSubtitle() {
+ protected String getDefaultChartSubtitle(final CallContext context) {
List<DataProvider> providers =
context.getDataProvider(
CrossSectionFacet.BLACKBOARD_CS_MASTER_DATA);
@@ -164,8 +164,7 @@
}
@Override
- protected void addAnnotationsToRenderer(XYPlot plot) {
- super.addAnnotationsToRenderer(plot);
+ protected void doAddFurtherAnnotations(XYPlot plot, List<RiverAnnotation> annotations) {
// Paints for the boxes/lines.
Stroke basicStroke = new BasicStroke(1.0f);
@@ -179,7 +178,7 @@
plot.getDomainAxis(0),
plot.getRangeAxis());
- for(RiverAnnotation fa : this.annotations) {
+ for(RiverAnnotation fa : annotations) {
// Access text styling, if any.
ThemeDocument theme = fa.getTheme();
@@ -245,14 +244,14 @@
}
@Override
- protected String getDefaultXAxisLabel() {
+ protected String getDefaultXAxisLabel(final CallContext context) {
return msg(I18N_XAXIS_LABEL, I18N_XAXIS_LABEL_DEFAULT);
}
@Override
protected String getDefaultYAxisLabel(int pos) {
- D4EArtifact flys = (D4EArtifact) master;
+ D4EArtifact flys = getArtifact();
String unit = RiverUtils.getRiver(flys).getWstUnit().getName();
@@ -279,6 +278,8 @@
log.error("No facet name for doOut(). No output generated!");
return;
}
+
+ CallContext context = getContext();
if (name.equals(CROSS_SECTION)) {
doCrossSectionOut(
@@ -351,11 +352,13 @@
// DO NOT SORT DATA! This destroys the gaps indicated by NaNs.
StyledXYSeries series = new StyledXYSeries(seriesName, false, theme);
+ CallContext context = getContext();
+
if (!theme.parseShowLineLabel()) {
series.setLabel("");
}
if (theme.parseShowWidth()) {
- NumberFormat nf = Formatter.getMeterFormat(this.context);
+ NumberFormat nf = Formatter.getMeterFormat(context);
String labelAdd = "b=" + nf.format(lines.width) + "m";
if (series.getLabel().length() == 0) {
series.setLabel(labelAdd);
@@ -366,8 +369,8 @@
}
if (theme.parseShowLevel() && lines.points.length > 1
&& lines.points[1].length > 0) {
- NumberFormat nf = Formatter.getMeterFormat(this.context);
- D4EArtifact flys = (D4EArtifact) master;
+ NumberFormat nf = Formatter.getMeterFormat(context);
+ D4EArtifact flys = getArtifact();
String unit = RiverUtils.getRiver(flys).getWstUnit().getName();
@@ -380,7 +383,7 @@
}
}
if (theme.parseShowMiddleHeight() && lines.width != 0) {
- NumberFormat nf = Formatter.getMeterFormat(this.context);
+ NumberFormat nf = Formatter.getMeterFormat(context);
String labelAdd = "T=" + nf.format(lines.area / lines.width) + "m";
// : " + lines.area + "/" + lines.width);
if (series.getLabel().length() == 0) {
@@ -450,9 +453,9 @@
* @return a new <i>ChartSection</i>.
*/
@Override
- protected ChartSection buildChartSection() {
+ protected ChartSection buildChartSection(final CallContext context) {
ChartSection chartSection = new ChartSection();
- chartSection.setTitle(getChartTitle());
+ chartSection.setTitle(getChartTitle(context));
chartSection.setDisplayGrid(isGridVisible());
chartSection.setDisplayLogo(showLogo());
chartSection.setLogoVPlacement(logoVPlace());
diff -r b8e7f6becf78 -r 1cc7653ca84f artifacts/src/main/java/org/dive4elements/river/exports/DiagramGenerator.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/DiagramGenerator.java Tue Jun 05 19:10:38 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/DiagramGenerator.java Tue Jun 05 19:21:16 2018 +0200
@@ -10,9 +10,7 @@
import java.awt.Color;
import java.awt.Font;
-
import java.text.NumberFormat;
-
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
@@ -21,62 +19,43 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
-
+import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import java.util.regex.Matcher;
-
-import java.io.OutputStream;
import javax.swing.ImageIcon;
+import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
-
import org.dive4elements.artifactdatabase.state.ArtifactAndFacet;
import org.dive4elements.artifactdatabase.state.Facet;
-
import org.dive4elements.artifacts.CallContext;
-
import org.dive4elements.river.artifacts.D4EArtifact;
import org.dive4elements.river.exports.DiagramAttributes.AxisAttributes;
import org.dive4elements.river.exports.process.Processor;
-
-import org.dive4elements.river.jfree.RiverAnnotation;
-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.RiverAnnotation;
import org.dive4elements.river.jfree.StyledAreaSeriesCollection;
import org.dive4elements.river.jfree.XYMetaSeriesCollection;
-
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;
-import org.w3c.dom.Document;
-
-import org.apache.commons.lang.StringUtils;
-
/**
* The main diagram creation class.
@@ -102,9 +81,9 @@
/** The log that is used in this generator. */
private static Logger log = Logger.getLogger(DiagramGenerator.class);
- protected List<Marker> domainMarkers = new ArrayList<Marker>();
+ protected List<Marker> domainMarkers = new ArrayList<>();
- protected List<Marker> valueMarkers = new ArrayList<Marker>();
+ protected List<Marker> valueMarkers = new ArrayList<>();
/** The max X range to include all X values of all series for each axis. */
protected Map<Integer, Bounds> xBounds;
@@ -144,17 +123,7 @@
diagramAttributes = da.new Instance();
}
- @Override
- public void init(
- String outName,
- Document request,
- OutputStream out,
- CallContext context
- ) {
- super.init(outName, request, out, context);
- }
-
- private void setInvertedFromConfig() {
+ private void setInvertedFromConfig(CallContext context) {
DiagramAttributes.DomainAxisAttributes dx =
diagramAttributes.getDomainAxis();
@@ -175,13 +144,13 @@
* Generate the chart anew (including localized axis and all).
*/
@Override
- public JFreeChart generateChart() {
+ protected JFreeChart generateChart(CallContext context) {
log.debug("DiagramGenerator.generateChart");
postProcess();
JFreeChart chart = ChartFactory.createXYLineChart(
- getChartTitle(),
+ getChartTitle(context),
"",
"",
null,
@@ -191,13 +160,13 @@
false);
XYPlot plot = (XYPlot) chart.getPlot();
- ValueAxis axis = createXAxis(getXAxisLabel());
+ ValueAxis axis = createXAxis(context, getXAxisLabel());
plot.setDomainAxis(axis);
chart.setBackgroundPaint(Color.WHITE);
plot.setBackgroundPaint(Color.WHITE);
- addSubtitles(chart);
- addMetadataSubtitle(chart);
+ addSubtitles(context, chart);
+ addMetadataSubtitle(context, chart);
adjustPlot(plot);
//debugAxis(plot);
@@ -215,7 +184,7 @@
localizeAxes(plot);
- setInvertedFromConfig();
+ setInvertedFromConfig(context);
adjustAxes(plot);
if (!(axis instanceof LogarithmicAxis)) {
@@ -230,10 +199,8 @@
//debugAxis(plot);
// These have to go after the autozoom.
- AnnotationHelper.addAnnotationsToRenderer(annotations, plot,
- getChartSettings(), datasets);
- AnnotationHelper.addYAnnotationsToRenderer(yAnnotations, plot,
- getChartSettings(), datasets);
+ addAnnotationsToRenderer(plot);
+ addYAnnotationsToRenderer(plot);
// Add a logo (maybe).
addLogo(plot);
@@ -249,10 +216,6 @@
return chart;
}
- public String getOutName() {
- return outName;
- }
-
/**
* Return left most data points x value (on first axis).
*/
@@ -393,7 +356,7 @@
}
- protected NumberAxis createXAxis(String label) {
+ protected NumberAxis createXAxis(final CallContext context, String label) {
boolean logarithmic = (Boolean)diagramAttributes.getDomainAxis().
isLog().evaluate((D4EArtifact)getMaster(), context);
@@ -1113,7 +1076,7 @@
}
@Override
- public String getDefaultChartTitle() {
+ protected final String getDefaultChartTitle(CallContext context) {
DiagramAttributes.Title dTitle = diagramAttributes.getTitle();
if (dTitle == null) {
return "Title not configured in conf.xml";
@@ -1122,8 +1085,9 @@
return dTitle.evaluate((D4EArtifact)getMaster(), context);
}
+
@Override
- public String getDefaultChartSubtitle() {
+ protected String getDefaultChartSubtitle(CallContext context) {
String parts = "";
DiagramAttributes.Title dTitle = diagramAttributes.getSubtitle();
if (dTitle == null &&
@@ -1154,7 +1118,7 @@
* Get internationalized label for the x axis.
*/
@Override
- protected String getDefaultXAxisLabel() {
+ protected String getDefaultXAxisLabel(CallContext context) {
DiagramAttributes.DomainAxisAttributes dx =
diagramAttributes.getDomainAxis();
@@ -1167,8 +1131,7 @@
return "Domain Axis Title not configured in conf.xml";
}
- @Override
- protected String getDefaultYAxisLabel(String axisName) {
+ protected final String getDefaultYAxisLabel(String axisName) {
Set labelSet = axesLabels.get(diagramAttributes.getAxisIndex(axisName));
log.debug("Labels for axis: " + labelSet);
if (labelSet != null && !labelSet.isEmpty()) {
@@ -1198,8 +1161,9 @@
*
* @return a list of Y axis sections.
*/
- protected List<AxisSection> buildYAxisSections() {
- List<AxisSection> axisSections = new ArrayList<AxisSection>();
+ @Override
+ protected final List<AxisSection> buildYAxisSections() {
+ List<AxisSection> axisSections = new ArrayList<>();
List<DiagramAttributes.AxisAttributes> axesAttrs =
diagramAttributes.getAxesAttributes();
@@ -1315,7 +1279,7 @@
final AxisAttributes axisAttributes = diagramAttributes.getAxesAttributes().get(index);
- boolean logarithmic = (Boolean)axisAttributes.isLog().evaluate((D4EArtifact)getMaster(), context);
+ boolean logarithmic = (Boolean)axisAttributes.isLog().evaluate((D4EArtifact)getMaster(), getContext());
NumberAxis axis;
if (logarithmic) {
@@ -1347,4 +1311,4 @@
public void addSubtitle(String part) {
this.subTitleParts.add(part);
}
-}
+}
\ No newline at end of file
diff -r b8e7f6becf78 -r 1cc7653ca84f artifacts/src/main/java/org/dive4elements/river/exports/DischargeCurveGenerator.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/DischargeCurveGenerator.java Tue Jun 05 19:10:38 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/DischargeCurveGenerator.java Tue Jun 05 19:21:16 2018 +0200
@@ -28,6 +28,7 @@
import org.dive4elements.river.themes.ThemeDocument;
import org.dive4elements.artifactdatabase.state.State;
+import org.dive4elements.artifacts.CallContext;
import org.dive4elements.river.artifacts.GaugeDischargeCurveArtifact;
import org.apache.log4j.Logger;
@@ -121,8 +122,8 @@
if (getMaster() instanceof GaugeDischargeCurveArtifact) {
GaugeDischargeCurveArtifact myMaster =
(GaugeDischargeCurveArtifact) getMaster();
- State state = myMaster.getCurrentState(context);
- if (myMaster.STATIC_STATE_NAME.equals(state.getID())) {
+ State state = myMaster.getCurrentState(getContext());
+ if (GaugeDischargeCurveArtifact.STATIC_STATE_NAME.equals(state.getID())) {
return;
}
}
@@ -213,13 +214,13 @@
* Returns always null to suppress subtitles.
*/
@Override
- protected String getDefaultChartTitle() {
+ protected String getDefaultChartTitle(final CallContext context) {
return null;
}
@Override
- protected String getDefaultXAxisLabel() {
+ protected String getDefaultXAxisLabel(final CallContext context) {
return msg(I18N_XAXIS_LABEL, I18N_XAXIS_LABEL_DEFAULT);
}
@@ -278,6 +279,8 @@
String name = artifactFacet.getFacetName();
log.debug("DischargeCurveGenerator.doOut: " + name);
+ final CallContext context = getContext();
+
MiscDischargeProcessor dProcessor = new MiscDischargeProcessor(
getRange()[0]);
if (dProcessor.canHandle(name)) {
@@ -376,8 +379,7 @@
double y,
ThemeDocument theme
) {
- List<XYTextAnnotation> textAnnos =
- new ArrayList<XYTextAnnotation>();
+ final List<XYTextAnnotation> textAnnos = new ArrayList<>();
XYTextAnnotation anno = new CollisionFreeXYTextAnnotation(
title,
x,
@@ -429,8 +431,7 @@
// If no Q values (i.e. all -1) found, add annotations.
if (hasNoDischarge(data)) {
- List<StickyAxisAnnotation> xy =
- new ArrayList<StickyAxisAnnotation>();
+ final List<StickyAxisAnnotation> xy = new ArrayList<>();
for (double y: data[1]) {
if (translate != 0d) {
diff -r b8e7f6becf78 -r 1cc7653ca84f artifacts/src/main/java/org/dive4elements/river/exports/DischargeGenerator.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/DischargeGenerator.java Tue Jun 05 19:10:38 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/DischargeGenerator.java Tue Jun 05 19:21:16 2018 +0200
@@ -39,7 +39,7 @@
public void addDatasets(XYPlot plot) {
super.addDatasets(plot);
- Object pnp = context.getContextValue(PNP);
+ Object pnp = getContext().getContextValue(PNP);
if (!(pnp instanceof Number)) {
return;
}
@@ -52,7 +52,7 @@
return;
}
- AxisDataset data = datasets.get(wAxisIndex);
+ AxisDataset data = getDatasets().get(wAxisIndex);
if (data == null) {
// No W axis
return;
@@ -94,8 +94,7 @@
getYAxisFontSize(wAxisIndex));
String axisName = "W.in.cm";
- String axisLabel = Resources.getMsg(context.getMeta(),
- I18N_AXIS_LABEL, "W [cm]");
+ String axisLabel = msg( I18N_AXIS_LABEL, "W [cm]" );
IdentifiableNumberAxis axis = new IdentifiableNumberAxis(
axisName, axisLabel);
diff -r b8e7f6becf78 -r 1cc7653ca84f artifacts/src/main/java/org/dive4elements/river/exports/DurationCurveGenerator.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/DurationCurveGenerator.java Tue Jun 05 19:10:38 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/DurationCurveGenerator.java Tue Jun 05 19:21:16 2018 +0200
@@ -9,6 +9,7 @@
package org.dive4elements.river.exports;
import org.dive4elements.artifactdatabase.state.ArtifactAndFacet;
+import org.dive4elements.artifacts.CallContext;
import org.dive4elements.river.artifacts.model.FacetTypes;
import org.dive4elements.river.artifacts.model.WQDay;
import org.dive4elements.river.jfree.Bounds;
@@ -95,13 +96,13 @@
@Override
- protected String getDefaultChartTitle() {
+ protected String getDefaultChartTitle(final CallContext context) {
return msg(I18N_CHART_TITLE, I18N_CHART_TITLE_DEFAULT);
}
@Override
- protected String getDefaultChartSubtitle() {
+ protected String getDefaultChartSubtitle(final CallContext context) {
double[] dist = getRange();
Object[] args = new Object[] {
@@ -114,7 +115,7 @@
@Override
- protected String getDefaultXAxisLabel() {
+ protected String getDefaultXAxisLabel(final CallContext context) {
return msg(I18N_XAXIS_LABEL, I18N_XAXIS_LABEL_DEFAULT);
}
@@ -123,7 +124,7 @@
protected String getDefaultYAxisLabel(int index) {
String label = "default";
if (index == YAXIS.W.idx) {
- label = msg(I18N_YAXIS_LABEL_W, new Object[] { getRiverUnit() });
+ label = msg(I18N_YAXIS_LABEL_W, I18N_YAXIS_LABEL_W, new Object[] { getRiverUnit() });
}
else if (index == YAXIS.Q.idx) {
label = msg(I18N_YAXIS_LABEL_Q);
@@ -192,6 +193,8 @@
log.error("No facet given. Cannot create dataset.");
return;
}
+
+ final CallContext context = getContext();
if (name.equals(DURATION_W)) {
doWOut(
diff -r b8e7f6becf78 -r 1cc7653ca84f artifacts/src/main/java/org/dive4elements/river/exports/ExportSection.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/ExportSection.java Tue Jun 05 19:10:38 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/ExportSection.java Tue Jun 05 19:21:16 2018 +0200
@@ -18,13 +18,15 @@
public static final String WIDTH_ATTR = "width";
public static final String HEIGHT_ATTR = "height";
+ private static final String METADATA_ATTR = "chart_settings_export_metadata";
+
public ExportSection() {
super("export");
}
- public void setWidth(int width) {
+ public void setWidth(final int width) {
if (width <= 0) {
return;
}
@@ -38,7 +40,7 @@
}
- public void setHeight(int height) {
+ public void setHeight(final int height) {
if (height <= 0) {
return;
}
@@ -50,5 +52,12 @@
public Integer getHeight() {
return getIntegerValue(HEIGHT_ATTR);
}
-}
-// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
+
+ public void setMetadata(final boolean metadata) {
+ setBooleanValue(METADATA_ATTR, metadata);
+ }
+
+ public boolean getMetadata() {
+ return getBooleanValue(METADATA_ATTR, true);
+ }
+}
\ No newline at end of file
diff -r b8e7f6becf78 -r 1cc7653ca84f artifacts/src/main/java/org/dive4elements/river/exports/HistoricalDischargeCurveGenerator.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/HistoricalDischargeCurveGenerator.java Tue Jun 05 19:10:38 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/HistoricalDischargeCurveGenerator.java Tue Jun 05 19:21:16 2018 +0200
@@ -13,7 +13,7 @@
import org.apache.log4j.Logger;
import org.dive4elements.artifactdatabase.state.ArtifactAndFacet;
-
+import org.dive4elements.artifacts.CallContext;
import org.dive4elements.river.artifacts.D4EArtifact;
import org.dive4elements.river.artifacts.access.HistoricalDischargeAccess;
@@ -90,13 +90,13 @@
}
@Override
- protected String getDefaultChartTitle() {
+ protected String getDefaultChartTitle(final CallContext context) {
return msg(I18N_CHART_TITLE, I18N_CHART_TITLE);
}
@Override
- protected String getDefaultChartSubtitle() {
- D4EArtifact flys = (D4EArtifact) master;
+ protected String getDefaultChartSubtitle(final CallContext context) {
+ D4EArtifact flys = getArtifact();
Timerange evalTime = new HistoricalDischargeAccess(flys)
.getEvaluationTimerange();
@@ -107,7 +107,7 @@
}
@Override
- protected String getDefaultXAxisLabel() {
+ protected String getDefaultXAxisLabel(final CallContext context) {
return msg(I18N_XAXIS_LABEL, I18N_XAXIS_LABEL);
}
@@ -138,6 +138,8 @@
log.debug("Theme description is: "
+ artifactFacet.getFacetDescription());
+ final CallContext context = getContext();
+
if (name.equals(HISTORICAL_DISCHARGE_Q)) {
doHistoricalDischargeOutQ(
(D4EArtifact) artifactFacet.getArtifact(),
diff -r b8e7f6becf78 -r 1cc7653ca84f artifacts/src/main/java/org/dive4elements/river/exports/LegendSection.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/LegendSection.java Tue Jun 05 19:10:38 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/LegendSection.java Tue Jun 05 19:21:16 2018 +0200
@@ -55,8 +55,8 @@
}
- public Boolean getVisibility() {
- return getBooleanValue(VISIBILITY_ATTR);
+ public boolean getVisibility() {
+ return getBooleanValue(VISIBILITY_ATTR, true);
}
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
diff -r b8e7f6becf78 -r 1cc7653ca84f artifacts/src/main/java/org/dive4elements/river/exports/LongitudinalSectionGenerator.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/LongitudinalSectionGenerator.java Tue Jun 05 19:10:38 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/LongitudinalSectionGenerator.java Tue Jun 05 19:21:16 2018 +0200
@@ -10,6 +10,7 @@
import org.dive4elements.artifactdatabase.state.ArtifactAndFacet;
import org.dive4elements.artifactdatabase.state.Facet;
+import org.dive4elements.artifacts.CallContext;
import org.dive4elements.river.artifacts.D4EArtifact;
import org.dive4elements.river.artifacts.geom.Lines;
import org.dive4elements.river.artifacts.model.AreaFacet;
@@ -157,18 +158,17 @@
* @return the default title for this chart.
*/
@Override
- public String getDefaultChartTitle() {
+ public String getDefaultChartTitle(final CallContext context) {
return msg(I18N_CHART_TITLE, I18N_CHART_TITLE_DEFAULT);
}
-
/**
* Returns the default subtitle for this chart.
*
* @return the default subtitle for this chart.
*/
@Override
- protected String getDefaultChartSubtitle() {
+ protected String getDefaultChartSubtitle(final CallContext context) {
double[] dist = getRange();
Object[] args = null;
@@ -208,8 +208,8 @@
* Get internationalized label for the x axis.
*/
@Override
- protected String getDefaultXAxisLabel() {
- D4EArtifact flys = (D4EArtifact) master;
+ protected String getDefaultXAxisLabel(CallContext context) {
+ D4EArtifact flys = getArtifact();
return msg(
I18N_XAXIS_LABEL,
@@ -241,7 +241,7 @@
* Get internationalized label for the y axis.
*/
protected String getWAxisLabel() {
- D4EArtifact flys = (D4EArtifact) master;
+ D4EArtifact flys = getArtifact();
String unit = RiverUtils.getRiver(flys).getWstUnit().getName();
@@ -340,6 +340,8 @@
return;
}
+ CallContext context = getContext();
+
Processor wProcessor = new WOutProcessor();
Processor qProcessor = new QOutProcessor();
Processor bdyProcessor = new BedDiffYearProcessor();
diff -r b8e7f6becf78 -r 1cc7653ca84f artifacts/src/main/java/org/dive4elements/river/exports/LongitudinalSectionGenerator2.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/LongitudinalSectionGenerator2.java Tue Jun 05 19:10:38 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/LongitudinalSectionGenerator2.java Tue Jun 05 19:21:16 2018 +0200
@@ -10,6 +10,7 @@
import org.dive4elements.river.artifacts.D4EArtifact;
import org.dive4elements.artifactdatabase.state.ArtifactAndFacet;
+import org.dive4elements.artifacts.CallContext;
import org.dive4elements.river.jfree.Bounds;
import org.dive4elements.river.themes.ThemeDocument;
import org.dive4elements.river.artifacts.model.FacetTypes;
@@ -62,7 +63,7 @@
"chart.subtitle.radius";
@Override
- public String getDefaultChartSubtitle() {
+ public String getDefaultChartSubtitle(final CallContext context) {
double[] dist = getRange();
String parts = "";
@@ -124,6 +125,7 @@
// This might not be neccessary if every facet uses only the
// radius and does not do its own zoomscale calculation.
+ final CallContext context = getContext();
context.putContextValue("startkm", candidate.getLowerBound());
context.putContextValue("endkm", candidate.getUpperBound());
context.putContextValue("bounds_defined", true);
@@ -146,6 +148,7 @@
}
// fake startkm and endkm for the dry run
+ final CallContext context = getContext();
context.putContextValue("startkm", 0d);
context.putContextValue("endkm", 42d);
for (SuperBundle superbundle: postOutAF) {
@@ -185,15 +188,13 @@
SuperBundle superbundle = new SuperBundle(bundle, theme, visible);
if (postOutAF == null) {
- postOutAF = new ArrayList<SuperBundle>();
+ postOutAF = new ArrayList<>();
}
postOutAF.add(superbundle);
if (visible) {
log.debug("Adding radius subtitle.");
- addSubtitle(Resources.getMsg(
- getCallContext().getMeta(),
- I18N_SUBTITLE_RADIUS) + ": $RADIUS");
+ addSubtitle(msg(I18N_SUBTITLE_RADIUS) + ": $RADIUS");
}
return;
}
diff -r b8e7f6becf78 -r 1cc7653ca84f artifacts/src/main/java/org/dive4elements/river/exports/NormalizedReferenceCurveGenerator.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/NormalizedReferenceCurveGenerator.java Tue Jun 05 19:10:38 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/NormalizedReferenceCurveGenerator.java Tue Jun 05 19:21:16 2018 +0200
@@ -8,6 +8,8 @@
package org.dive4elements.river.exports;
+import org.dive4elements.artifacts.CallContext;
+
/**
* An OutGenerator that generates reference curves.
*/
@@ -25,7 +27,7 @@
/** Get default chart title. */
@Override
- protected String getDefaultChartTitle() {
+ protected String getDefaultChartTitle(final CallContext context) {
return msg(
I18N_NORMALIZED_CHART_TITLE,
I18N_NORMALIZED_CHART_TITLE_DEFAULT);
diff -r b8e7f6becf78 -r 1cc7653ca84f artifacts/src/main/java/org/dive4elements/river/exports/ReferenceCurveGenerator.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/ReferenceCurveGenerator.java Tue Jun 05 19:10:38 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/ReferenceCurveGenerator.java Tue Jun 05 19:21:16 2018 +0200
@@ -9,6 +9,7 @@
package org.dive4elements.river.exports;
import org.dive4elements.artifactdatabase.state.ArtifactAndFacet;
+import org.dive4elements.artifacts.CallContext;
import org.dive4elements.river.artifacts.model.FacetTypes;
import org.dive4elements.river.artifacts.model.WW;
import org.dive4elements.river.artifacts.model.WW.ApplyFunctionIterator;
@@ -86,12 +87,12 @@
/** Get default chart title. */
@Override
- protected String getDefaultChartTitle() {
+ protected String getDefaultChartTitle(final CallContext context) {
return msg(I18N_CHART_TITLE, I18N_CHART_TITLE_DEFAULT);
}
@Override
- protected String getDefaultChartSubtitle() {
+ protected String getDefaultChartSubtitle(final CallContext context) {
Object[] args = new Object[] {
getRiverName(),
};
@@ -102,14 +103,14 @@
/** True if axis is in cm (because at gauge). */
protected boolean getInCm(int index) {
- Object obj = context.getContextValue("reference.curve.axis.scale");
+ Object obj = getContext().getContextValue("reference.curve.axis.scale");
return obj instanceof WWAxisTypes && ((WWAxisTypes)obj).getInCm(index);
}
/** Get Label for X-axis (W). */
@Override
- protected String getDefaultXAxisLabel() {
+ protected String getDefaultXAxisLabel(final CallContext context) {
return msg(getInCm(0) ? I18N_X_AXIS_IN_CM : I18N_X_AXIS_IN_M);
}
@@ -149,6 +150,8 @@
return;
}
+ final CallContext context = getContext();
+
if (name.equals(facetName())) {
doReferenceOut(artifactFacet.getData(context), theme, visible);
}
@@ -194,7 +197,7 @@
) {
WW ww = (WW)data;
- Object obj = context.getContextValue("reference.curve.axis.scale");
+ Object obj = getContext().getContextValue("reference.curve.axis.scale");
WWAxisTypes wwat = obj instanceof WWAxisTypes
? (WWAxisTypes)obj
@@ -236,7 +239,7 @@
/** Set the tick units for given axis. */
protected void setAxisTickUnit(double tick, ValueAxis axis) {
TickUnits units = new TickUnits();
- units.add(new NumberTickUnit(tick, Formatter.getWaterlevelW(context)));
+ units.add(new NumberTickUnit(tick, Formatter.getWaterlevelW(getContext())));
axis.setStandardTickUnits(units);
axis.setAutoTickUnitSelection(true);
}
diff -r b8e7f6becf78 -r 1cc7653ca84f artifacts/src/main/java/org/dive4elements/river/exports/TimeseriesChartGenerator.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/TimeseriesChartGenerator.java Tue Jun 05 19:10:38 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/TimeseriesChartGenerator.java Tue Jun 05 19:21:16 2018 +0200
@@ -9,12 +9,12 @@
package org.dive4elements.river.exports;
import org.dive4elements.artifactdatabase.state.ArtifactAndFacet;
+import org.dive4elements.artifacts.CallContext;
import org.dive4elements.river.artifacts.resources.Resources;
import org.dive4elements.river.jfree.Bounds;
import org.dive4elements.river.jfree.CollisionFreeXYTextAnnotation;
import org.dive4elements.river.jfree.DoubleBounds;
import org.dive4elements.river.jfree.RiverAnnotation;
-import org.dive4elements.river.jfree.AnnotationHelper;
import org.dive4elements.river.jfree.StyledTimeSeries;
import org.dive4elements.river.jfree.TimeBounds;
import org.dive4elements.river.jfree.AxisDataset;
@@ -93,14 +93,12 @@
attributes = new HashMap<String, String>();
}
-
-
@Override
- public JFreeChart generateChart() {
+ protected JFreeChart generateChart(CallContext context) {
log.info("Generate Timeseries Chart.");
JFreeChart chart = ChartFactory.createTimeSeriesChart(
- getChartTitle(),
+ getChartTitle(context),
getXAxisLabel(),
getYAxisLabel(0),
null,
@@ -113,8 +111,8 @@
chart.setBackgroundPaint(Color.WHITE);
plot.setBackgroundPaint(Color.WHITE);
- addSubtitles(chart);
- addMetadataSubtitle( chart );
+ addSubtitles(context, chart);
+ addMetadataSubtitle( context, chart );
adjustPlot(plot);
addDatasets(plot);
adjustAxes(plot);
@@ -126,11 +124,8 @@
consumeAxisSettings(plot);
- AnnotationHelper.addAnnotationsToRenderer(
- annotations,
- plot,
- getChartSettings(),
- datasets);
+ addAnnotationsToRenderer(plot);
+
addLogo(plot);
aggregateLegendEntries(plot);
return chart;
@@ -629,7 +624,7 @@
catch(JSONException ex) {
String str = array.getString(0);
DateFormat df = DateFormat.getDateInstance(
- DateFormat.MEDIUM, Resources.getLocale(context.getMeta()));
+ DateFormat.MEDIUM, Resources.getLocale(getContext().getMeta()));
return df.parse(str);
}
}
@@ -856,7 +851,7 @@
* setLowerTimeRange */
@Override
protected List<AxisSection> buildXAxisSections() {
- List<AxisSection> axisSections = new ArrayList<AxisSection>();
+ List<AxisSection> axisSections = new ArrayList<>();
String identifier = "X";
diff -r b8e7f6becf78 -r 1cc7653ca84f artifacts/src/main/java/org/dive4elements/river/exports/TypeSection.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/TypeSection.java Tue Jun 05 19:10:38 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/TypeSection.java Tue Jun 05 19:21:16 2018 +0200
@@ -123,26 +123,25 @@
}
- public void setBooleanValue(String key, boolean value) {
- Attribute attr = getAttribute(key);
- if (attr == null) {
- attr = new BooleanAttribute(key, value, true);
- addAttribute(key, attr);
- }
- else {
+ protected final void setBooleanValue(String key, boolean value) {
+ final Attribute attr = getAttribute(key);
+ if (attr == null)
+ addAttribute(key, new BooleanAttribute(key, value, true));
+ else
attr.setValue(value);
- }
}
-
- public Boolean getBooleanValue(String key) {
- Attribute attr = getAttribute(key);
+ protected final boolean getBooleanValue(final String key, boolean defaultValue) {
+ final Attribute attr = getAttribute(key);
if (attr instanceof BooleanAttribute) {
- return (Boolean) attr.getValue();
+ final Boolean value = (Boolean) attr.getValue();
+ if( value == null )
+ return defaultValue;
+
+ return value;
}
- return null;
+ return defaultValue;
}
-}
-// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
+}
\ No newline at end of file
diff -r b8e7f6becf78 -r 1cc7653ca84f artifacts/src/main/java/org/dive4elements/river/exports/XYChartGenerator.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/XYChartGenerator.java Tue Jun 05 19:10:38 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/XYChartGenerator.java Tue Jun 05 19:21:16 2018 +0200
@@ -40,6 +40,7 @@
import org.json.JSONException;
import org.dive4elements.artifactdatabase.state.ArtifactAndFacet;
+import org.dive4elements.artifacts.CallContext;
import org.dive4elements.river.jfree.Bounds;
import org.dive4elements.river.jfree.CollisionFreeXYTextAnnotation;
import org.dive4elements.river.jfree.DoubleBounds;
@@ -47,7 +48,6 @@
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;
@@ -102,11 +102,11 @@
* Generate the chart anew (including localized axis and all).
*/
@Override
- public JFreeChart generateChart() {
+ protected JFreeChart generateChart(CallContext context) {
log.debug("XYChartGenerator.generateChart");
JFreeChart chart = ChartFactory.createXYLineChart(
- getChartTitle(),
+ getChartTitle(context),
getXAxisLabel(),
getYAxisLabel(0),
null,
@@ -121,8 +121,8 @@
chart.setBackgroundPaint(Color.WHITE);
plot.setBackgroundPaint(Color.WHITE);
- addSubtitles(chart);
- addMetadataSubtitle(chart);
+ addSubtitles(context, chart);
+ addMetadataSubtitle(context, chart);
adjustPlot(plot);
//debugAxis(plot);
@@ -994,10 +994,5 @@
public void setInverted(boolean inverted) {
this.inverted = inverted;
}
-
- protected void addAnnotationsToRenderer(XYPlot plot) {
- AnnotationHelper.addAnnotationsToRenderer(annotations, plot,
- getChartSettings(), datasets);
- }
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
diff -r b8e7f6becf78 -r 1cc7653ca84f artifacts/src/main/java/org/dive4elements/river/exports/extreme/ExtremeWQCurveGenerator.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/extreme/ExtremeWQCurveGenerator.java Tue Jun 05 19:10:38 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/extreme/ExtremeWQCurveGenerator.java Tue Jun 05 19:21:16 2018 +0200
@@ -19,6 +19,7 @@
import org.jfree.data.xy.XYSeries;
import org.dive4elements.artifactdatabase.state.ArtifactAndFacet;
+import org.dive4elements.artifacts.CallContext;
import org.dive4elements.river.artifacts.access.FixAnalysisAccess;
import org.dive4elements.river.artifacts.D4EArtifact;
import org.dive4elements.river.artifacts.model.DateRange;
@@ -114,7 +115,7 @@
) {
log.debug("doExtremeCurveBaseOut");
ExtremeCurveFacet facet = (ExtremeCurveFacet) aaf.getFacet();
- Curve curve = (Curve) facet.getData(aaf.getArtifact(), context);
+ Curve curve = (Curve) facet.getData(aaf.getArtifact(), getContext());
if (curve == null) {
log.warn("doExtremeCurveBaseOut: Facet does not contain Curve");
return;
@@ -155,7 +156,7 @@
) {
log.debug("doExtremeCurveOut");
ExtremeCurveFacet facet = (ExtremeCurveFacet) aaf.getFacet();
- Curve curve = (Curve) facet.getData(aaf.getArtifact(), context);
+ Curve curve = (Curve) facet.getData(aaf.getArtifact(), getContext());
if (curve == null) {
log.warn("doExtremeCurveOut: Facet does not contain Curve");
return;
@@ -189,29 +190,29 @@
@Override
- protected String getChartTitle() {
+ protected String getChartTitle(final CallContext context) {
return Resources.format(
- context.getMeta(),
+ getContext().getMeta(),
I18N_CHART_TITLE,
I18N_CHART_TITLE_DEFAULT,
- context.getContextValue(CURRENT_KM));
+ getContext().getContextValue(CURRENT_KM));
}
@Override
- protected String getDefaultChartTitle() {
+ protected String getDefaultChartTitle(final CallContext context) {
return msg(I18N_CHART_TITLE, I18N_CHART_TITLE_DEFAULT);
}
@Override
- protected String getDefaultChartSubtitle() {
+ protected String getDefaultChartSubtitle(final CallContext context) {
FixAnalysisAccess access = new FixAnalysisAccess(artifact);
DateRange dateRange = access.getDateRange();
DateRange refRange = access.getReferencePeriod();
if (dateRange != null && refRange != null) {
return Resources.format(
- context.getMeta(),
+ getContext().getMeta(),
I18N_CHART_SUBTITLE,
"",
access.getRiverName(),
@@ -225,8 +226,8 @@
}
@Override
- protected void addSubtitles(JFreeChart chart) {
- String defaultSubtitle = getDefaultChartSubtitle();
+ protected void addSubtitles(final CallContext context, JFreeChart chart) {
+ String defaultSubtitle = getDefaultChartSubtitle(context);
if (defaultSubtitle == null || defaultSubtitle.length() == 0) {
return;
@@ -236,13 +237,13 @@
}
@Override
- protected String getDefaultXAxisLabel() {
+ protected String getDefaultXAxisLabel(final CallContext context) {
return msg(I18N_XAXIS_LABEL, I18N_XAXIS_LABEL_DEFAULT);
}
@Override
protected String getDefaultYAxisLabel(int pos) {
- D4EArtifact flys = (D4EArtifact) master;
+ D4EArtifact flys = getArtifact();
String unit = RiverUtils.getRiver(flys).getWstUnit().getName();
if (pos == 0) {
diff -r b8e7f6becf78 -r 1cc7653ca84f artifacts/src/main/java/org/dive4elements/river/exports/fixings/FixDeltaWtGenerator.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/fixings/FixDeltaWtGenerator.java Tue Jun 05 19:10:38 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/fixings/FixDeltaWtGenerator.java Tue Jun 05 19:21:16 2018 +0200
@@ -106,24 +106,24 @@
@Override
- protected String getDefaultChartTitle() {
+ protected String getDefaultChartTitle(final CallContext context) {
return msg(I18N_CHART_TITLE, I18N_CHART_TITLE);
}
@Override
- protected String getChartTitle() {
+ protected String getChartTitle(final CallContext context) {
return Resources.format(
context.getMeta(),
I18N_CHART_TITLE,
"",
FixChartGenerator
- .getCurrentKmFromRequest(request).doubleValue());
+ .getCurrentKmFromRequest(getRequest()).doubleValue());
}
@Override
- protected String getDefaultChartSubtitle() {
+ protected String getDefaultChartSubtitle(final CallContext context) {
FixAnalysisAccess access = new FixAnalysisAccess(artifact);
DateRange dateRange = access.getDateRange();
DateRange refRange = access.getReferencePeriod();
@@ -140,7 +140,7 @@
@Override
- protected String getDefaultXAxisLabel() {
+ protected String getDefaultXAxisLabel(final CallContext context) {
return msg(I18N_XAXIS_LABEL, I18N_XAXIS_LABEL);
}
@@ -171,6 +171,8 @@
this.artifact = (D4EArtifact)artifactFacet.getArtifact();
+ final CallContext context = getContext();
+
if (name.contains(FIX_SECTOR_AVERAGE_DWT)) {
doSectorAverageOut(
(D4EArtifact) artifactFacet.getArtifact(),
@@ -388,10 +390,10 @@
return;
}
- Locale locale = Resources.getLocale(context.getMeta());
+ Locale locale = Resources.getLocale(getContext().getMeta());
NumberFormat nf = NumberFormat.getInstance(locale);
- List<XYTextAnnotation> textAnnos = new ArrayList<XYTextAnnotation>();
+ List<XYTextAnnotation> textAnnos = new ArrayList<>();
for (int[] idxs: annoIdxMap.values()) {
diff -r b8e7f6becf78 -r 1cc7653ca84f artifacts/src/main/java/org/dive4elements/river/exports/fixings/FixWQCurveGenerator.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/fixings/FixWQCurveGenerator.java Tue Jun 05 19:10:38 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/fixings/FixWQCurveGenerator.java Tue Jun 05 19:21:16 2018 +0200
@@ -28,6 +28,7 @@
import org.dive4elements.artifactdatabase.state.ArtifactAndFacet;
import org.dive4elements.artifactdatabase.state.Facet;
+import org.dive4elements.artifacts.CallContext;
import org.dive4elements.river.artifacts.D4EArtifact;
import org.dive4elements.river.artifacts.StaticWKmsArtifact;
import org.dive4elements.river.artifacts.WINFOArtifact;
@@ -115,7 +116,7 @@
/** Returns value != 0 if the current km is not at a gauge. */
public double getCurrentGaugeDatum() {
- Object ckm = context.getContextValue(CURRENT_KM);
+ Object ckm = getContext().getContextValue(CURRENT_KM);
if (ckm != null) {
return DischargeCurveGenerator.getCurrentGaugeDatum(
(Double) ckm,
@@ -210,6 +211,8 @@
this.artifact = (D4EArtifact) aaf.getArtifact();
+ final CallContext context = getContext();
+
if(name.startsWith(FIX_SECTOR_AVERAGE_WQ)) {
doSectorAverageOut(aaf, doc, visible);
}
@@ -286,7 +289,7 @@
) {
log.debug("doSectorAverageOut");
- QWDDateRange qwdd = (QWDDateRange) aaf.getData(context);
+ QWDDateRange qwdd = (QWDDateRange) aaf.getData(getContext());
QWD qwd = qwdd != null ? qwdd.getQWD() : null;
if(qwd != null) {
@@ -305,7 +308,7 @@
) {
log.debug("doAnalysisEventsOut");
- QWD qwd = (QWD)aaf.getData(context);
+ QWD qwd = (QWD)aaf.getData(getContext());
if (qwd == null) {
log.debug("doAnalysisEventsOut: qwd == null");
@@ -365,7 +368,7 @@
) {
log.debug("doReferenceEventsOut");
- QWI qwd = (QWI)aaf.getData(context);
+ QWI qwd = (QWI)aaf.getData(getContext());
if (qwd == null) {
log.debug("doReferenceEventsOut: qwds == null");
return;
@@ -421,7 +424,7 @@
boolean visible
) {
XYSeries series = new StyledXYSeries(title, theme);
- Double ckm = (Double) context.getContextValue(CURRENT_KM);
+ Double ckm = (Double) getContext().getContextValue(CURRENT_KM);
if (wqkms == null || wqkms.getKms().length == 0 || ckm == null) {
log.info("addPointFromWQKms: No event data to show.");
return;
@@ -458,7 +461,7 @@
) {
log.debug("doEventsOut");
// Find W/Q at km.
- addPointFromWQKms((WQKms) aaf.getData(context),
+ addPointFromWQKms((WQKms) aaf.getData(getContext()),
aaf.getFacetDescription(), doc, visible);
}
@@ -472,7 +475,7 @@
FixWQCurveFacet facet = (FixWQCurveFacet)aaf.getFacet();
FixFunction func = (FixFunction)facet.getData(
- aaf.getArtifact(), context);
+ aaf.getArtifact(), getContext());
if (func == null) {
log.warn("doWQCurveOut: Facet does not contain FixFunction");
@@ -527,7 +530,7 @@
) {
log.debug("doOutlierOut");
- QWI[] qws = (QWI[])aaf.getData(context);
+ QWI[] qws = (QWI[])aaf.getData(getContext());
addQWSeries(qws, aaf, doc, visible);
}
@@ -543,7 +546,7 @@
return;
}
- Object qsectorsObj = aaf.getData(context);
+ Object qsectorsObj = aaf.getData(getContext());
if (qsectorsObj == null || !(qsectorsObj instanceof List)) {
log.warn("No QSectors coming from data.");
return;
@@ -631,7 +634,7 @@
log.debug("Got WKms");
WKms data = (WKms) wqkms;
- Double ckm = (Double) context.getContextValue(CURRENT_KM);
+ Double ckm = (Double) getContext().getContextValue(CURRENT_KM);
double location = (ckm != null)
? ckm.doubleValue()
: getRange()[0];
@@ -709,7 +712,7 @@
// be delivered by the facet already (instead of in the Generator).
log.debug("FixWQCurveGenerator: doWQOut: WQKms");
- addPointFromWQKms((WQKms)aaf.getData(context),
+ addPointFromWQKms((WQKms)aaf.getData(getContext()),
aaf.getFacetDescription(), theme, visible);
}
else {
@@ -773,7 +776,7 @@
}
@Override
- protected String getChartTitle() {
+ protected String getChartTitle(final CallContext context) {
return Resources.format(
context.getMeta(),
I18N_CHART_TITLE,
@@ -782,12 +785,12 @@
}
@Override
- protected String getDefaultChartTitle() {
+ protected String getDefaultChartTitle(final CallContext context) {
return msg(I18N_CHART_TITLE, I18N_CHART_TITLE_DEFAULT);
}
@Override
- protected String getDefaultChartSubtitle() {
+ protected String getDefaultChartSubtitle(final CallContext context) {
FixAnalysisAccess access = new FixAnalysisAccess(artifact);
DateRange dateRange = access.getDateRange();
DateRange refRange = access.getReferencePeriod();
@@ -808,8 +811,8 @@
}
@Override
- protected void addSubtitles(JFreeChart chart) {
- String defaultSubtitle = getDefaultChartSubtitle();
+ protected void addSubtitles(final CallContext context, final JFreeChart chart) {
+ String defaultSubtitle = getDefaultChartSubtitle(getContext());
if (defaultSubtitle == null || defaultSubtitle.length() == 0) {
return;
@@ -841,13 +844,13 @@
}
@Override
- protected String getDefaultXAxisLabel() {
+ protected String getDefaultXAxisLabel(final CallContext context) {
return msg(I18N_XAXIS_LABEL, I18N_XAXIS_LABEL_DEFAULT);
}
@Override
protected String getDefaultYAxisLabel(int pos) {
- D4EArtifact flys = (D4EArtifact) master;
+ D4EArtifact flys = getArtifact();
String unit = pos == 0
? "cm"
diff -r b8e7f6becf78 -r 1cc7653ca84f artifacts/src/main/java/org/dive4elements/river/exports/process/AnnotationProcessor.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/process/AnnotationProcessor.java Tue Jun 05 19:10:38 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/process/AnnotationProcessor.java Tue Jun 05 19:21:16 2018 +0200
@@ -38,7 +38,7 @@
// Nothing to do
return;
}
- CallContext context = generator.getCallContext();
+ CallContext context = generator.getContext();
if (!(bundle.getData(context) instanceof RiverAnnotation)) {
// Just a bit defensive should not happen
log.error("Incompatible facet in doOut");
@@ -62,7 +62,7 @@
// Nothing to do
return;
}
- CallContext context = generator.getCallContext();
+ CallContext context = generator.getContext();
if (!(bundle.getData(context) instanceof RiverAnnotation)) {
// Just a bit defensive should not happen
log.error("Incompatible facet in doOut");
diff -r b8e7f6becf78 -r 1cc7653ca84f artifacts/src/main/java/org/dive4elements/river/exports/process/AreaProcessor.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/process/AreaProcessor.java Tue Jun 05 19:10:38 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/process/AreaProcessor.java Tue Jun 05 19:21:16 2018 +0200
@@ -83,7 +83,7 @@
ArtifactAndFacet bundle,
ThemeDocument theme,
boolean visible) {
- CallContext context = generator.getCallContext();
+ CallContext context = generator.getContext();
String seriesName = bundle.getFacetDescription();
StyledAreaSeriesCollection area = new StyledAreaSeriesCollection(theme);
diff -r b8e7f6becf78 -r 1cc7653ca84f artifacts/src/main/java/org/dive4elements/river/exports/process/BedDiffHeightYearProcessor.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/process/BedDiffHeightYearProcessor.java Tue Jun 05 19:10:38 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/process/BedDiffHeightYearProcessor.java Tue Jun 05 19:21:16 2018 +0200
@@ -43,7 +43,7 @@
ThemeDocument theme,
boolean visible
) {
- CallContext context = generator.getCallContext();
+ CallContext context = generator.getContext();
Object data = bundle.getData(context);
Map<String, String> metaData = bundle.getFacet().getMetaData(
bundle.getArtifact(), context);
@@ -74,7 +74,7 @@
boolean visible,
int index
) {
- CallContext context = generator.getCallContext();
+ CallContext context = generator.getContext();
Object data = bundle.getData(context);
if (!(data instanceof double[][])) {
diff -r b8e7f6becf78 -r 1cc7653ca84f artifacts/src/main/java/org/dive4elements/river/exports/process/BedDiffYearProcessor.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/process/BedDiffYearProcessor.java Tue Jun 05 19:10:38 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/process/BedDiffYearProcessor.java Tue Jun 05 19:21:16 2018 +0200
@@ -42,7 +42,7 @@
ThemeDocument theme,
boolean visible
) {
- CallContext context = generator.getCallContext();
+ CallContext context = generator.getContext();
Map<String, String> metaData =
bundle.getFacet().getMetaData(bundle.getArtifact(), context);
yAxisLabel = metaData.get("Y");
diff -r b8e7f6becf78 -r 1cc7653ca84f artifacts/src/main/java/org/dive4elements/river/exports/process/BedHeightProcessor.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/process/BedHeightProcessor.java Tue Jun 05 19:10:38 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/process/BedHeightProcessor.java Tue Jun 05 19:21:16 2018 +0200
@@ -50,7 +50,7 @@
ThemeDocument theme,
boolean visible) {
XYSeries series = prepareSeries(
- bundle, theme, generator.getCallContext());
+ bundle, theme, generator.getContext());
if (series != null) {
generator.addAxisSeries(series, axisName, visible);
}
@@ -65,7 +65,7 @@
int index
) {
XYSeries series = prepareSeries(
- bundle, theme, generator.getCallContext());
+ bundle, theme, generator.getContext());
if (series != null) {
generator.addAxisSeries(series, index, visible);
}
@@ -120,7 +120,7 @@
D4EArtifact flys = (D4EArtifact) generator.getMaster();
String unit = new RiverAccess(flys).getRiver().getWstUnit().getName();
- CallMeta meta = generator.getCallContext().getMeta();
+ CallMeta meta = generator.getContext().getMeta();
if (yAxisLabel != null && !yAxisLabel.isEmpty()) {
return Resources.getMsg(
diff -r b8e7f6becf78 -r 1cc7653ca84f artifacts/src/main/java/org/dive4elements/river/exports/process/BedQualityDensityProcessor.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/process/BedQualityDensityProcessor.java Tue Jun 05 19:10:38 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/process/BedQualityDensityProcessor.java Tue Jun 05 19:21:16 2018 +0200
@@ -37,7 +37,7 @@
ArtifactAndFacet bundle,
ThemeDocument theme,
boolean visible) {
- CallContext context = generator.getCallContext();
+ CallContext context = generator.getContext();
StyledXYSeries series = new StyledXYSeries(bundle.getFacetDescription(),
theme);
Map<String, String> metaData = bundle.getFacet().getMetaData();
@@ -69,7 +69,7 @@
@Override
public String getAxisLabel(DiagramGenerator generator) {
- CallMeta meta = generator.getCallContext().getMeta();
+ CallMeta meta = generator.getContext().getMeta();
if (yAxisLabel != null && !yAxisLabel.isEmpty()) {
return Resources.getMsg(meta, yAxisLabel);
diff -r b8e7f6becf78 -r 1cc7653ca84f artifacts/src/main/java/org/dive4elements/river/exports/process/BedQualityDiameterProcessor.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/process/BedQualityDiameterProcessor.java Tue Jun 05 19:10:38 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/process/BedQualityDiameterProcessor.java Tue Jun 05 19:21:16 2018 +0200
@@ -37,7 +37,7 @@
ArtifactAndFacet bundle,
ThemeDocument theme,
boolean visible) {
- CallContext context = generator.getCallContext();
+ CallContext context = generator.getContext();
Map<String, String> metaData = bundle.getFacet().getMetaData();
StyledXYSeries series = new StyledXYSeries(bundle.getFacetDescription(),
theme);
@@ -71,7 +71,7 @@
@Override
public String getAxisLabel(DiagramGenerator generator) {
- CallMeta meta = generator.getCallContext().getMeta();
+ CallMeta meta = generator.getContext().getMeta();
if (yAxisLabel != null && !yAxisLabel.isEmpty()) {
return Resources.getMsg(meta, yAxisLabel);
diff -r b8e7f6becf78 -r 1cc7653ca84f artifacts/src/main/java/org/dive4elements/river/exports/process/BedQualityPorosityProcessor.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/process/BedQualityPorosityProcessor.java Tue Jun 05 19:10:38 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/process/BedQualityPorosityProcessor.java Tue Jun 05 19:21:16 2018 +0200
@@ -37,7 +37,7 @@
ArtifactAndFacet bundle,
ThemeDocument theme,
boolean visible) {
- CallContext context = generator.getCallContext();
+ CallContext context = generator.getContext();
Map<String, String> metaData = bundle.getFacet().getMetaData();
StyledXYSeries series = new StyledXYSeries(bundle.getFacetDescription(),
theme);
diff -r b8e7f6becf78 -r 1cc7653ca84f artifacts/src/main/java/org/dive4elements/river/exports/process/BedWidthProcessor.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/process/BedWidthProcessor.java Tue Jun 05 19:10:38 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/process/BedWidthProcessor.java Tue Jun 05 19:21:16 2018 +0200
@@ -41,7 +41,7 @@
ArtifactAndFacet bundle,
ThemeDocument theme,
boolean visible) {
- CallContext context = generator.getCallContext();
+ CallContext context = generator.getContext();
Map<String, String> metaData = bundle.getFacet().getMetaData();
StyledXYSeries series = new StyledXYSeries(bundle.getFacetDescription(),
theme);
diff -r b8e7f6becf78 -r 1cc7653ca84f artifacts/src/main/java/org/dive4elements/river/exports/process/DeltaWProcessor.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/process/DeltaWProcessor.java Tue Jun 05 19:10:38 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/process/DeltaWProcessor.java Tue Jun 05 19:21:16 2018 +0200
@@ -88,7 +88,7 @@
private void doSectorAverageOut(DiagramGenerator generator,
ArtifactAndFacet bundle,
ThemeDocument doc, boolean visible) {
- CallContext context = generator.getCallContext();
+ CallContext context = generator.getContext();
int index = bundle.getFacet().getIndex();
int sectorNdx = index & 3;
@@ -118,7 +118,7 @@
private void doReferenceEventsOut(DiagramGenerator generator,
ArtifactAndFacet bundle, ThemeDocument doc, boolean visible) {
- CallContext context = generator.getCallContext();
+ CallContext context = generator.getContext();
KMIndex<QWD> kms =
(KMIndex<QWD>)bundle.getData(context);
@@ -148,7 +148,7 @@
ArtifactAndFacet bundle,
ThemeDocument doc,
boolean visible) {
- CallContext context = generator.getCallContext();
+ CallContext context = generator.getContext();
KMIndex<QWD> kms =
(KMIndex<QWD>)bundle.getData(context);
@@ -178,7 +178,7 @@
ArtifactAndFacet bundle,
ThemeDocument doc,
boolean visible) {
- CallContext context = generator.getCallContext();
+ CallContext context = generator.getContext();
int index = bundle.getFacet().getIndex();
int sectorNdx = index & 3;
@@ -221,7 +221,7 @@
ArtifactAndFacet bundle,
ThemeDocument doc,
boolean visible) {
- CallContext context = generator.getCallContext();
+ CallContext context = generator.getContext();
KMIndex<double[]> kms =
(KMIndex<double[]>)bundle.getData(context);
diff -r b8e7f6becf78 -r 1cc7653ca84f artifacts/src/main/java/org/dive4elements/river/exports/process/DischargeProcessor.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/process/DischargeProcessor.java Tue Jun 05 19:10:38 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/process/DischargeProcessor.java Tue Jun 05 19:21:16 2018 +0200
@@ -60,7 +60,7 @@
ThemeDocument theme,
boolean visible
) {
- CallContext context = generator.getCallContext();
+ CallContext context = generator.getContext();
Object data = bundle.getData(context);
if (data instanceof WQKms) {
doDischargeOut(
@@ -99,7 +99,7 @@
ThemeDocument theme,
boolean visible
) {
- CallContext context = generator.getCallContext();
+ CallContext context = generator.getContext();
Map<String, String> metaData = bundle.getFacet().getMetaData(
bundle.getArtifact(), context);
WQKms data = (WQKms)bundle.getData(context);
@@ -123,7 +123,7 @@
@Override
public String getAxisLabel(DiagramGenerator generator) {
- CallMeta meta = generator.getCallContext().getMeta();
+ CallMeta meta = generator.getContext().getMeta();
RiverAccess access =
new RiverAccess((D4EArtifact)generator.getMaster());
String unit = access.getRiver().getWstUnit().getName();
diff -r b8e7f6becf78 -r 1cc7653ca84f artifacts/src/main/java/org/dive4elements/river/exports/process/FixDeltaWAProcessor.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/process/FixDeltaWAProcessor.java Tue Jun 05 19:10:38 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/process/FixDeltaWAProcessor.java Tue Jun 05 19:21:16 2018 +0200
@@ -39,7 +39,7 @@
ArtifactAndFacet bundle,
ThemeDocument theme,
boolean visible) {
- CallContext context = generator.getCallContext();
+ CallContext context = generator.getContext();
Object data = bundle.getData(context);
XYSeries series = new StyledXYSeries(
diff -r b8e7f6becf78 -r 1cc7653ca84f artifacts/src/main/java/org/dive4elements/river/exports/process/FixDeltaWProcessor.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/process/FixDeltaWProcessor.java Tue Jun 05 19:10:38 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/process/FixDeltaWProcessor.java Tue Jun 05 19:21:16 2018 +0200
@@ -39,7 +39,7 @@
ArtifactAndFacet bundle,
ThemeDocument theme,
boolean visible) {
- CallContext context = generator.getCallContext();
+ CallContext context = generator.getContext();
Object data = bundle.getData(context);
XYSeries series = new StyledXYSeries(
diff -r b8e7f6becf78 -r 1cc7653ca84f artifacts/src/main/java/org/dive4elements/river/exports/process/FixDerivedProcessor.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/process/FixDerivedProcessor.java Tue Jun 05 19:10:38 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/process/FixDerivedProcessor.java Tue Jun 05 19:21:16 2018 +0200
@@ -48,12 +48,12 @@
ThemeDocument theme,
boolean visible
) {
- CallContext context = generator.getCallContext();
+ CallContext context = generator.getContext();
Map<String, String> metaData = bundle.getFacet().getMetaData(
bundle.getArtifact(), context);
FixDerivateFacet facet = (FixDerivateFacet)bundle.getFacet();
FixFunction func = (FixFunction)facet.getData(
- bundle.getArtifact(), generator.getCallContext());
+ bundle.getArtifact(), generator.getContext());
yAxisLabel = metaData.get("Y");
@@ -86,7 +86,7 @@
@Override
public String getAxisLabel(DiagramGenerator generator) {
- CallMeta meta = generator.getCallContext().getMeta();
+ CallMeta meta = generator.getContext().getMeta();
RiverAccess access =
new RiverAccess((D4EArtifact)generator.getMaster());
String unit = access.getRiver().getWstUnit().getName();
diff -r b8e7f6becf78 -r 1cc7653ca84f artifacts/src/main/java/org/dive4elements/river/exports/process/FixWQProcessor.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/process/FixWQProcessor.java Tue Jun 05 19:10:38 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/process/FixWQProcessor.java Tue Jun 05 19:21:16 2018 +0200
@@ -111,7 +111,7 @@
) {
log.debug("doSectorAverageOut");
QWDDateRange qwdd = (QWDDateRange)bundle.getData(
- generator.getCallContext());
+ generator.getContext());
QWD qwd = qwdd != null ? qwdd.getQWD() : null;
if(qwd != null) {
@@ -154,7 +154,7 @@
) {
log.debug("doAnalysisEventsOut");
- QWD qwd = (QWD)bundle.getData(generator.getCallContext());
+ QWD qwd = (QWD)bundle.getData(generator.getContext());
if (qwd == null) {
log.debug("doAnalysisEventsOut: qwd == null");
@@ -206,7 +206,7 @@
boolean visible) {
log.debug("doReferenceEventsOut");
- QWI qwd = (QWI)bundle.getData(generator.getCallContext());
+ QWI qwd = (QWI)bundle.getData(generator.getContext());
if (qwd == null) {
log.debug("doReferenceEventsOut: qwds == null in "
+ bundle.getFacetDescription());
@@ -259,7 +259,7 @@
FixWQCurveFacet facet = (FixWQCurveFacet)bundle.getFacet();
FixFunction func = (FixFunction)facet.getData(
- bundle.getArtifact(), generator.getCallContext());
+ bundle.getArtifact(), generator.getContext());
if (func == null) {
log.warn("doWQCurveOut: Facet does not contain FixFunction");
@@ -292,7 +292,7 @@
) {
log.debug("doOutlierOut");
- QWI[] qws = (QWI[])bundle.getData(generator.getCallContext());
+ QWI[] qws = (QWI[])bundle.getData(generator.getContext());
if(qws != null) {
XYSeries series = new StyledXYSeries(
bundle.getFacetDescription(),
@@ -338,7 +338,7 @@
return;
}
- Object qsectorsObj = bundle.getData(generator.getCallContext());
+ Object qsectorsObj = bundle.getData(generator.getContext());
if (qsectorsObj == null || !(qsectorsObj instanceof List)) {
log.warn("No QSectors coming from data.");
return;
@@ -405,7 +405,7 @@
ThemeDocument theme,
boolean visible
) {
- Object data = bundle.getData(generator.getCallContext());
+ Object data = bundle.getData(generator.getContext());
List<StickyAxisAnnotation> xy = new ArrayList<StickyAxisAnnotation>();
if (data instanceof double[][]) {
log.debug("Got double[][]");
@@ -430,7 +430,7 @@
WKms wkms = (WKms) data;
Double ckm =
- (Double)generator.getCallContext().getContextValue(
+ (Double)generator.getContext().getContextValue(
FixChartGenerator.CURRENT_KM);
double location = (ckm != null)
? ckm.doubleValue()
@@ -454,14 +454,14 @@
ThemeDocument theme,
boolean visible
) {
- Object data = bundle.getData(generator.getCallContext());
+ Object data = bundle.getData(generator.getContext());
if (data instanceof WQKms) {
WQKms wqkms = (WQKms)data;
// TODO As in doEventsOut, the value-searching should
// be delivered by the facet already
XYSeries series = new StyledXYSeries(
bundle.getFacetDescription(), theme);
- Double ckm = (Double) generator.getCallContext()
+ Double ckm = (Double) generator.getContext()
.getContextValue(CURRENT_KM);
if (wqkms == null || wqkms.getKms().length == 0 || ckm == null) {
@@ -525,7 +525,7 @@
@Override
public String getAxisLabel(DiagramGenerator generator) {
- CallMeta meta = generator.getCallContext().getMeta();
+ CallMeta meta = generator.getContext().getMeta();
RiverAccess access = new RiverAccess((D4EArtifact)generator
.getMaster());
diff -r b8e7f6becf78 -r 1cc7653ca84f artifacts/src/main/java/org/dive4elements/river/exports/process/FlowVelocityProcessor.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/process/FlowVelocityProcessor.java Tue Jun 05 19:10:38 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/process/FlowVelocityProcessor.java Tue Jun 05 19:21:16 2018 +0200
@@ -41,7 +41,7 @@
ArtifactAndFacet bundle,
ThemeDocument theme,
boolean visible) {
- CallContext context = generator.getCallContext();
+ CallContext context = generator.getContext();
Map<String, String> metaData = bundle.getFacet().getMetaData();
StyledXYSeries series = new StyledXYSeries(
bundle.getFacetDescription(),
diff -r b8e7f6becf78 -r 1cc7653ca84f artifacts/src/main/java/org/dive4elements/river/exports/process/ManualPointsProcessor.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/process/ManualPointsProcessor.java Tue Jun 05 19:10:38 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/process/ManualPointsProcessor.java Tue Jun 05 19:21:16 2018 +0200
@@ -40,7 +40,7 @@
ArtifactAndFacet bundle,
ThemeDocument theme,
boolean visible) {
- CallContext context = generator.getCallContext();
+ CallContext context = generator.getContext();
String seriesName = bundle.getFacetDescription();
XYSeries series = new StyledXYSeries(seriesName, theme);
String jsonData = (String) bundle.getData(context);
diff -r b8e7f6becf78 -r 1cc7653ca84f artifacts/src/main/java/org/dive4elements/river/exports/process/MiddleBedHeightProcessor.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/process/MiddleBedHeightProcessor.java Tue Jun 05 19:10:38 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/process/MiddleBedHeightProcessor.java Tue Jun 05 19:21:16 2018 +0200
@@ -43,7 +43,7 @@
ArtifactAndFacet bundle,
ThemeDocument theme,
boolean visible) {
- CallContext context = generator.getCallContext();
+ CallContext context = generator.getContext();
Map<String, String> metaData = bundle.getFacet().getMetaData();
yAxisLabel = metaData.get("Y");
diff -r b8e7f6becf78 -r 1cc7653ca84f artifacts/src/main/java/org/dive4elements/river/exports/process/MiscDischargeProcessor.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/process/MiscDischargeProcessor.java Tue Jun 05 19:10:38 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/process/MiscDischargeProcessor.java Tue Jun 05 19:21:16 2018 +0200
@@ -66,7 +66,7 @@
ArtifactAndFacet bundle,
ThemeDocument theme,
boolean visible) {
- CallContext context = generator.getCallContext();
+ CallContext context = generator.getContext();
Object data = bundle.getData(context);
if (HISTORICAL_DISCHARGE_WQ_Q.equals(bundle.getFacetName())) {
doHistoricalDischargeOutQ(generator, bundle, theme, visible);
@@ -108,7 +108,7 @@
boolean visible,
int axisIndex
) {
- CallContext context = generator.getCallContext();
+ CallContext context = generator.getContext();
Object data = bundle.getData(context);
/* TODO: Remove the first case.*/
if (bundle.getFacetName().equals(STATIC_WQ)) {
@@ -145,7 +145,7 @@
) {
XYSeries series = new StyledXYSeries(
bundle.getFacetDescription(), theme);
- Object wq = bundle.getData(generator.getCallContext());
+ Object wq = bundle.getData(generator.getContext());
if (wq instanceof double[][]) {
double [][] data = (double [][]) wq;
StyledSeriesBuilder.addPoints(series, data, true);
@@ -278,7 +278,7 @@
boolean visible
) {
double value = Double.valueOf(
- bundle.getData(generator.getCallContext()).toString());
+ bundle.getData(generator.getContext()).toString());
generator.addDomainMarker(
new StyledValueMarker(value, theme), visible);
}
@@ -290,7 +290,7 @@
boolean visible
) {
double value = Double.valueOf(
- bundle.getData(generator.getCallContext()).toString());
+ bundle.getData(generator.getContext()).toString());
generator.addValueMarker(
new StyledValueMarker(value, theme), visible);
}
@@ -373,7 +373,7 @@
@Override
public String getAxisLabel(DiagramGenerator generator) {
- CallMeta meta = generator.getCallContext().getMeta();
+ CallMeta meta = generator.getContext().getMeta();
RiverAccess access = new RiverAccess((D4EArtifact)generator
.getMaster());
String unit = access.getRiver().getWstUnit().getName();
diff -r b8e7f6becf78 -r 1cc7653ca84f artifacts/src/main/java/org/dive4elements/river/exports/process/QOutProcessor.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/process/QOutProcessor.java Tue Jun 05 19:10:38 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/process/QOutProcessor.java Tue Jun 05 19:21:16 2018 +0200
@@ -47,7 +47,7 @@
ArtifactAndFacet bundle,
ThemeDocument theme,
boolean visible) {
- CallContext context = generator.getCallContext();
+ CallContext context = generator.getContext();
Object data = bundle.getData(context);
XYSeries series = new StyledXYSeries(
bundle.getFacetDescription(), theme);
@@ -81,7 +81,7 @@
boolean visible,
int index)
{
- CallContext context = generator.getCallContext();
+ CallContext context = generator.getContext();
WQKms wqkms = (WQKms) bundle.getData(context);
XYSeries series = new StyledXYSeries(
diff -r b8e7f6becf78 -r 1cc7653ca84f artifacts/src/main/java/org/dive4elements/river/exports/process/SQRelationProcessor.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/process/SQRelationProcessor.java Tue Jun 05 19:10:38 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/process/SQRelationProcessor.java Tue Jun 05 19:21:16 2018 +0200
@@ -47,7 +47,7 @@
ArtifactAndFacet bundle,
ThemeDocument theme,
boolean visible) {
- CallContext context = generator.getCallContext();
+ CallContext context = generator.getContext();
String facetName = bundle.getFacetName();
StyledXYSeries series;
Object data = bundle.getData(context);
diff -r b8e7f6becf78 -r 1cc7653ca84f artifacts/src/main/java/org/dive4elements/river/exports/process/SedimentDensityProcessor.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/process/SedimentDensityProcessor.java Tue Jun 05 19:10:38 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/process/SedimentDensityProcessor.java Tue Jun 05 19:21:16 2018 +0200
@@ -41,7 +41,7 @@
ArtifactAndFacet bundle,
ThemeDocument theme,
boolean visible) {
- CallContext context = generator.getCallContext();
+ CallContext context = generator.getContext();
XYSeries series = new StyledXYSeries(bundle.getFacetDescription(),
theme);
Object data = bundle.getData(context);
diff -r b8e7f6becf78 -r 1cc7653ca84f artifacts/src/main/java/org/dive4elements/river/exports/process/SedimentLoadLSProcessor.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/process/SedimentLoadLSProcessor.java Tue Jun 05 19:10:38 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/process/SedimentLoadLSProcessor.java Tue Jun 05 19:21:16 2018 +0200
@@ -31,7 +31,7 @@
ThemeDocument theme,
boolean visible) {
log.debug("doOut " + bundle.getFacetName());
- CallContext context = generator.getCallContext();
+ CallContext context = generator.getContext();
XYSeries series = new StyledXYSeries(bundle.getFacetDescription(),
false, // Handle NaN
theme);
diff -r b8e7f6becf78 -r 1cc7653ca84f artifacts/src/main/java/org/dive4elements/river/exports/process/SedimentLoadProcessor.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/process/SedimentLoadProcessor.java Tue Jun 05 19:10:38 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/process/SedimentLoadProcessor.java Tue Jun 05 19:21:16 2018 +0200
@@ -41,7 +41,7 @@
ThemeDocument theme,
boolean visible) {
- CallContext context = generator.getCallContext();
+ CallContext context = generator.getContext();
XYSeries series = new StyledXYSeries(bundle.getFacetDescription(),
false, // Handle NaN
theme);
diff -r b8e7f6becf78 -r 1cc7653ca84f artifacts/src/main/java/org/dive4elements/river/exports/process/ShearStressProcessor.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/process/ShearStressProcessor.java Tue Jun 05 19:10:38 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/process/ShearStressProcessor.java Tue Jun 05 19:21:16 2018 +0200
@@ -37,7 +37,7 @@
ArtifactAndFacet bundle,
ThemeDocument theme,
boolean visible) {
- CallContext context = generator.getCallContext();
+ CallContext context = generator.getContext();
XYSeries series = new StyledXYSeries(bundle.getFacetDescription(),
theme);
String facetName = bundle.getFacetName();
diff -r b8e7f6becf78 -r 1cc7653ca84f artifacts/src/main/java/org/dive4elements/river/exports/process/WOutProcessor.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/process/WOutProcessor.java Tue Jun 05 19:10:38 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/process/WOutProcessor.java Tue Jun 05 19:21:16 2018 +0200
@@ -50,7 +50,7 @@
boolean visible
) {
log.debug("Processing facet: " + bundle.getFacetName());
- CallContext context = generator.getCallContext();
+ CallContext context = generator.getContext();
Object data = bundle.getData(context);
XYSeries series = new StyledXYSeries(
@@ -128,7 +128,7 @@
{
log.debug("doOut");
- CallContext context = generator.getCallContext();
+ CallContext context = generator.getContext();
XYSeries series = new StyledXYSeries(
bundle.getFacetDescription(), theme);
diff -r b8e7f6becf78 -r 1cc7653ca84f artifacts/src/main/java/org/dive4elements/river/jfree/AnnotationHelper.java
--- a/artifacts/src/main/java/org/dive4elements/river/jfree/AnnotationHelper.java Tue Jun 05 19:10:38 2018 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,413 +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.jfree;
-
-import org.dive4elements.river.themes.ThemeDocument;
-
-import java.util.List;
-import java.util.ArrayList;
-import java.util.Map;
-import java.util.SortedMap;
-
-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.jfree.chart.renderer.xy.XYItemRenderer;
-
-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 log = 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";
-
-
- public static void addYAnnotationsToRenderer(
- SortedMap<Integer, RiverAnnotation> yAnnotations,
- XYPlot plot,
- ChartSettings settings,
- Map<Integer, AxisDataset> datasets
- ) {
- List<RiverAnnotation> annotations = new ArrayList<RiverAnnotation>();
-
- for (Map.Entry<Integer, RiverAnnotation> entry:
- yAnnotations.entrySet()) {
- int axis = entry.getKey();
- AxisDataset dataset = datasets.get(new Integer(axis));
-
- if (dataset == null || dataset.getRange() == null) {
- log.warn("No dataset available and active for axis " + axis);
- }
- else {
- RiverAnnotation ya = entry.getValue();
- for (StickyAxisAnnotation sta: ya.getAxisTextAnnotations()) {
- sta.setAxisSymbol(axis);
- }
- annotations.add(ya);
- }
- }
-
- addAnnotationsToRenderer(annotations, plot, settings, datasets);
- }
-
- /**
- * Add annotations (Sticky, Text and hyk zones) to a plot.
- * @param annotations Annotations to add
- * @param plot XYPlot to add annotations to.
- * @param settings ChartSettings object for settings.
- * @param datasets Map of axis index and datasets
- */
- public static void addAnnotationsToRenderer(
- List<RiverAnnotation> annotations,
- XYPlot plot,
- ChartSettings settings,
- Map<Integer, AxisDataset> datasets
- ) {
- if (annotations == null || annotations.isEmpty()) {
- log.debug("addAnnotationsToRenderer: no annotations.");
- return;
- }
-
- // OPTMIMIZE: Pre-calculate positions
- ChartArea area = new ChartArea(
- plot.getDomainAxis(0),
- plot.getRangeAxis());
-
- // 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 Theming 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;
- }
-
- Color textColor = theme.parseTextColor();
- if (textColor == null) {
- textColor = 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)
- );
-
- newItem.setLabelPaint(textColor);
-
- 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 axisIndex = annotation.getAxisSymbol();
- XYItemRenderer renderer = null;
- if (dataset != null && dataset.getDatasets().length > 0) {
- renderer = plot.getRendererForDataset(dataset.getDatasets()[0]);
- }
- else {
- renderer = plot.getRenderer();
- }
-
- 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 {
- // Stick to the "right" (opposed to left) Y-Axis.
- if (axisIndex != 0 && plot.getRangeAxis(axisIndex) != null) {
- // 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.
- textAnnotation = new CollisionFreeXYTextAnnotation(
- annotation.getText(),
- area.ofRight(TEXT_OFF),
- annotation.getPos()
- );
- textAnnotation.setRotationAnchor(TextAnchor.CENTER_RIGHT);
- textAnnotation.setTextAnchor(TextAnchor.CENTER_RIGHT);
- lineAnnotation = createRightStickAnnotation(
- area, annotation.getPos(), lineStyle);
-
- // hit-lines for duration curve
- ChartArea area2 = new ChartArea(
- plot.getDomainAxis(), plot.getRangeAxis(axisIndex));
- 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);
- renderer.addAnnotation(hitLineAnnotation,
- org.jfree.ui.Layer.BACKGROUND);
- }
- if (theme.parseShowHorizontalLine()) {
- XYLineAnnotation lineBackAnnotation =
- createStickyLineAnnotation(
- StickyAxisAnnotation.SimpleAxis.Y_AXIS2,
- annotation.getPos(), annotation.getHitPoint(),
- area2, lineStyle);
- renderer.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);
- renderer.addAnnotation(hitLineAnnotation,
- org.jfree.ui.Layer.BACKGROUND);
- }
- if (theme.parseShowVerticalLine()) {
- XYLineAnnotation lineBackAnnotation =
- createStickyLineAnnotation(
- StickyAxisAnnotation.SimpleAxis.X_AXIS,
- annotation.getHitPoint(), annotation.getPos(),
- area, lineStyle);
- renderer.addAnnotation(lineBackAnnotation,
- org.jfree.ui.Layer.BACKGROUND);
- }
- }
- }
- }
-
- // Style the text.
- if (textStyle != null) {
- textStyle.apply(textAnnotation);
- }
-
- // Add the Annotations to renderer.
- renderer.addAnnotation(textAnnotation, org.jfree.ui.Layer.FOREGROUND);
- renderer.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.atRight(), pos,
- area.ofRight(ANNOTATIONS_AXIS_OFFSET), 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);
- }
- }
-
-};
More information about the Dive4Elements-commits
mailing list