Наборы данных из нескольких областей с накоплением в JFreechart - PullRequest
0 голосов
/ 29 ноября 2018

Я использую JFreechart и пытаюсь получить то, что будет похоже на XYDifferenceRenderer, но для CategoryPlot.Проблема, с которой я сталкиваюсь - это возможность нанести несколько StackedAreaRenderer s на один и тот же графикУ следующего есть одна 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
Если я раскомментирую фрагменты кода для dataset2 и renderer2, то получаю странные результаты, где у меня есть три областии три элемента, перечисленные в легенде.

версия 2
Если я раскомментирую разделы кода для dataset2 и renderer1, я получаю то, что я думаю, близко к тому, что я хочу, нообласть для обоих - красная, а для обеих - легенда Second, которой нет для dataset2.

Кто-нибудь знает, как я могу получить раскраску для версии 1, но область установленаверсии 2?

1 Ответ

0 голосов
/ 29 ноября 2018

Я узнал, как получить то, что я ищу.Проблема возникает из-за того, что визуализатору нужно знать индекс наборов данных относительно самого себя по сравнению с индексом наборов данных относительно графика.
Таким образом, это было исправлено с помощью второго визуализатора, использующего индексирование набора данных относительно себя, когда визуализатор добавляется всюжет.

Код с ожидаемыми выходами:

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

    }
}
...