1

私は JFreeChart を初めて使用し、巨大なデータセットをレンダリングしようとしてパフォーマンスの問題に直面しています。私のシナリオのデータセットは、46700 をはるかに超える行 (行) とプロットする約 2666900 以上のデータ ポイントを持つ csv ファイルから取得されます。

プロットの現在のコードは次のとおりです。

public  void doPlot(String plotTitle, HashMap<Integer, ArrayList<PlotCheckBox>> plotDataList, boolean dotOnly) {

    plotDialog.dispose();

    DefaultXYDataset xyDataSet;
    try {
        if (plotDataList.isEmpty()) {
            return;
        }

        xyDataSet = new DefaultXYDataset();
        /**
         * Populate Data Set
         */
        boolean[] optionList;
        int countPlotPoints = 0;

        for (Integer tabIndex : plotDataList.keySet()) {
            ArrayList<PlotCheckBox> checkBoxList = plotDataList.get(tabIndex);
            try {
                if (checkBoxList == null) {
                    continue;
                } else if (checkBoxList.isEmpty()) {
                    continue;
                }

                optionList = new boolean[checkBoxList.size()];
                for (int index = 0; index < checkBoxList.size(); index++) {
                    optionList[index] = checkBoxList.get(index).isSelectedForPlot();
                }

                /**
                * The getTabXYData() method builds up the xyDataSet by loading values from a given csv file and the 
                * attributes chosen by the user to plot
                */
                countPlotPoints += getTabXYData(xyDataSet, tabIndex, optionList, jTabbedPane_results.getTitleAt(tabIndex));
            } finally {
                checkBoxList = null;
                optionList = null;
            }
        }

        System.out.println("Plot Points In This Graph: "+countPlotPoints);

        if (countPlotPoints == 0) {
            print("No options selected.\n");
            JOptionPane.showMessageDialog(this, "No Plot Points Were Selected!", "Warning", JOptionPane.WARNING_MESSAGE);
            return;
        }

        JFreeChart chart = ChartFactory.createXYLineChart(plotTitle, "time(ms)", "---", xyDataSet, PlotOrientation.VERTICAL, true, true, false);
        XYPlot plot = (XYPlot) chart.getPlot();
        XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer();

        for (int i = 0; i < countPlotPoints; i++) {
            if (dotOnly) {
                renderer.setSeriesLinesVisible(i, false);
            } else {
                renderer.setSeriesLinesVisible(i, true);
            }
            renderer.setSeriesShapesVisible(i, true);
        }
        plot.setRenderer(renderer);


        ChartPanel chartpanel = new ChartPanel(chart);
        chartpanel.setDefaultDirectoryForSaveAs(new File(lastAnalyzedPath));

        JFrame frame = new JFrame();
        frame.setTitle(plotTitle);
        frame.add(new JScrollPane(chartpanel));
        frame.pack();
        frame.setVisible(true);

        frame.addWindowListener(new java.awt.event.WindowAdapter() {
            @Override
            public  void windowClosing(java.awt.event.WindowEvent evt) {
                try {
                    System.out.println(":: Clearning Memory ::");
                    System.out.println("\tFree Memory (Before cleanup): "+Runtime.getRuntime().freeMemory());
                    Component component = getComponent(0);
                    if(component instanceof ChartPanel){
                        JFreeChart chart = ((ChartPanel) component).getChart();
                        XYPlot plot = (XYPlot) chart.getPlot();
                        plot        = null;
                        chart       = null;
                        component   = null;
                    }
                } finally {
                    System.runFinalization();
                    System.gc();
                    System.out.println("\tFree Memory (Post cleanup): "+Runtime.getRuntime().freeMemory());
                }
            }
        });

    } finally {
        xyDataSet = null;
        System.runFinalization();
        System.gc();
    }
}

この膨大なデータセットのため、プロットの読み込みに時間がかかり、プロット ウィンドウのサイズを変更しようとすると OutOfMemoryError がスローされ、アプリケーションがクラッシュします。

私が知りたいのは、パフォーマンスを改善するための提案です。これが私が考えたことです(これに関するコメント/提案/フィードバックは本当にありがたいです):

  1. プロットする特定の範囲にユーザーを制限します。問題は、JFreeChart が処理できるデータの量がわからないことです。これに関する提案はありますか?マジックナンバーや試行錯誤の方法を使用したくないことが望ましいです。

  2. スクロール可能な XYDataSet を使用します。私はこれにかなり慣れていないため、実装についてはあまり考えていません。サンプル コードと、この手法の有効性に関するコメントをいただければ幸いです。

私は新しいアイデアを探求することにオープンです。この問題についてどう思うか教えてください。事前に多くの感謝を!

4

1 に答える 1

1

~10 6データ ポイントの場合FastScatterPlotは、良い選択です。より大きな数については、テストする必要があります。render()速度を上げるために、プラグイン レンダラーではなく、内部メソッドを使用します。またSwingWorker、データが読み取られるときにグラフを段階的に更新するために を使用することも検討してください。

于 2012-07-02T14:50:57.050 に答える