changeset 9325:094ed9d1f2ad

Fixed: change of point style of interpolated data did not change in WQ chart of fixanalysis Fixed: change of point style of interpolated data did not change in dWt chart of fixanalysis; also had duplicate legend entries
author gernotbelger
date Fri, 27 Jul 2018 14:33:41 +0200
parents 058701d91552
children 0452f1c1bad3
files artifacts/src/main/java/org/dive4elements/river/artifacts/model/fixings/FixAnalysisCalculation.java artifacts/src/main/java/org/dive4elements/river/exports/AbstractChartGenerator.java artifacts/src/main/java/org/dive4elements/river/exports/TimeseriesChartGenerator.java artifacts/src/main/java/org/dive4elements/river/exports/fixings/FixDeltaWtGenerator.java artifacts/src/main/java/org/dive4elements/river/exports/fixings/FixWQCurveGenerator.java artifacts/src/main/java/org/dive4elements/river/exports/process/FixWQProcessor.java artifacts/src/main/java/org/dive4elements/river/jfree/XYStyle.java artifacts/src/main/java/org/dive4elements/river/themes/ThemeDocument.java
diffstat 8 files changed, 216 insertions(+), 324 deletions(-) [+]
line wrap: on
line diff
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/model/fixings/FixAnalysisCalculation.java	Fri Jul 27 14:32:14 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/model/fixings/FixAnalysisCalculation.java	Fri Jul 27 14:33:41 2018 +0200
@@ -130,7 +130,8 @@
         int kmIndex   = parameters.columnIndex("km");
         int maxQIndex = parameters.columnIndex("max_q");
 
-        double [] wq = new double[2];
+        final double [] ws = new double[1];
+        final double [] qs = new double[1];
 
         int [] parameterIndices =
             parameters.columnIndices(function.getParameterNames());
@@ -221,33 +222,43 @@
                             continue;
                         }
 
-                        Column column = cc.getColumn(meta);
-                        if (column == null || !column.getQW(km, wq)) {
+                        final Column column = cc.getColumn(meta);
+                        if (column == null )
                             continue;
-                        }
 
-                        double fw = instance.value(wq[1]);
+                        boolean interpolated = !column.getQW(km, qs, ws, 0);
+                        // FIXME: it was like this before... check if this has an effekt on the calculation
+                        interpolated = true;
+
+                        final double w = ws[0];
+                        final double q = qs[0];
+                        if( Double.isNaN(w) || Double.isNaN(q))
+                            continue;
+
+                        double fw = instance.value(q);
                         if (Double.isNaN(fw)) {
                             continue;
                         }
 
-                        double dw = (wq[0] - fw)*100.0;
+                        double dw = (w - fw)*100.0;
 
+                        
                         stdDev.increment(dw);
 
                         Date date = column.getDate();
                         String description = column.getDescription();
-
+                        
+                        
                         QWD qwd = new QWD(
-                            wq[1], wq[0],
+                            q, w,
                             description,
-                            date, true,
+                            date, interpolated,
                             dw, getIndex(col2index, column.getIndex()));
 
                         qwds.add(qwd);
 
-                        sumW += wq[0];
-                        sumQ += wq[1];
+                        sumW += w;
+                        sumQ += q;
 
                         dateAverager.add(date);
                     }
--- a/artifacts/src/main/java/org/dive4elements/river/exports/AbstractChartGenerator.java	Fri Jul 27 14:32:14 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/AbstractChartGenerator.java	Fri Jul 27 14:33:41 2018 +0200
@@ -930,7 +930,7 @@
             }
 
             LegendItem legendItem = renderer.getLegendItem(idx, s);
-            if (legendItem.getLabel().endsWith(" ") || legendItem.getLabel().endsWith("interpol")) {
+            if (legendItem.getLabel().endsWith(" ")) {
                 legendItem = null;
             }
 
--- a/artifacts/src/main/java/org/dive4elements/river/exports/TimeseriesChartGenerator.java	Fri Jul 27 14:32:14 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/TimeseriesChartGenerator.java	Fri Jul 27 14:33:41 2018 +0200
@@ -66,8 +66,6 @@
 
     protected List<Marker> valueMarker;
 
-    protected Map<String, String> attributes;
-
     protected boolean domainZeroLineVisible;
 
     private static final Logger log =
@@ -90,7 +88,6 @@
         yBounds = new HashMap<Integer, Bounds>();
         domainMarker = new ArrayList<Marker>();
         valueMarker = new ArrayList<Marker>();
-        attributes = new HashMap<String, String>();
     }
 
     @Override
@@ -120,8 +117,6 @@
         addValueAxisMarker(plot);
         adaptZoom(plot);
 
-        applySeriesAttributes(plot);
-
         consumeAxisSettings(plot);
 
         addAnnotationsToRenderer(plot);
@@ -715,87 +710,6 @@
         valueMarker.clear();
     }
 
