JFreechart中的多个堆积面积数据集

时间:2018-11-28 22:57:08

标签: jfreechart

我正在使用JFreechart,并且试图获得与XYDifferenceRenderer类似的内容,但要获取CategoryPlot。我遇到的问题是能够在同一图上绘制多个StackedAreaRenderer。以下有一个StackedArea看起来像是浮动的。这就是我想要的。

package test;

import java.awt.Color;
import java.awt.Dimension;

import java.util.List;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.AxisLocation;
import org.jfree.chart.axis.CategoryLabelPositions;
import org.jfree.chart.labels.StandardCategoryToolTipGenerator;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.AreaRendererEndType;
import org.jfree.chart.renderer.category.StackedAreaRenderer;
import org.jfree.chart.ui.ApplicationFrame;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;

import org.jfree.ui.RefineryUtilities;

/**
 *
 * @author buxk
 */
public class DifferenceWithCategories extends ApplicationFrame{


    public DifferenceWithCategories(String title){
        super(title);

        final JFreeChart chart = createChart();

        final ChartPanel chartPanel = new ChartPanel(chart);
        chartPanel.setPreferredSize(new Dimension(500,270));
        setContentPane(chartPanel);

    }

    /**
     * Returns a sample dataset.
     *
     * @return The dataset.
     */
    private CategoryDataset createDataset1() {

        // row keys...
        String series1 = "First";

        // column keys...
        String category1 = "Category 1";
        String category2 = "Category 2";
        String category3 = "Category 3";
        String category4 = "Category 4";
        String category5 = "Category 5";

        // create the dataset...
        DefaultCategoryDataset dataset = new DefaultCategoryDataset();

        dataset.addValue(4.0, series1, category1);
        dataset.addValue(4.0, series1, category2);
        dataset.addValue(3.0, series1, category3);
        dataset.addValue(5.0, series1, category4);
        dataset.addValue(5.0, series1, category5);

        return dataset;
    }


    /**
     * Returns a sample dataset.
     *
     * @return The dataset.
     */
    private CategoryDataset createDataset2() {

        // row keys...
        String series2 = "Second";

        // column keys...
        String category1 = "Category 1";
        String category2 = "Category 2";
        String category3 = "Category 3";
        String category4 = "Category 4";
        String category5 = "Category 5";

        // create the dataset...
        DefaultCategoryDataset dataset = new DefaultCategoryDataset();

        dataset.addValue(5.0, series2, category1);
        dataset.addValue(7.0, series2, category2);
        dataset.addValue(6.0, series2, category3);
        dataset.addValue(8.0, series2, category4);
        dataset.addValue(6.0, series2, category5);

        return dataset;
    }


    /**
     * Returns a sample dataset.
     *
     * @return The dataset.
     */
    private CategoryDataset createDataset3() {

        // row keys...
        String series3 = "Third";

        // column keys...
        String category1 = "Category 1";
        String category2 = "Category 2";
        String category3 = "Category 3";
        String category4 = "Category 4";
        String category5 = "Category 5";

        // create the dataset...
        DefaultCategoryDataset dataset = new DefaultCategoryDataset();

        dataset.addValue(1.0, series3, category1);
        dataset.addValue(3.0, series3, category2);
        dataset.addValue(2.0, series3, category3);
        dataset.addValue(3.0, series3, category4);
        dataset.addValue(4.0, series3, category5);

        return dataset;
    }

    private CategoryDataset merge4StackedDataset(CategoryDataset d1, CategoryDataset d2){

        DefaultCategoryDataset dataset = new DefaultCategoryDataset();
        List<Comparable> columnKeys = d1.getColumnKeys();
        List<Comparable> d1RowKeys = d1.getRowKeys();
        List<Comparable> d2RowKeys = d2.getRowKeys();
        double minValue, maxValue;
        for (Comparable columnKey : columnKeys) {
            for (Comparable rowKey : d1RowKeys) {
                for (Comparable d2RowKey : d2RowKeys) {
                    minValue = Math.min(d1.getValue(rowKey, columnKey).doubleValue(),d2.getValue(d2RowKey, columnKey).doubleValue());
                    maxValue = Math.max(d1.getValue(rowKey, columnKey).doubleValue(),d2.getValue(d2RowKey, columnKey).doubleValue());
                    dataset.addValue(minValue, rowKey, columnKey);
                    dataset.addValue(maxValue - minValue, d2RowKey, columnKey);
//                    dataset.addValue(d2.getValue(d2RowKey, columnKey).doubleValue(), d2RowKey, columnKey);
                }
            }

        }

        return dataset;
    }

