使用 JFreeChart 在 XYPlot 中创建多个系列的问题

2022-01-21 00:00:00 dataset java jfreechart

The following example code creates a graph with only one data series. The other two data series will not be created.

The main()-methods contains the data series.

import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.StandardXYItemRenderer;
import org.jfree.data.xy.XYDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;

import javax.swing.*;

public class MultipleChartFactory {
    private XYPlot plot;

    private ChartPanel chartPanel;

    // datasetIndex is used for multiple datasets
    private int datasetIndex = 0;
    private ArrayList<XYSeriesCollection> seriesArrayList = new ArrayList<XYSeriesCollection>();

    public MultipleChartFactory(String title, String xAxis) {
        super();
        String yAxis = title;

        XYSeriesCollection dataset = createDataset("Series");
        JFreeChart chart = ChartFactory.createXYLineChart("", xAxis, yAxis, dataset, PlotOrientation.VERTICAL, false, false, false);
        chart.setBackgroundPaint(Color.white);

        plot = chart.getXYPlot();
        plot.setBackgroundPaint(Color.lightGray);
        plot.setDomainGridlinePaint(Color.white);
        plot.setRangeGridlinePaint(Color.white);

        ValueAxis axis = plot.getDomainAxis();
        axis.setAutoRange(true);

        NumberAxis rangeAxis2 = new NumberAxis("Range Axis 2");
        rangeAxis2.setAutoRangeIncludesZero(false);

        JPanel content = new JPanel(new BorderLayout());
        chartPanel = new ChartPanel(chart);
        content.add(chartPanel);
    }

    private XYSeriesCollection createDataset(String name) {
        XYSeries series = new XYSeries(name);

        return new XYSeriesCollection(series);
    }

    public ChartPanel getChart() {
        return chartPanel;
    }

    public void createAdditionalDataset() {
        seriesArrayList.add(createDataset("S" + this.datasetIndex));

        this.datasetIndex++;
        this.plot.setDataset(
                this.datasetIndex, seriesArrayList.get(0));
        this.plot.setRenderer(this.datasetIndex, new StandardXYItemRenderer());
    }

    public XYSeriesCollection getXYSeries(int datasetIndex) {
        return seriesArrayList.get(datasetIndex);
    }

    public int getDatasetCount() {
        return this.plot.getDatasetCount();
    }

    public static void main(String [] args) throws InterruptedException {
        MultipleChartFactory mcf = new MultipleChartFactory("Battery","Time");

        JFrame frame = new JFrame();
        frame.setSize(700, 700);
        JPanel panel = new JPanel();
        panel.add(mcf.getChart());
        frame.add(panel);
        frame.setVisible(true);

        // on closing window
        frame.addWindowListener(new WindowAdapter() {
            public synchronized void windowClosing(WindowEvent we) {
                System.exit(0);
            }
        });

        mcf.createAdditionalDataset();
        mcf.createAdditionalDataset();
        mcf.createAdditionalDataset();
        mcf.getXYSeries(0).getSeries(0).add(1, 10);
        mcf.getXYSeries(0).getSeries(0).add(2, 100);
        Thread.sleep(3000);
        System.out.println("first");
        mcf.getXYSeries(1).getSeries(0).add(1, 20);
        mcf.getXYSeries(1).getSeries(0).add(2, 200);
        Thread.sleep(3000);
        System.out.println("second");
        mcf.getXYSeries(2).getSeries(0).add(1, 30);
        mcf.getXYSeries(2).getSeries(0).add(2, 300);
    }
}

Debugger stops after mcf.getXYSeries(0).getSeries(0).add(1, 10);. I am not really understanding why it stops there.

Do you have suggestion to display every data series in the graph?

解决方案

You need to use the datasetIndex when acessing the seriesArrayList.

public void createAdditionalDataset() {
    seriesArrayList.add(createDataset("S" + this.datasetIndex));
    this.plot.setDataset(this.datasetIndex, seriesArrayList.get(datasetIndex));
    this.plot.setRenderer(this.datasetIndex, new StandardXYItemRenderer());
    this.datasetIndex++;
}

Notes:

  • Program to the interface, e.g. List<XYSeriesCollection>.

  • Use pack() on the enclosing Window to obtain the preferred size of components.

  • See also Initial Threads.

SSCCE:

import java.awt.BorderLayout;
import java.awt.Color;
import java.util.ArrayList;
import java.util.List;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.StandardXYItemRenderer;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;

import javax.swing.*;

public class MultipleChartFactory {

    private XYPlot plot;
    private ChartPanel chartPanel;
    private int datasetIndex = 0;
    private List<XYSeriesCollection> seriesArrayList = new ArrayList<XYSeriesCollection>();

    public MultipleChartFactory(String title, String xAxis) {
        super();
        String yAxis = title;
        XYSeriesCollection dataset = createDataset("Series");
        JFreeChart chart = ChartFactory.createXYLineChart("", xAxis, yAxis,
            dataset, PlotOrientation.VERTICAL, false, false, false);
        chart.setBackgroundPaint(Color.white);
        plot = chart.getXYPlot();
        plot.setBackgroundPaint(Color.lightGray);
        plot.setDomainGridlinePaint(Color.white);
        plot.setRangeGridlinePaint(Color.white);
        ValueAxis axis = plot.getDomainAxis();
        axis.setAutoRange(true);
        NumberAxis rangeAxis2 = new NumberAxis("Range Axis 2");
        rangeAxis2.setAutoRangeIncludesZero(false);
        JPanel content = new JPanel(new BorderLayout());
        chartPanel = new ChartPanel(chart);
        content.add(chartPanel);
    }

    private XYSeriesCollection createDataset(String name) {
        XYSeries series = new XYSeries(name);
        return new XYSeriesCollection(series);
    }

    public ChartPanel getChart() {
        return chartPanel;
    }

    public void createAdditionalDataset() {
        seriesArrayList.add(createDataset("S" + this.datasetIndex));
        this.plot.setDataset(this.datasetIndex, seriesArrayList.get(datasetIndex));
        this.plot.setRenderer(this.datasetIndex, new StandardXYItemRenderer());
        this.datasetIndex++;
    }

    public XYSeriesCollection getXYSeries(int datasetIndex) {
        return seriesArrayList.get(datasetIndex);
    }

    public int getDatasetCount() {
        return this.plot.getDatasetCount();
    }

    public static void main(String[] args) throws InterruptedException {
        MultipleChartFactory mcf = new MultipleChartFactory("Battery", "Time");
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JPanel panel = new JPanel();
        panel.add(mcf.getChart());
        frame.add(panel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);

        mcf.createAdditionalDataset();
        mcf.createAdditionalDataset();
        mcf.createAdditionalDataset();
        mcf.getXYSeries(0).getSeries(0).add(1, 10);
        mcf.getXYSeries(0).getSeries(0).add(2, 100);
        System.out.println("first");
        mcf.getXYSeries(1).getSeries(0).add(1, 20);
        mcf.getXYSeries(1).getSeries(0).add(2, 200);
        System.out.println("second");
        mcf.getXYSeries(2).getSeries(0).add(1, 30);
        mcf.getXYSeries(2).getSeries(0).add(2, 300);
    }
}

相关文章