-    public void addAttribute(String seriesKey, String name) {
-        attributes.put(seriesKey, name);
-    }
-
-    private LegendItem getLegendItemFor(XYPlot plot, String interSeriesKey) {
-        LegendItemCollection litems = plot.getLegendItems();
-        Iterator<LegendItem> iter = litems.iterator();
-        while(iter.hasNext()) {
-            LegendItem item = iter.next();
-            if(interSeriesKey.startsWith(item.getSeriesKey().toString())) {
-                return item;
-            }
-        }
-        return null;
-    }
-
-    protected void applySeriesAttributes(XYPlot plot) {
-        int count  = plot.getDatasetCount();
-        for (int i = 0; i < count; i++) {
-            XYDataset data = plot.getDataset(i);
-            if (data == null) {
-                continue;
-            }
-
-            int seriesCount = data.getSeriesCount();
-            for (int j = 0; j < seriesCount; j++) {
-                StyledTimeSeries series =
-                    (StyledTimeSeries)getSeriesOf(data, j);
-                String key = series.getKey().toString();
-
-                if (attributes.containsKey(key)) {
-                    // Interpolated points are drawn unfilled
-                    if (attributes.get(key).equals("interpolate")) {
-                        XYLineAndShapeRenderer renderer =
-                                series.getStyle().getRenderer();
-                        renderer.setSeriesPaint(
-                            j,
-                            renderer.getSeriesFillPaint(j));
-                        renderer.setSeriesShapesFilled(j, false);
-
-                        LegendItem legendItem = getLegendItemFor(plot, key);
-                        if(legendItem != null) {
-                            LegendItem interLegend = new LegendItem(
-                                    legendItem.getLabel(),
-                                    legendItem.getDescription(),
-                                    legendItem.getToolTipText(),
-                                    legendItem.getURLText(),
-                                    legendItem.isShapeVisible(),
-                                    legendItem.getShape(),
-                                    false, // shapeFilled?
-                                    legendItem.getFillPaint(),
-                                    true,  // shapeOutlineVisible?
-                                    renderer.getSeriesFillPaint(j),
-                                    legendItem.getOutlineStroke(),
-                                    legendItem.isLineVisible(),
-                                    legendItem.getLine(),
-                                    legendItem.getLineStroke(),
-                                    legendItem.getLinePaint()
-                                    );
-                            interLegend.setSeriesKey(series.getKey());
-                            log.debug("applySeriesAttributes: "
-                                + "draw unfilled legend item");
-                            plot.getLegendItems().add(interLegend);
-                        }
-                    }
-                }
-
-                if (attributes.containsKey(key)) {
-                    if(attributes.get(key).equals("outline")) {
-                        XYLineAndShapeRenderer renderer =
-                            series.getStyle().getRenderer();
-                        renderer.setSeriesPaint(
-                            j,
-                            renderer.getSeriesFillPaint(j));
-                        renderer.setDrawOutlines(true);
-                    }
-                }
-            }
-        }
-    }
-
     /** Two Ranges that span a rectangular area. */
     public static class Area {
         protected Range xRange;
--- a/artifacts/src/main/java/org/dive4elements/river/exports/fixings/FixDeltaWtGenerator.java	Fri Jul 27 14:32:14 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/fixings/FixDeltaWtGenerator.java	Fri Jul 27 14:33:41 2018 +0200
@@ -175,7 +175,6 @@
         
         if (name.contains(FIX_SECTOR_AVERAGE_DWT)) {
             doSectorAverageOut(
-                    (D4EArtifact) artifactFacet.getArtifact(),
                     artifactFacet.getData(context),
                     artifactFacet.getFacetDescription(),
                     theme,
@@ -183,7 +182,6 @@
         }
         else if (name.equals(FIX_REFERENCE_EVENTS_DWT)) {
             doReferenceEventsOut(
-                    (D4EArtifact) artifactFacet.getArtifact(),
                     artifactFacet.getData(context),
                     artifactFacet.getFacetDescription(),
                     theme,
@@ -191,7 +189,6 @@
         }
         else if (name.equals(FIX_ANALYSIS_EVENTS_DWT)) {
             doAnalysisEventsOut(
-                    (D4EArtifact) artifactFacet.getArtifact(),
                     artifactFacet.getData(context),
                     artifactFacet.getFacetDescription(),
                     theme,
@@ -199,7 +196,6 @@
         }
         else if (name.equals(FIX_DEVIATION_DWT)) {
             doDeviationOut(
-                    (D4EArtifact) artifactFacet.getArtifact(),
                     artifactFacet.getData(context),
                     artifactFacet.getFacetDescription(),
                     theme,
@@ -207,17 +203,13 @@
         }
         else if (name.equals(FIX_ANALYSIS_PERIODS_DWT)) {
             doAnalysisPeriodsOut(
-                    (D4EArtifact) artifactFacet.getArtifact(),
                     artifactFacet.getData(context),
-                    artifactFacet.getFacetDescription(),
                     theme,
                     visible);
         }
         else if (name.equals(FIX_REFERENCE_PERIOD_DWT)) {
             doReferencePeriodsOut(
                     (D4EArtifact) artifactFacet.getArtifact(),
-                    artifactFacet.getData(context),
-                    artifactFacet.getFacetDescription(),
                     theme,
                     visible);
         }
@@ -235,8 +227,6 @@
 
     protected void doReferencePeriodsOut(
             D4EArtifact   artifact,
-            Object        data,
-            String        desc,
             ThemeDocument theme,
             boolean       visible)
     {
@@ -264,7 +254,6 @@
 
 
     protected void doSectorAverageOut(
-            D4EArtifact   artifact,
             Object        data,
             String        desc,
             ThemeDocument theme,
@@ -294,8 +283,7 @@
         addAxisDataset(tsc, 0, visible);
 
         if (visible && theme.parseShowLineLabel()) {
-            List<XYTextAnnotation> textAnnos =
-                new ArrayList<XYTextAnnotation>();
+            List<XYTextAnnotation> textAnnos = new ArrayList<>();
             XYTextAnnotation anno = new CollisionFreeXYTextAnnotation(
                     "\u0394 W(t) [cm] "
                     + (float)Math.round(qwd.qwd.getDeltaW() * 10000) / 10000,
@@ -312,7 +300,6 @@
 
 
     protected void doAnalysisEventsOut(
-            D4EArtifact artifact,
             Object       data,
             String       desc,
             ThemeDocument theme,
@@ -331,56 +318,36 @@
         ThemeDocument theme,
         boolean visible
     ) {
-        TimeSeriesCollection tsc = new TimeSeriesCollection();
-
-        TimeSeries   series = new StyledTimeSeries(desc, theme);
-        TimeSeries interpol = new StyledTimeSeries(desc + "interpol", theme);
+        final TimeSeriesCollection tsc = new TimeSeriesCollection();
 
         if (qwd == null) {
             log.debug("doQWDEventsOut: qwd == null");
             return;
         }
 
-        Map<Integer, int[]> annoIdxMap = new HashMap<Integer, int[]>();
+        final ThemeDocument themeInterpolated = FixWQCurveGenerator.configureThemeInterpolated(theme, qwd);
+        
+        final Map<Integer, int[]> annoIdxMap = new HashMap<>();
+ 
+        final long time = uniqueDate(qwd.getDate().getTime());
+        final RegularTimePeriod rtp = new FixedMillisecond(time);
+        final double value =  qwd.getDeltaW();
 
-        int idxInterpol = 0;
-        int idxRegular = 0;
-        long time = uniqueDate(qwd.getDate().getTime());
-        RegularTimePeriod rtp = new FixedMillisecond(time);
-        double value =  qwd.getDeltaW();
-        boolean interpolate = qwd.getInterpolated();
-        if (interpolate) {
-            if(interpol.addOrUpdate(rtp, value) == null) {
-                annoIdxMap.put(
-                        0,
-                        new int[]{1, idxInterpol});
-                idxInterpol++;
-            }
-        }
-        else {
-            if(series.addOrUpdate(rtp, value) == null) {
-                annoIdxMap.put(
-                        0,
-                        new int[]{0, idxRegular});
-                idxRegular++;
-            }
-        }
+        final TimeSeries series = new StyledTimeSeries(desc, themeInterpolated);
+        series.addOrUpdate(rtp, value);
 
         tsc.addSeries(series);
-        tsc.addSeries(interpol);
+        
         addAxisDataset(tsc, 0, visible);
-        addAttribute(desc + "interpol", "interpolate");
-        addAttribute(desc, "outline");
 
         doQWDTextAnnotations(annoIdxMap, tsc, qwd, theme, visible);
     }
 
-
     /**
      * @param annoIdxMap map of index in qwds to series/data item indices
      *                   in tsc.
      */
-    protected void doQWDTextAnnotations(Map<Integer, int[]> annoIdxMap,
+    private void doQWDTextAnnotations(Map<Integer, int[]> annoIdxMap,
             TimeSeriesCollection tsc, QWD qwd, ThemeDocument theme,
             boolean visible) {
         log.debug("doQWDTextAnnotation()");
@@ -395,25 +362,18 @@
 
         List<XYTextAnnotation> textAnnos = new ArrayList<>();
 
-        for (int[] idxs: annoIdxMap.values()) {
-
-            double x = tsc.getXValue(idxs[0], idxs[1]);
-
-            XYTextAnnotation anno = new CollisionFreeXYTextAnnotation(
-                    nf.format(qwd.getQ()) + " m\u00B3/s",
-                    x,
-                    qwd.getDeltaW());
-            textAnnos.add(anno);
-        }
+        final double x = tsc.getXValue(0, 0);
+        
+        String text = nf.format(qwd.getQ()) + " m\u00B3/s";
+        XYTextAnnotation anno = new CollisionFreeXYTextAnnotation( text, x, qwd.getDeltaW());
+        textAnnos.add(anno);
 
         RiverAnnotation flysAnno = new RiverAnnotation(null, null, null, theme);
         flysAnno.setTextAnnotations(textAnnos);
         addAnnotations(flysAnno);
     }
 
-
     protected void doReferenceEventsOut(
-            D4EArtifact  artifact,
             Object        data,
             String        desc,
             ThemeDocument theme,
@@ -427,7 +387,6 @@
 
 
     protected void doDeviationOut(
-            D4EArtifact   artifact,
             Object        data,
             String        desc,
             ThemeDocument theme,
@@ -451,9 +410,7 @@
 
 
     protected void doAnalysisPeriodsOut(
-            D4EArtifact artifact,
             Object        data,
-            String        desc,
             ThemeDocument theme,
             boolean       visible)
     {
@@ -497,5 +454,4 @@
             new StyledValueMarker(0, new ThemeDocument(request));
         valueMarker.add(marker);
     }
-}
-// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :
+}
\ No newline at end of file
--- a/artifacts/src/main/java/org/dive4elements/river/exports/fixings/FixWQCurveGenerator.java	Fri Jul 27 14:32:14 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/fixings/FixWQCurveGenerator.java	Fri Jul 27 14:33:41 2018 +0200
@@ -322,15 +322,11 @@
 
         double w = factor*(qwd.getW()-gaugeDatum);
 
-        // Force empty symbol.
-        if (qwd.getInterpolated()) {
-            doc = new ThemeDocument(doc); // prevent potential side effects.
-            doc.setValue(ThemeDocument.USE_FILL_PAINT, "true");
-        }
+        final ThemeDocument theme = configureThemeInterpolated(doc, qwd);
 
         XYSeries series = new StyledXYSeries(
             aaf.getFacetDescription(),
-            doc,
+            theme,
             qwd.getInterpolated()
                 ? ShapeUtils.INTERPOLATED_SHAPE
                 : ShapeUtils.MEASURED_SHAPE);
@@ -339,7 +335,7 @@
 
         addAxisSeries(series, atGauge ? YAXIS.WCm.idx : YAXIS.W.idx, visible);
 
-        if (visible && doc.parseShowPointLabel()) {
+        if (visible && theme.parseShowPointLabel()) {
 
             List<XYTextAnnotation> textAnnos =
                 new ArrayList<XYTextAnnotation>();
@@ -353,7 +349,7 @@
             textAnnos.add(anno);
 
             RiverAnnotation flysAnno =
-                new RiverAnnotation(null, null, null, doc);
+                new RiverAnnotation(null, null, null, theme);
             flysAnno.setTextAnnotations(textAnnos);
             addAnnotations(flysAnno);
         }
@@ -375,14 +371,11 @@
         }
 
         // Force empty symbol.
-        if (qwd.getInterpolated()) {
-            doc = new ThemeDocument(doc); // prevent potential side effects.
-            doc.setValue(ThemeDocument.USE_FILL_PAINT, "true");
-        }
+        final ThemeDocument theme = configureThemeInterpolated(doc, qwd);
 
         XYSeries series = new StyledXYSeries(
             aaf.getFacetDescription(),
-            false, true, doc,
+            false, true, theme,
             qwd.getInterpolated()
                 ? ShapeUtils.INTERPOLATED_SHAPE
                 : ShapeUtils.MEASURED_SHAPE);
@@ -396,7 +389,7 @@
 
         series.add(qwd.getQ(), w, false);
 
-        if (visible && doc.parseShowPointLabel()) {
+        if (visible && theme.parseShowPointLabel()) {
             DateFormat dateFormat = DateFormat.getDateInstance(
                 DateFormat.SHORT);
 
@@ -409,7 +402,7 @@
                 new ArrayList<XYTextAnnotation>();
             textAnnos.add(anno);
             RiverAnnotation flysAnno =
-                new RiverAnnotation(null, null, null, doc);
+                new RiverAnnotation(null, null, null, theme);
             flysAnno.setTextAnnotations(textAnnos);
             addAnnotations(flysAnno);
         }
@@ -418,6 +411,24 @@
     }
 
 
+    public static final ThemeDocument configureThemeInterpolated(ThemeDocument theme, QWI qwd) {
+        
+        // FIXME: it was like this before: points were always shown, flag had no effekt on this kind of theme, although the option is visible in the style editor
+        final boolean showPoints = true;
+//        final boolean showPoints = theme.parseShowPoints();
+        
+        final boolean doFill = showPoints && !qwd.getInterpolated(); 
+        final boolean doOutline = showPoints && qwd.getInterpolated(); 
+        
+        // prevent potential side effects by copying original theme
+        final ThemeDocument newTheme = new ThemeDocument(theme); 
+
+        newTheme.setValue(ThemeDocument.SHOW_POINTS, Boolean.toString(doFill));
+        newTheme.setValue(ThemeDocument.SHOW_POINTS_OUTLINE, Boolean.toString(doOutline));
+
+        return newTheme;
+    }
+
     private void addPointFromWQKms(WQKms wqkms,
         String        title,
         ThemeDocument theme,
--- a/artifacts/src/main/java/org/dive4elements/river/exports/process/FixWQProcessor.java	Fri Jul 27 14:32:14 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/process/FixWQProcessor.java	Fri Jul 27 14:33:41 2018 +0200
@@ -30,6 +30,7 @@
 import org.dive4elements.river.artifacts.resources.Resources;
 import org.dive4elements.river.exports.DiagramGenerator;
 import org.dive4elements.river.exports.StyledSeriesBuilder;
+import org.dive4elements.river.exports.fixings.FixWQCurveGenerator;
 import org.dive4elements.river.java2d.ShapeUtils;
 import org.dive4elements.river.jfree.CollisionFreeXYTextAnnotation;
 import org.dive4elements.river.jfree.JFreeUtil;
@@ -161,15 +162,12 @@
             return;
         }
 
-        // Force empty symbol.
-        if (qwd.getInterpolated()) {
-            theme = new ThemeDocument(theme); // prevent potential side effects
-            theme.setValue(ThemeDocument.USE_FILL_PAINT, "true");
-        }
+        // prevent potential side effects
+        final ThemeDocument themeInterpolated = FixWQCurveGenerator.configureThemeInterpolated(theme, qwd);
 
         XYSeries series = new StyledXYSeries(
             bundle.getFacetDescription(),
-            theme,
+            themeInterpolated,
             qwd.getInterpolated()
                 ? ShapeUtils.INTERPOLATED_SHAPE
                 : ShapeUtils.MEASURED_SHAPE);
@@ -178,7 +176,7 @@
 
         generator.addAxisSeries(series, axisName, visible);
 
-        if (visible && theme.parseShowPointLabel()) {
+        if (visible && themeInterpolated.parseShowPointLabel()) {
 
             List<XYTextAnnotation> textAnnos =
                 new ArrayList<XYTextAnnotation>();
@@ -192,7 +190,7 @@
             textAnnos.add(anno);
 
             RiverAnnotation flysAnno =
-                new RiverAnnotation(null, null, null, theme);
+                new RiverAnnotation(null, null, null, themeInterpolated);
             flysAnno.setTextAnnotations(textAnnos);
             generator.addAnnotations(flysAnno);
         }
@@ -213,22 +211,18 @@
             return;
         }
 
-        // Force empty symbol.
-        if (qwd.getInterpolated()) {
-            theme = new ThemeDocument(theme); // prevent potential side effects
-            theme.setValue(ThemeDocument.USE_FILL_PAINT, "true");
-        }
+        final ThemeDocument themeInterpolated = FixWQCurveGenerator.configureThemeInterpolated(theme, qwd);
 
         XYSeries series = new StyledXYSeries(
             bundle.getFacetDescription(),
-            false, true, theme,
+            false, true, themeInterpolated,
             qwd.getInterpolated()
                 ? ShapeUtils.INTERPOLATED_SHAPE
                 : ShapeUtils.MEASURED_SHAPE);
 
         series.add(qwd.getQ(), qwd.getW(), false);
 
-        if (visible && theme.parseShowPointLabel()) {
+        if (visible && themeInterpolated.parseShowPointLabel()) {
             DateFormat dateFormat = DateFormat.getDateInstance(
                 DateFormat.SHORT);
 
@@ -241,7 +235,7 @@
                 new ArrayList<XYTextAnnotation>();
             textAnnos.add(anno);
             RiverAnnotation flysAnno =
-                new RiverAnnotation(null, null, null, theme);
+                new RiverAnnotation(null, null, null, themeInterpolated);
             flysAnno.setTextAnnotations(textAnnos);
             generator.addAnnotations(flysAnno);
         }
--- a/artifacts/src/main/java/org/dive4elements/river/jfree/XYStyle.java	Fri Jul 27 14:32:14 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/jfree/XYStyle.java	Fri Jul 27 14:33:41 2018 +0200
@@ -8,67 +8,57 @@
 
 package org.dive4elements.river.jfree;
 
-import org.dive4elements.river.themes.ThemeDocument;
-
 import java.awt.BasicStroke;
 import java.awt.Color;
 import java.awt.Shape;
 import java.awt.geom.Ellipse2D;
 
-import org.apache.log4j.Logger;
+import org.dive4elements.river.themes.ThemeDocument;
 import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
 
-
 /**
  * Utility to apply theme-settings to a renderer.
+ *
  * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
  */
-public class XYStyle implements Style {
-
-    private static Logger log = Logger.getLogger(XYStyle.class);
-
-    protected ThemeDocument theme;
+public final class XYStyle implements Style {
 
-    protected XYLineAndShapeRenderer renderer;
+    private final ThemeDocument theme;
 
-    protected Shape shape;
+    private XYLineAndShapeRenderer renderer;
 
+    private final Shape shape;
 
-    public XYStyle(ThemeDocument theme) {
-        this.theme = theme;
+    public XYStyle(final ThemeDocument theme) {
+        this(theme, null);
     }
 
-    public XYStyle(ThemeDocument theme, Shape shape) {
+    public XYStyle(final ThemeDocument theme, final Shape shape) {
         this.theme = theme;
         this.shape = shape;
     }
 
-
     /**
      * Applies line color, size and type attributes to renderer, also
      * whether to draw lines and/or points.
      */
     @Override
-    public XYLineAndShapeRenderer applyTheme(
-        XYLineAndShapeRenderer r,
-        int idx
-    ) {
+    public XYLineAndShapeRenderer applyTheme(final XYLineAndShapeRenderer r, final int idx) {
         this.renderer = r;
-        if (shape != null) {
-            r.setShape(shape);
-        }
-        if (theme == null) {
-            // Hurray we already applied nothing :)
+
+        if (this.shape != null)
+            r.setShape(this.shape);
+
+        if (this.theme == null)
             return r;
-        }
-        applyUseFillPaint(r);
+
         applyLineColor(r, idx);
         applyLineSize(r, idx);
         applyLineType(r, idx);
         applyShowLine(r, idx);
-        applyShowPoints(r, idx);
-        applyPointSize(r, idx);
-        applyPointColor(r, idx);
+
+        applyPointStyles(r, idx);
+
         applyShowMinimum(r, idx);
         applyShowMaximum(r, idx);
 
@@ -83,177 +73,195 @@
         // TODO: Currently point label are annotations and
         // are not drawn this way
         /*
-        applyShowPointLabelBG(r, idx);
-        applyLinePointFont(r, idx);
-        applyLinePointColor(r, idx);
-        applyLinePointBGColor(r, idx);*/
+         * applyShowPointLabelBG(r, idx);
+         * applyLinePointFont(r, idx);
+         * applyLinePointColor(r, idx);
+         * applyLinePointBGColor(r, idx);
+         */
 
         return r;
     }
 
-    protected void applyUseFillPaint(XYLineAndShapeRenderer r) {
-        Boolean use = theme.parseUseFillPaint();
-        if (use != null) {
-            r.setUseFillPaint(use);
-        }
-    }
-
-
     /** Set line color to renderer. */
-    protected void applyLineColor(XYLineAndShapeRenderer r, int idx) {
-        Color c = theme.parseLineColorField();
+    private void applyLineColor(final XYLineAndShapeRenderer r, final int idx) {
+        final Color c = this.theme.parseLineColorField();
         if (c != null) {
             r.setSeriesPaint(idx, c);
         }
     }
 
-
     /** Tells the renderer whether or not to add a label to a line. */
-    protected void applyShowLineLabel(XYLineAndShapeRenderer r, int idx) {
-        if (!(r instanceof EnhancedLineAndShapeRenderer)) {
-            return;
-        }
-        boolean showLabelLine = theme.parseShowLineLabel();
-        boolean anyLabel = showLabelLine || theme.parseShowWidth() ||
-                           theme.parseShowLevel() ||
-                           theme.parseShowMiddleHeight();
-        ((EnhancedLineAndShapeRenderer)r).setShowLineLabel(anyLabel, idx);
-    }
-
-
-    /** Tells the renderer whether or not to fill the bg of a lines label. */
-    protected void applyShowLineLabelBG(XYLineAndShapeRenderer r, int idx) {
-        if (!(r instanceof EnhancedLineAndShapeRenderer)) {
-            return;
-        }
-        boolean showLabelLine = theme.parseLabelShowBackground();
-        ((EnhancedLineAndShapeRenderer)r).setShowLineLabelBG(
-            idx, showLabelLine);
-    }
-
-    /** Tell the renderer which font (and -size and -style) to use for
-     * linelabels. */
-    protected void applyLineLabelFont(XYLineAndShapeRenderer r, int idx) {
+    private void applyShowLineLabel(final XYLineAndShapeRenderer r, final int idx) {
         if (!(r instanceof EnhancedLineAndShapeRenderer)) {
             return;
         }
-        ((EnhancedLineAndShapeRenderer)r).setLineLabelFont(
-                theme.parseTextFont(), idx);
+        final boolean showLabelLine = this.theme.parseShowLineLabel();
+        final boolean anyLabel = showLabelLine || this.theme.parseShowWidth() || this.theme.parseShowLevel() || this.theme.parseShowMiddleHeight();
+        ((EnhancedLineAndShapeRenderer) r).setShowLineLabel(anyLabel, idx);
     }
 
-    /** Tell the renderer which color to use for
-     * linelabels. */
-    protected void applyLineLabelColor(XYLineAndShapeRenderer r, int idx) {
+    /** Tells the renderer whether or not to fill the bg of a lines label. */
+    private void applyShowLineLabelBG(final XYLineAndShapeRenderer r, final int idx) {
         if (!(r instanceof EnhancedLineAndShapeRenderer)) {
             return;
         }
-        ((EnhancedLineAndShapeRenderer)r).setLineLabelTextColor(
-                idx, theme.parseTextColor());
+        final boolean showLabelLine = this.theme.parseLabelShowBackground();
+        ((EnhancedLineAndShapeRenderer) r).setShowLineLabelBG(idx, showLabelLine);
     }
 
-    /** Tell the renderer which color to use for bg of
-     * linelabels. */
-    protected void applyLineLabelBGColor(XYLineAndShapeRenderer r, int idx) {
+    /**
+     * Tell the renderer which font (and -size and -style) to use for
+     * linelabels.
+     */
+    private void applyLineLabelFont(final XYLineAndShapeRenderer r, final int idx) {
         if (!(r instanceof EnhancedLineAndShapeRenderer)) {
             return;
         }
-        ((EnhancedLineAndShapeRenderer)r).setLineLabelBGColor(idx,
-            theme.parseTextBackground());
+        ((EnhancedLineAndShapeRenderer) r).setLineLabelFont(this.theme.parseTextFont(), idx);
+    }
+
+    /**
+     * Tell the renderer which color to use for
+     * linelabels.
+     */
+    private void applyLineLabelColor(final XYLineAndShapeRenderer r, final int idx) {
+        if (!(r instanceof EnhancedLineAndShapeRenderer)) {
+            return;
+        }
+        ((EnhancedLineAndShapeRenderer) r).setLineLabelTextColor(idx, this.theme.parseTextColor());
+    }
+
+    /**
+     * Tell the renderer which color to use for bg of
+     * linelabels.
+     */
+    private void applyLineLabelBGColor(final XYLineAndShapeRenderer r, final int idx) {
+        if (!(r instanceof EnhancedLineAndShapeRenderer)) {
+            return;
+        }
+        ((EnhancedLineAndShapeRenderer) r).setLineLabelBGColor(idx, this.theme.parseTextBackground());
     }
 
     /** Set stroke of series. */
-    protected void applyLineSize(XYLineAndShapeRenderer r, int idx) {
-        int size = theme.parseLineWidth();
-        r.setSeriesStroke(
-            idx,
-            new BasicStroke(size));
+    private void applyLineSize(final XYLineAndShapeRenderer r, final int idx) {
+        final int size = this.theme.parseLineWidth();
+        r.setSeriesStroke(idx, new BasicStroke(size));
     }
 
-
     /** Set stroke strength of series. */
-    protected void applyLineType(XYLineAndShapeRenderer r, int idx) {
-        int size = theme.parseLineWidth();
-        float[] dashes = theme.parseLineStyle();
+    private void applyLineType(final XYLineAndShapeRenderer r, final int idx) {
+        final int size = this.theme.parseLineWidth();
+        final float[] dashes = this.theme.parseLineStyle();
 
         // Do not apply the dashed style.
         if (dashes.length <= 1) {
             return;
         }
 
-        r.setSeriesStroke(
-            idx,
-            new BasicStroke(size,
-                            BasicStroke.CAP_BUTT,
-                            BasicStroke.JOIN_ROUND,
-                            1.0f,
-                            dashes,
-                            0.0f));
+        r.setSeriesStroke(idx, new BasicStroke(size, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND, 1.0f, dashes, 0.0f));
     }
 
+    private void applyPointStyles(final XYLineAndShapeRenderer r, final int idx) {
+        applyPointSize(r, idx);
 
-    protected void applyPointSize(XYLineAndShapeRenderer r, int idx) {
-        int size = theme.parsePointWidth();
-        int dim  = 2 * size;
+        final Color c = this.theme.parsePointColor();
+        final boolean show = this.theme.parseShowPoints();
+        final boolean showOutline = this.theme.parseShowPointsOutline();
+
+        if (c != null)
+            r.setSeriesFillPaint(idx, c);
+        r.setUseFillPaint(c!= null);
+        
+        r.setSeriesShapesFilled(idx, show);
+
+        r.setSeriesOutlinePaint(idx, c);
+        r.setDrawOutlines(showOutline);
+        r.setUseOutlinePaint(c != null);
+
+        r.setSeriesShapesVisible(idx, show || showOutline);
+
+        // applyShowPoints(r, idx);
+        // applyPointColor(r, idx);
+
+        // applyUseFillPaint(r);
+    }
+
+    private void applyPointSize(final XYLineAndShapeRenderer r, final int idx) {
+        final int size = this.theme.parsePointWidth();
+        final int dim = 2 * size;
 
         r.setSeriesShape(idx, new Ellipse2D.Double(-size, -size, dim, dim));
     }
 
-
-    protected void applyPointColor(XYLineAndShapeRenderer r, int idx) {
-        Color c = theme.parsePointColor();
+    private void applyPointColor(final XYLineAndShapeRenderer r, final int idx) {
+        final Color c = this.theme.parsePointColor();
 
-        if (c != null) {
+        boolean alt = false;
+        if (alt) {
+
+            if (c != null) {
+                r.setSeriesFillPaint(idx, c);
+
+                r.setUseFillPaint(true);
+                r.setDrawOutlines(false);
+            }
+        } else {
+            // if (c != null) {
             r.setSeriesFillPaint(idx, c);
-            r.setUseFillPaint(true);
-            r.setDrawOutlines(false);
+            r.setUseFillPaint(c != null);
+
+            r.setSeriesOutlinePaint(idx, c);
+            r.setDrawOutlines(c != null);
+            // }
         }
     }
 
-
     /**
      * Sets form and visibility of points.
      */
-    protected void applyShowPoints(XYLineAndShapeRenderer r, int idx) {
-        boolean show = theme.parseShowPoints();
+    private void applyShowPoints(final XYLineAndShapeRenderer r, final int idx) {
+        final boolean show = this.theme.parseShowPoints();
 
         r.setSeriesShapesVisible(idx, show);
         r.setDrawOutlines(true);
     }
 
+    // private void applyUseFillPaint(final XYLineAndShapeRenderer r) {
+    // final Boolean use = this.theme.parseUseFillPaint();
+    // if (use != null) {
+    // r.setUseFillPaint(use);
+    // }
+    // }
 
-    protected void applyShowLine(XYLineAndShapeRenderer r, int idx) {
-        boolean show = theme.parseShowLine();
+    private void applyShowLine(final XYLineAndShapeRenderer r, final int idx) {
+        final boolean show = this.theme.parseShowLine();
         r.setSeriesLinesVisible(idx, show);
     }
 
-
-    protected void applyShowMinimum(XYLineAndShapeRenderer r, int idx) {
+    private void applyShowMinimum(final XYLineAndShapeRenderer r, final int idx) {
         if (!(r instanceof EnhancedLineAndShapeRenderer)) {
             return;
         }
 
-        boolean visible = theme.parseShowMinimum();
+        final boolean visible = this.theme.parseShowMinimum();
 
-        EnhancedLineAndShapeRenderer er = (EnhancedLineAndShapeRenderer) r;
+        final EnhancedLineAndShapeRenderer er = (EnhancedLineAndShapeRenderer) r;
         er.setIsMinimumShapeVisisble(idx, visible);
     }
 
-
-    protected void applyShowMaximum(XYLineAndShapeRenderer r, int idx) {
+    private void applyShowMaximum(final XYLineAndShapeRenderer r, final int idx) {
         if (!(r instanceof EnhancedLineAndShapeRenderer)) {
             return;
         }
 
-        boolean visible = theme.parseShowMaximum();
+        final boolean visible = this.theme.parseShowMaximum();
 
-        EnhancedLineAndShapeRenderer er = (EnhancedLineAndShapeRenderer) r;
+        final EnhancedLineAndShapeRenderer er = (EnhancedLineAndShapeRenderer) r;
         er.setIsMaximumShapeVisible(idx, visible);
     }
 
-
     @Override
     public XYLineAndShapeRenderer getRenderer() {
         return this.renderer;
     }
-}
-// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
+}
\ No newline at end of file
--- a/artifacts/src/main/java/org/dive4elements/river/themes/ThemeDocument.java	Fri Jul 27 14:32:14 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/themes/ThemeDocument.java	Fri Jul 27 14:33:41 2018 +0200
@@ -56,6 +56,8 @@
 
     public final static String SHOW_POINTS = "showpoints";
 
+    public final static String SHOW_POINTS_OUTLINE = "showpointsoutline";
+
     public final static String SHOW_LINE = "showlines";
 
     public final static String SHOW_VERTICAL_LINE = "showverticalline";
@@ -122,8 +124,6 @@
 
     public final static String SHOWEXTRAMARK = "showextramark";
 
-    public final static String USE_FILL_PAINT = "usefillpaint";
-
     /* boolean parameter if the range of this theme should be considered when auto-zooming. Only works for area-series at the moment */
     private static final String CALCULATE_RANGE = "calculateRange";
 
@@ -364,6 +364,11 @@
         return parseBoolean(show, false);
     }
 
+    public boolean parseShowPointsOutline() {
+        String show = getValue(SHOW_POINTS_OUTLINE);
+        return parseBoolean(show, false);
+    }
+
     public boolean parseShowLine() {
         String show = getValue(SHOW_LINE);
         return parseBoolean(show, false);
@@ -484,13 +489,6 @@
         return parseBoolean(show, false);
     }
 
-    public Boolean parseUseFillPaint() {
-        String use = getValue(USE_FILL_PAINT);
-        return use != null
-            ? parseBoolean(use, false)
-            : null;
-    }
-
     public int parseFontSize() {
         String size = getValue(TEXT_SIZE);
         if (size == null) {

http://dive4elements.wald.intevation.org