# HG changeset patch # User gernotbelger # Date 1518698795 -3600 # Node ID 87a2424254670dc889965fe987f22cf32091c986 # Parent f431aec10d2cc6a6d4a8dbcf6f7b18397c48a3aa Introduced ChartExtender that allows to tweak the charts for very specific use cases. diff -r f431aec10d2c -r 87a242425467 artifacts/src/main/java/org/dive4elements/river/exports/ChartExtender.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/artifacts/src/main/java/org/dive4elements/river/exports/ChartExtender.java Thu Feb 15 13:46:35 2018 +0100 @@ -0,0 +1,34 @@ +/** 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 org.jfree.chart.plot.XYPlot; + +/** + * Implementors of this class can be used to tweak some very application specific behaviour within the charts.
+ * Implementations should not have a state, because they are instantiated only once. + * + * @author Gernot Belger + */ +public interface ChartExtender { + + /** + * Called after {@link DiagramGenerator#autoZoom(org.jfree.chart.plot.XYPlot)} was called, allows to tweak auto zoom + * behavior. + */ + void afterAutoZoom(DiagramGenerator generator); + + /** + * Called after the complete chart is generated. + * + * @param plot + */ + void afterGenerateChart(DiagramGenerator generator, XYPlot plot); +} \ No newline at end of file diff -r f431aec10d2c -r 87a242425467 artifacts/src/main/java/org/dive4elements/river/exports/ChartGenerator2.java --- a/artifacts/src/main/java/org/dive4elements/river/exports/ChartGenerator2.java Wed Feb 14 19:06:21 2018 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/exports/ChartGenerator2.java Thu Feb 15 13:46:35 2018 +0100 @@ -22,6 +22,7 @@ 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; @@ -139,6 +140,8 @@ protected String outName; + private Map axisNameToAxis = new HashMap<>(); + /** * Default constructor that initializes internal data structures. */ @@ -1479,8 +1482,7 @@ String axisName = axisIndexToName(index); - IdentifiableNumberAxis axis = new IdentifiableNumberAxis( - axisName, getYAxisLabel(axisName)); + IdentifiableNumberAxis axis = new IdentifiableNumberAxis(axisName, getYAxisLabel(axisName)); axis.setAutoRangeIncludesZero(false); axis.setLabelFont(labelFont); @@ -1489,6 +1491,9 @@ axis.setLowerMargin(0); axis.setUpperMargin(0); + /* remember axis for lookup */ + axisNameToAxis.put( axisName, axis ); + return axis; } @@ -1599,4 +1604,8 @@ public CallContext getCallContext() { return context; } -} + + public final IdentifiableNumberAxis getAxis(final String axisName) { + return axisNameToAxis.get(axisName); + } +} \ No newline at end of file diff -r f431aec10d2c -r 87a242425467 artifacts/src/main/java/org/dive4elements/river/exports/DiagramAttributes.java --- a/artifacts/src/main/java/org/dive4elements/river/exports/DiagramAttributes.java Wed Feb 14 19:06:21 2018 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/exports/DiagramAttributes.java Thu Feb 15 13:46:35 2018 +0100 @@ -9,6 +9,8 @@ package org.dive4elements.river.exports; import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; import java.util.List; import org.w3c.dom.Element; @@ -82,6 +84,10 @@ public List getProcessors() { return processors; } + + public Collection getExtenders() { + return DiagramAttributes.this.getExtenders(); + } public Title getTitle() { return DiagramAttributes.this.getTitle(); @@ -345,6 +351,7 @@ private List axesAttrs; private List axesProcessors; + private List extenders = new ArrayList<>(); private Title title; private Title subtitle; @@ -363,6 +370,7 @@ parseTitle(config); parseSubtitle(config); parseDomainAxis(config); + parseExtenders(config); return this; } @@ -459,6 +467,10 @@ public List getAxesProcessors() { return axesProcessors; } + + public Collection getExtenders() { + return Collections.unmodifiableCollection(extenders); + } public Title getTitle() { return title; @@ -493,6 +505,33 @@ } } } + + private void parseExtenders(final Element config) { + final NodeList processorNodes = config.getElementsByTagName("chartextender"); + + for (int i = 0, N = processorNodes.getLength(); i < N; ++i) { + final Element extenderElement = (Element)processorNodes.item(i); + final String className = extenderElement.getAttribute("class").trim(); + if (className.isEmpty() ) { + log.error("chartextender missing 'class' attribute"); + continue; + } + + try { + final Class protoclass = Class.forName(className); + if( !ChartExtender.class.isAssignableFrom(protoclass) ) { + log.error(String.format( "Chart extender must implement interface ChartExtender: %s", className) ); + continue; + } + + final ChartExtender extender = (ChartExtender) protoclass.newInstance(); + extenders.add(extender); + } + catch (ClassNotFoundException | InstantiationException | IllegalAccessException cnfe) { + log.error(String.format( "Failed to load or create chartextender class: %s", className ), cnfe); + } + } + } private void parseTitle(Element config) { title = extractTitle(config, "title"); diff -r f431aec10d2c -r 87a242425467 artifacts/src/main/java/org/dive4elements/river/exports/DiagramGenerator.java --- a/artifacts/src/main/java/org/dive4elements/river/exports/DiagramGenerator.java Wed Feb 14 19:06:21 2018 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/exports/DiagramGenerator.java Thu Feb 15 13:46:35 2018 +0100 @@ -14,6 +14,7 @@ import java.text.NumberFormat; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashSet; @@ -238,6 +239,12 @@ aggregateLegendEntries(plot); + /* allow extenders to do some work */ + final Collection extenders = this.diagramAttributes.getExtenders(); + for (final ChartExtender extender : extenders) { + extender.afterGenerateChart(this, plot); + } + return chart; } @@ -390,12 +397,19 @@ isLog().evaluate((D4EArtifact)getMaster(), context); if (logarithmic) { - return new LogarithmicAxis(label); + final LogarithmicAxis axis = new LogarithmicAxis(label); + // REMARK: we overwrite the default values to 0.0, because in earlier version margins were never applied. + axis.setLowerMargin(0); + axis.setUpperMargin(0); + return axis; } final NumberAxis axis = new NumberAxis(label); // REMARK: we overwrite the default values to 0.0, because in earlier version margins were never applied. axis.setLowerMargin(0); axis.setUpperMargin(0); + // REMARK: we overwrite the default values to 0.0, because in earlier version margins were never applied. + axis.setLowerMargin(0); + axis.setUpperMargin(0); return axis; } @@ -739,9 +753,14 @@ log.debug("Prepare zoom settings for y axis at index: " + i); zoom(plot, yaxis, getYBounds(Integer.valueOf(i)), yrange); } + + /* allow chart extenders to tweak zoom behaviour */ + final Collection extenders = this.diagramAttributes.getExtenders(); + for (final ChartExtender extender : extenders) { + extender.afterAutoZoom(this); + } } - protected Range getDomainAxisRange() { String[] ranges = getDomainAxisRangeFromRequest();