在jFreeChart中一次显示所有XYSeries以提高速度

假设我们需要在单个XYSeriesCollection显示多个XYSeriesCollection 。 我的问题是每次添加XYSeriesJFreeChart都想更新图表,这会减慢显示多个XYSeries的过程。

我想要的是这样的:

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

我怎样才能做到这一点?

构造具有所需系列的新XYSeriesCollection ,并在XYPlot上调用setDataset() 。 这将生成一个DatasetChangeEvent

附录:这是一个更新N系列的SSCCE,每个都有N 2个值。 由于这是性能问题,因此该示例可能有助于分析 。

测试图像

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

查看XYSeriesCollection的文档 (假设add应该是addSeries ),没有方法addAll (或类似的)。

如果需要, 可以扩展XYSeriesCollection并实现addAll 。 在此方法中,您可以在添加之前暂时禁用所有侦听器,然后重新添加它们。 但是,这可能是一个坏主意,肯定需要synchronized

  • 它会产生不可预测的多态行为
  • 它需要reflection黑客,因为AbstractDataset.listenerListprivate
  • 它可能会产生安全exception
  • 它不是线程安全的

所以简短的答案是否定的,这是不可行的


……但这是你如何做到这一点的起点:

 Field field = getClass().getDeclaredField("listenerList"); field.setAccessible(true); EventListenerList ell = field.get(this); // go from here field.setAccessible(false);