org.pentaho.plugin.jfreereport.reportcharts.PieChartExpression.java Source code

Java tutorial

Introduction

Here is the source code for org.pentaho.plugin.jfreereport.reportcharts.PieChartExpression.java

Source

/*!
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software
* Foundation.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
* or from the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* Copyright (c) 2002-2017 Hitachi Vantara..  All rights reserved.
*/

package org.pentaho.plugin.jfreereport.reportcharts;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.labels.StandardPieSectionLabelGenerator;
import org.jfree.chart.plot.PiePlot;
import org.jfree.chart.plot.Plot;
import org.jfree.data.general.Dataset;
import org.jfree.data.general.PieDataset;
import org.jfree.util.Rotation;
import org.pentaho.reporting.engine.classic.core.function.ExpressionRuntime;
import org.pentaho.reporting.libraries.base.util.StringUtils;
import org.pentaho.reporting.libraries.formatting.FastDecimalFormat;

import java.awt.*;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.Locale;

public class PieChartExpression extends AbstractChartExpression {
    private static final int EXPLODE_VALUE = 0;
    private static final int EXPLODE_MIN = 1;
    private static final int EXPLODE_MAX = 2;

    private static final long serialVersionUID = 5755617219149952355L;

    private boolean rotationClockwise;
    private String explodeSegment;
    private Double explodePct;
    private boolean ignoreNulls;
    private boolean ignoreZeros;
    private String pieLabelFormat;
    private boolean circular;
    private String pieLegendLabelFormat;

    private Color shadowPaint;
    private Double shadowXOffset;
    private Double shadowYOffset;

    public PieChartExpression() {
        rotationClockwise = true;
        pieLegendLabelFormat = StandardPieSectionLabelGenerator.DEFAULT_SECTION_LABEL_FORMAT;
        pieLabelFormat = "{2}";
        ignoreZeros = true;
        ignoreNulls = true;
        circular = true;
        setItemsLabelVisible(Boolean.TRUE);
    }

    public Color getShadowPaint() {
        return shadowPaint;
    }

    public void setShadowPaint(final Color shadowPaint) {
        this.shadowPaint = shadowPaint;
    }

    public Double getShadowXOffset() {
        return shadowXOffset;
    }

    public void setShadowXOffset(final Double shadowXOffset) {
        this.shadowXOffset = shadowXOffset;
    }

    public Double getShadowYOffset() {
        return shadowYOffset;
    }

    public void setShadowYOffset(final Double shadowYOffset) {
        this.shadowYOffset = shadowYOffset;
    }

    public boolean isRotationClockwise() {
        return rotationClockwise;
    }

    public void setRotationClockwise(final boolean value) {
        rotationClockwise = value;
    }

    public boolean isIgnoreNulls() {
        return ignoreNulls;
    }

    public void setIgnoreNulls(final boolean value) {
        ignoreNulls = value;
    }

    public boolean isIgnoreZeros() {
        return ignoreZeros;
    }

    public void setIgnoreZeros(final boolean value) {
        ignoreZeros = value;
    }

    public String getExplodeSegment() {
        return explodeSegment;
    }

    public void setExplodeSegment(final String value) {
        explodeSegment = value;
    }

    public Double getExplodePct() {
        return explodePct;
    }

    public void setExplodePct(final Double value) {
        explodePct = value;
    }

    public String getPieLabelFormat() {
        return pieLabelFormat;
    }

    public void setPieLabelFormat(final String value) {
        pieLabelFormat = value;
    }

    public String getPieLegendLabelFormat() {
        return pieLegendLabelFormat;
    }

    public void setPieLegendLabelFormat(final String value) {
        pieLegendLabelFormat = value;
    }

    public boolean getIsCircular() {
        return circular;
    }

    public void setCircular(final boolean value) {
        circular = value;
    }

    protected JFreeChart computeChart(final Dataset dataset) {

        PieDataset pieDataset = null;
        if (dataset instanceof PieDataset) {
            pieDataset = (PieDataset) dataset;
        }

        if (isThreeD()) {
            return ChartFactory.createPieChart3D(computeTitle(), pieDataset, isShowLegend(), false, false);
        } else {
            return ChartFactory.createPieChart(computeTitle(), pieDataset, isShowLegend(), false, false);
        }
    }

