1

Suppose that we need to display multiple XYSeries in a single XYSeriesCollection. My problem is that every time I add a XYSeries, the JFreeChart wants to update the chart and that slows down the process of displaying multiple XYSeries.

What I want is similar to this:

// Do not update the chart
XYSeriesCollection.add(XYSeries1)
XYSeriesCollection.add(XYSeries2) 
...
XYSeriesCollection.add(XYSeries10)
// Update the chart

How can I do this?

wchargin
  • 15,589
  • 12
  • 71
  • 110
C graphics
  • 7,308
  • 19
  • 83
  • 134

2 Answers2

1

Looking at the documentation for XYSeriesCollection (assuming add should be addSeries) there is no method addAll (or similar).

If you want, you could extend XYSeriesCollection and implement addAll. In this method, you could temporarily disable all listeners before adding and re-add them after. However, this would probably be a bad idea, and would definitely need to be synchronized:

  • it would produce unpredictable polymorphism behavior
  • it would require reflection hacks, as AbstractDataset.listenerList is private
  • it could generate a security exception
  • it would not be thread safe

So the short answer is no, it is not feasible.


… but this is a starting point for how you could do it:

Field field = getClass().getDeclaredField("listenerList");
field.setAccessible(true);
EventListenerList ell = field.get(this);
// go from here
field.setAccessible(false);
wchargin
  • 15,589
  • 12
  • 71
  • 110
1

Construct a new XYSeriesCollection having the desired series, and invoke setDataset() on the XYPlot. This will generate a single DatasetChangeEvent.

Addendum: Here's an SSCCE that updates N series, each having N2 values. As this is a performance question, the example may be helpful in profiling.

test image

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.util.Random;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import org.jfree.chart.*;
import org.jfree.chart.plot.XYPlot;
import org.jfree.data.time.Day;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.data.xy.XYDataset;

public class ChartPanelTest {

    private static final int N = 16;
    private static final Random random = new Random();

    private static XYDataset createDataset() {
        TimeSeriesCollection tsc = new TimeSeriesCollection();
        for (int j = 0; j < N; j++) {
            TimeSeries series = new TimeSeries("Data" + j);
            Day current = new Day();
            for (int i = 0; i < N * N; i++) {
                series.add(current, random.nextGaussian());
                current = (Day) current.next();
            }
            tsc.addSeries(series);
        }
        return tsc;
    }

    private static JFreeChart createChart(final XYDataset dataset) {
        JFreeChart chart = ChartFactory.createTimeSeriesChart(
            "Test", "Day", "Value", dataset, false, false, false);
        return chart;
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame f = new JFrame();
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                XYDataset dataset = createDataset();
                JFreeChart chart = createChart(dataset);
                final XYPlot plot = chart.getXYPlot();
                ChartPanel chartPanel = new ChartPanel(chart) {
                    @Override
                    public Dimension getPreferredSize() {
                        return new Dimension(600, 300);
                    }
                };
                f.add(chartPanel);
                JPanel p = new JPanel();
                p.add(new JButton(new AbstractAction("New") {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        plot.setDataset(createDataset());
                    }
                }));
                f.add(p, BorderLayout.SOUTH);
                f.pack();
                f.setLocationRelativeTo(null);
                f.setVisible(true);
            }
        });
    }
}
Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • Thanks. Could you please take a look at this one too: http://stackoverflow.com/questions/16574733/how-to-make-jfreechart-displaying-the-tooltip-point-information-faster – C graphics May 15 '13 at 20:51