    private JFreeChart createChart() {

        CategoryDataset dataset1 = merge4StackedDataset(createDataset1(), createDataset2());
        CategoryDataset dataset2 = merge4StackedDataset(createDataset1(), createDataset3());

        //create chart with empty dataset
        final JFreeChart chart = ChartFactory.createAreaChart(
                "Testing",
                "Categories",
                "Values",
                dataset1,
                PlotOrientation.VERTICAL,
                true,  // legend
                true,  // tool tips
                false  // URLs
        );

        //make the chart have a white background
        chart.setBackgroundPaint(Color.white);

        //get the chart's plot
        final CategoryPlot plot = chart.getCategoryPlot();

        //color the plot
        plot.setBackgroundPaint(Color.lightGray);
        plot.setDomainGridlinePaint(Color.white);
        plot.setRangeGridlinePaint(Color.white);

        //make a stacked area renderer for the first dataset
        final StackedAreaRenderer renderer1 = new StackedAreaRenderer();
        renderer1.setEndType(AreaRendererEndType.LEVEL);
        renderer1.setDefaultToolTipGenerator(new StandardCategoryToolTipGenerator());

        //turn off the first data set that lets the stack float
        renderer1.setSeriesPaint(0, new Color(Color.blue.getRed(), Color.blue.getGreen(), Color.blue.getBlue(), 0));
        renderer1.setSeriesVisibleInLegend(0, false);

        plot.setRenderer(0, renderer1);
        plot.setRenderer(1, renderer1);


//        plot.setDataset(2, dataset2);
//        final StackedAreaRenderer renderer2 = new StackedAreaRenderer();
//        renderer2.setEndType(AreaRendererEndType.LEVEL);
//        renderer2.setDefaultToolTipGenerator(new StandardCategoryToolTipGenerator());
//        renderer2.setSeriesPaint(2, new Color(Color.green.getRed(), Color.green.getGreen(), Color.green.getBlue(), 0));
//        renderer2.setSeriesVisibleInLegend(2, false);
//        renderer1.setSeriesPaint(2, new Color(Color.green.getRed(), Color.green.getGreen(), Color.green.getBlue(), 0));
//        renderer1.setSeriesPaint(3, new Color(Color.black.getRed(), Color.black.getGreen(), Color.black.getBlue(), 255));
//        renderer1.setSeriesVisibleInLegend(2, false);
//        plot.setRenderer(2, renderer2);
//        plot.setRenderer(3, renderer2);
//        plot.setRenderer(2, renderer1);
//        plot.setRenderer(3, renderer1);

        plot.setDomainAxisLocation(AxisLocation.BOTTOM_OR_RIGHT);
        plot.getDomainAxis().setCategoryLabelPositions(CategoryLabelPositions.DOWN_45);
        plot.setDomainCrosshairVisible(true);
        plot.setRangeCrosshairVisible(true);

        return chart;
    }

    public static void main(String[] args) {
        final DifferenceWithCategories demo = new DifferenceWithCategories("Diference With Categories");
        demo.pack();
        RefineryUtilities.centerFrameOnScreen(demo);
        demo.setVisible(true);

    }
}

版本1
如果我取消注释dataset2renderer2的代码部分,那么我会得到一些奇怪的结果,其中有三个区域,图例中列出了三项。

版本2
如果我取消对dataset2renderer1的代码段的注释,则我得到的内容接近于我想要的内容,但是,两者的区域均为红色,且两者的图例均为Second dataset2不存在。

有人知道我如何获得版本1的颜色,但是我能得到版本2的区域集吗?

1 个答案:

答案 0 :(得分:0)

我发现了如何获得想要的东西。问题出在渲染器需要知道相对于自身的数据集索引与相对于图的数据集索引之间。
因此,在将渲染器添加到绘图时,使用相对于自身的数据集索引使用第二个渲染器修复了该问题。

具有预期输出的代码:

import java.awt.Dimension;

import java.util.List;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.AxisLocation;
import org.jfree.chart.axis.CategoryLabelPositions;
import org.jfree.chart.labels.StandardCategoryToolTipGenerator;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.AreaRendererEndType;
import org.jfree.chart.renderer.category.StackedAreaRenderer;
import org.jfree.chart.ui.ApplicationFrame;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;

import org.jfree.ui.RefineryUtilities;

/**
 *
 * @author buxk
 */
public class DifferenceWithCategories extends ApplicationFrame{


    public DifferenceWithCategories(String title){
        super(title);

        final JFreeChart chart = createChart();

        final ChartPanel chartPanel = new ChartPanel(chart);
        chartPanel.setPreferredSize(new Dimension(500,270));
        setContentPane(chartPanel);

    }

    /**
     * Returns a sample dataset.
     *
     * @return The dataset.
     */
    private CategoryDataset createDataset1() {

        // row keys...
        String series1 = "First";

        // column keys...
        String category1 = "Category 1";
        String category2 = "Category 2";
        String category3 = "Category 3";
        String category4 = "Category 4";
        String category5 = "Category 5";

        // create the dataset...
        DefaultCategoryDataset dataset = new DefaultCategoryDataset();

        dataset.addValue(4.0, series1, category1);
        dataset.addValue(4.0, series1, category2);
        dataset.addValue(3.0, series1, category3);
        dataset.addValue(5.0, series1, category4);
        dataset.addValue(5.0, series1, category5);

        return dataset;
    }


