view artifacts/src/main/java/org/dive4elements/river/jfree/XYStyle.java @ 9555:ef5754ba5573

Implemented legend aggregation based on type of themes. Added theme-editor style configuration for aggregated legend entries. Only configured themes get aggregated.
author gernotbelger
date Tue, 23 Oct 2018 16:26:48 +0200
parents ddcd52d239cd
children
line wrap: on
line source
/* 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 java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Shape;
import java.awt.geom.Ellipse2D;

import org.dive4elements.river.themes.ThemeDocument;
import org.jfree.chart.LegendItem;
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 final class XYStyle implements Style {

    private final ThemeDocument theme;

    private XYLineAndShapeRenderer renderer;

    private final Shape shape;

    public XYStyle(final ThemeDocument theme) {
        this(theme, null);
    }

    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(final XYLineAndShapeRenderer r, final int idx) {
        this.renderer = r;

        if (this.shape != null)
            r.setShape(this.shape);

        if (this.theme == null)
            return r;

        applyLineColor(r, idx);
        applyLineSize(r, idx);
        applyLineType(r, idx);
        applyShowLine(r, idx);

        applyPointStyles(r, idx);

        applyShowMinimum(r, idx);
        applyShowMaximum(r, idx);

        // Line label styles
        applyShowLineLabel(r, idx);
        applyShowLineLabelBG(r, idx);
        applyLineLabelFont(r, idx);
        applyLineLabelColor(r, idx);
        applyLineLabelBGColor(r, idx);

        // Point label styles
        // TODO: Currently point label are annotations and
        // are not drawn this way
        /*
         * applyShowPointLabelBG(r, idx);
         * applyLinePointFont(r, idx);
         * applyLinePointColor(r, idx);
         * applyLinePointBGColor(r, idx);
         */

        return r;
    }

    /** Set line color to renderer. */
    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. */
    private void applyShowLineLabel(final XYLineAndShapeRenderer r, final int idx) {
        if (!(r instanceof EnhancedLineAndShapeRenderer)) {
            return;
        }
        final boolean showLabelLine = this.theme.parseShowLineLabel();
        final boolean anyLabel = showLabelLine || this.theme.parseShowWidth() || this.theme.parseShowLevel() || this.theme.parseShowMiddleHeight();
        ((EnhancedLineAndShapeRenderer) r).setShowLineLabel(anyLabel, 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;
        }
        final boolean showLabelLine = this.theme.parseLabelShowBackground();
        ((EnhancedLineAndShapeRenderer) r).setShowLineLabelBG(idx, showLabelLine);
    }

    /**
     * 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).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. */
    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. */
    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));
    }

    private void applyPointStyles(final XYLineAndShapeRenderer r, final int idx) {
        applyPointSize(r, idx);

        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);
    }

    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));
    }

    private void applyShowLine(final XYLineAndShapeRenderer r, final int idx) {
        final boolean show = this.theme.parseShowLine();
        r.setSeriesLinesVisible(idx, show);
    }

    private void applyShowMinimum(final XYLineAndShapeRenderer r, final int idx) {
        if (!(r instanceof EnhancedLineAndShapeRenderer)) {
            return;
        }

        final boolean visible = this.theme.parseShowMinimum();

        final EnhancedLineAndShapeRenderer er = (EnhancedLineAndShapeRenderer) r;
        er.setIsMinimumShapeVisisble(idx, visible);
    }

    private void applyShowMaximum(final XYLineAndShapeRenderer r, final int idx) {
        if (!(r instanceof EnhancedLineAndShapeRenderer)) {
            return;
        }

        final boolean visible = this.theme.parseShowMaximum();

        final EnhancedLineAndShapeRenderer er = (EnhancedLineAndShapeRenderer) r;
        er.setIsMaximumShapeVisible(idx, visible);
    }

    @Override
    public XYLineAndShapeRenderer getRenderer() {
        return this.renderer;
    }

    @Override
    public void applyAggregatedLegendTheme(final LegendItem item, final ThemeDocument legendTheme) {

        if (this.theme == null)
            return;

        if (this.shape != null)
            item.setShape(this.shape);

        final Color lineColor = legendTheme.parseLineColorField();
        if (lineColor != null)
            item.setLinePaint(lineColor);

        if (legendTheme.getValue(ThemeDocument.SHOW_LINE) != null)
            item.setLineVisible(legendTheme.parseShowLine());

        /* remark cant set line stroke on legend item */
        // applyLineSize(r, idx);
        // applyLineType(r, idx);

        /*
         * REMARK: we only change the colors, as visibility and such are interdependend and should be the same as the original
         * items
         */
        final Color c = legendTheme.parsePointColor();
        if (c != null) {
            item.setFillPaint(c);
            item.setOutlinePaint(c);
        }
    }
}

http://dive4elements.wald.intevation.org