私は 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 がスローされ、アプリケーションがクラッシュします。
私が知りたいのは、パフォーマンスを改善するための提案です。これが私が考えたことです(これに関するコメント/提案/フィードバックは本当にありがたいです):
プロットする特定の範囲にユーザーを制限します。問題は、JFreeChart が処理できるデータの量がわからないことです。これに関する提案はありますか?マジックナンバーや試行錯誤の方法を使用したくないことが望ましいです。
スクロール可能な XYDataSet を使用します。私はこれにかなり慣れていないため、実装についてはあまり考えていません。サンプル コードと、この手法の有効性に関するコメントをいただければ幸いです。
私は新しいアイデアを探求することにオープンです。この問題についてどう思うか教えてください。事前に多くの感謝を!