    /**
     * Returns a sample dataset.
     *
     * @return The dataset.
     */
    private CategoryDataset createDataset2() {

        // row keys...
        String series2 = "Second";

        // column keys...
        String category1 = "Category 1";
        String category2 = "Category 2";
        String category3 = "Category 3";
        String category4 = "Category 4";
        String category5 = "Category 5";

        // create the dataset...
        DefaultCategoryDataset dataset = new DefaultCategoryDataset();

        dataset.addValue(5.0, series2, category1);
        dataset.addValue(7.0, series2, category2);
        dataset.addValue(6.0, series2, category3);
        dataset.addValue(8.0, series2, category4);
        dataset.addValue(6.0, series2, category5);

        return dataset;
    }


    /**
     * Returns a sample dataset.
     *
     * @return The dataset.
     */
    private CategoryDataset createDataset3() {

        // row keys...
        String series3 = "Third";

        // column keys...
        String category1 = "Category 1";
        String category2 = "Category 2";
        String category3 = "Category 3";
        String category4 = "Category 4";
        String category5 = "Category 5";

        // create the dataset...
        DefaultCategoryDataset dataset = new DefaultCategoryDataset();

        dataset.addValue(1.0, series3, category1);
        dataset.addValue(3.0, series3, category2);
        dataset.addValue(2.0, series3, category3);
        dataset.addValue(3.0, series3, category4);
        dataset.addValue(4.0, series3, category5);

        return dataset;
    }

    private CategoryDataset merge4StackedDataset(CategoryDataset d1, CategoryDataset d2){

        DefaultCategoryDataset dataset = new DefaultCategoryDataset();
        List<Comparable> columnKeys = d1.getColumnKeys();
        List<Comparable> d1RowKeys = d1.getRowKeys();
        List<Comparable> d2RowKeys = d2.getRowKeys();
        double minValue, maxValue;
        for (Comparable columnKey : columnKeys) {
            for (Comparable rowKey : d1RowKeys) {
                for (Comparable d2RowKey : d2RowKeys) {
                    minValue = Math.min(d1.getValue(rowKey, columnKey).doubleValue(),d2.getValue(d2RowKey, columnKey).doubleValue());
                    maxValue = Math.max(d1.getValue(rowKey, columnKey).doubleValue(),d2.getValue(d2RowKey, columnKey).doubleValue());
                    dataset.addValue(minValue, rowKey, columnKey);
                    dataset.addValue(maxValue - minValue, d2RowKey, columnKey);
//                    dataset.addValue(d2.getValue(d2RowKey, columnKey).doubleValue(), d2RowKey, columnKey);
                }
            }

        }

        return dataset;
    }

    private JFreeChart createChart() {

        CategoryDataset dataset1 = merge4StackedDataset(createDataset1(), createDataset2());
        CategoryDataset dataset2 = merge4StackedDataset(createDataset1(), createDataset3());

        //create chart with empty dataset
        final JFreeChart chart = ChartFactory.createAreaChart(
                "Testing",
                "Categories",
                "Values",
                dataset1,
                PlotOrientation.VERTICAL,
                true,  // legend
                true,  // tool tips
                false  // URLs
        );

        //make the chart have a white background
        chart.setBackgroundPaint(Color.white);

        //get the chart's plot
        final CategoryPlot plot = chart.getCategoryPlot();

        //color the plot
        plot.setBackgroundPaint(Color.lightGray);
        plot.setDomainGridlinePaint(Color.white);
        plot.setRangeGridlinePaint(Color.white);

        //make a stacked area renderer for the first dataset
        final StackedAreaRenderer renderer1 = new StackedAreaRenderer();
        renderer1.setEndType(AreaRendererEndType.LEVEL);
        renderer1.setDefaultToolTipGenerator(new StandardCategoryToolTipGenerator());

        //turn off the first data set that lets the stack float
        renderer1.setSeriesPaint(0, new Color(Color.blue.getRed(), Color.blue.getGreen(), Color.blue.getBlue(), 0));
        renderer1.setSeriesVisibleInLegend(0, false);

        plot.setRenderer(0, renderer1);
        plot.setRenderer(1, renderer1);


        plot.setDataset(2, dataset2);
        final StackedAreaRenderer renderer2 = new StackedAreaRenderer();
        renderer2.setEndType(AreaRendererEndType.LEVEL);
        renderer2.setDefaultToolTipGenerator(new StandardCategoryToolTipGenerator());
        renderer2.setSeriesPaint(0, new Color(Color.green.getRed(), Color.green.getGreen(), Color.green.getBlue(), 0));
        renderer2.setSeriesVisibleInLegend(0, false);
        plot.setRenderer(2, renderer2);
        plot.setRenderer(3, renderer2);

        plot.setDomainAxisLocation(AxisLocation.BOTTOM_OR_RIGHT);
        plot.getDomainAxis().setCategoryLabelPositions(CategoryLabelPositions.DOWN_45);
        plot.setDomainCrosshairVisible(true);
        plot.setRangeCrosshairVisible(true);

        return chart;
    }

    public static void main(String[] args) {
        final DifferenceWithCategories demo = new DifferenceWithCategories("Diference With Categories");
        demo.pack();
        RefineryUtilities.centerFrameOnScreen(demo);
        demo.setVisible(true);

    }
}