1

XYSeries単一の で複数を表示する必要があるとしますXYSeriesCollectionXYSeries私の問題は、を追加するたびにJFreeChartがチャートを更新しようとするため、複数の を表示するプロセスが遅くなることXYSeriesです。

私が欲しいのはこれに似ています:

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

これどうやってするの?

4

2 に答える 2

1

目的のシリーズを持つ新しいを構築しXYSeriesCollection、 を呼び出しsetDataset()ますXYPlot。これにより、単一のDatasetChangeEvent.

補遺: これは、それぞれがN 2の値を持つNシリーズを更新する SSCCEです。これはパフォーマンスの問題であるため、この例はプロファイリングに役立つ場合があります。

テスト画像

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);
            }
        });
    }
}
于 2013-05-14T21:01:35.713 に答える
1

(と仮定して)のドキュメントをXYSeriesCollection見ると、メソッド(または類似のもの)はありaddません。addSeriesaddAll

必要に応じて、拡張して実装できます。この方法では、追加する前にすべてのリスナーを一時的に無効にし、後で再度追加することができます。ただし、これはおそらく悪い考えであり、次のようにする必要があります。XYSeriesCollectionaddAllsynchronized

  • 予測不可能なポリモーフィズムの動作を引き起こす可能性があります
  • AbstractDataset.listenerListそのままでは、リフレクション ハックが必要になります。private
  • セキュリティ例外を生成する可能性があります
  • スレッドセーフではありません

したがって、短い答えはノーです。それは実現不可能です。


…しかし、これはあなたがそれを行う方法の出発点です:

Field field = getClass().getDeclaredField("listenerList");
field.setAccessible(true);
EventListenerList ell = field.get(this);
// go from here
field.setAccessible(false);
于 2013-05-14T20:41:16.247 に答える