    protected void configureExplode(final PiePlot pp) {
        final PieDataset pieDS = pp.getDataset();

        final int explodeType = computeExplodeType();
        if (explodeType == EXPLODE_VALUE) {
            try {
                final int actualSegment = Integer.parseInt(explodeSegment);
                if (actualSegment >= 0) {
                    pp.setExplodePercent(pieDS.getKey(actualSegment), explodePct.doubleValue());
                }
            } catch (Exception ignored) {
            }
            return;
        }

        // Calculate min and max...
        if (pieDS != null) {
            final int itemCount = pieDS.getItemCount();
            Number maxNum = new Double(Integer.MIN_VALUE);
            Number minNum = new Double(Integer.MAX_VALUE);
            int maxSegment = -1;
            int minSegment = -1;
            for (int i = 0; i < itemCount; i++) {
                final Number nbr = pieDS.getValue(i);
                if (nbr.doubleValue() > maxNum.doubleValue()) {
                    maxNum = nbr;
                    maxSegment = i;
                }
                if (nbr.doubleValue() < minNum.doubleValue()) {
                    minNum = nbr;
                    minSegment = i;
                }
            }

            if (explodeType == EXPLODE_MIN) { //$NON-NLS-1$
                if (minSegment >= 0) {
                    pp.setExplodePercent(pieDS.getKey(minSegment), explodePct.doubleValue());
                }
            } else {
                if (maxSegment >= 0) {
                    pp.setExplodePercent(pieDS.getKey(maxSegment), explodePct.doubleValue());
                }
            }
        }

    }

    private int computeExplodeType() {
        if ("minValue".equals(explodeSegment)) {
            return EXPLODE_MIN;
        } else if ("maxValue".equals(explodeSegment)) {
            return EXPLODE_MAX;
        }
        return EXPLODE_VALUE;
    }

    protected void configureChart(final JFreeChart chart) {
        super.configureChart(chart);

        final Plot plot = chart.getPlot();
        final PiePlot pp = (PiePlot) plot;
        final PieDataset pieDS = pp.getDataset();
        pp.setDirection(rotationClockwise ? Rotation.CLOCKWISE : Rotation.ANTICLOCKWISE);
        if ((explodeSegment != null) && (explodePct != null)) {
            configureExplode(pp);
        }
        if (StringUtils.isEmpty(getTooltipFormula()) == false) {
            pp.setToolTipGenerator(new FormulaPieTooltipGenerator(getRuntime(), getTooltipFormula()));
        }
        if (StringUtils.isEmpty(getUrlFormula()) == false) {
            pp.setURLGenerator(new FormulaPieURLGenerator(getRuntime(), getUrlFormula()));
        }

        pp.setIgnoreNullValues(ignoreNulls);
        pp.setIgnoreZeroValues(ignoreZeros);
        if (Boolean.FALSE.equals(getItemsLabelVisible())) {
            pp.setLabelGenerator(null);
        } else {
            final ExpressionRuntime runtime = getRuntime();
            final Locale locale = runtime.getResourceBundleFactory().getLocale();

            final FastDecimalFormat fastPercent = new FastDecimalFormat(FastDecimalFormat.TYPE_PERCENT, locale);
            final FastDecimalFormat fastInteger = new FastDecimalFormat(FastDecimalFormat.TYPE_INTEGER, locale);

            final DecimalFormat numFormat = new DecimalFormat(fastInteger.getPattern(),
                    new DecimalFormatSymbols(locale));
            numFormat.setRoundingMode(RoundingMode.HALF_UP);

            final DecimalFormat percentFormat = new DecimalFormat(fastPercent.getPattern(),
                    new DecimalFormatSymbols(locale));
            percentFormat.setRoundingMode(RoundingMode.HALF_UP);

            final StandardPieSectionLabelGenerator labelGen = new StandardPieSectionLabelGenerator(pieLabelFormat,
                    numFormat, percentFormat);
            pp.setLabelGenerator(labelGen);

            final StandardPieSectionLabelGenerator legendGen = new StandardPieSectionLabelGenerator(
                    pieLegendLabelFormat, numFormat, percentFormat);
            pp.setLegendLabelGenerator(legendGen);
        }

        if (StringUtils.isEmpty(getLabelFont()) == false) {
            pp.setLabelFont(Font.decode(getLabelFont()));
        }

        if (pieDS != null) {
            final String[] colors = getSeriesColor();
            for (int i = 0; i < colors.length; i++) {
                if (i < pieDS.getItemCount()) {
                    pp.setSectionPaint(pieDS.getKey(i), parseColorFromString(colors[i]));
                } else {
                    break;
                }
            }
        }

        if (shadowPaint != null) {
            pp.setShadowPaint(shadowPaint);
        }
        if (shadowXOffset != null) {
            pp.setShadowXOffset(shadowXOffset.doubleValue());
        }
        if (shadowYOffset != null) {
            pp.setShadowYOffset(shadowYOffset.doubleValue());
        }
        pp.setCircular(circular);

        if (isShowBorder() == false || isChartSectionOutline() == false) {
            chart.setBorderVisible(false);
            chart.getPlot().setOutlineVisible(false);
        }

    }

}