java - 性能问题 - JFreeChart (XYDataSet)

标签 java performance jfreechart scatter-plot

我对 JFreeChart 还很陌生,在尝试渲染巨大的数据集时面临性能问题。我的场景中的数据集来自一个 csv 文件,该文件包含超过 46700 行(行)和大约 2666900 多个要绘制的数据点。

我当前的绘图代码如下:

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 可以处理多少数据。对此有什么建议吗?我最好不想使用魔数(Magic Number)或只是试错方法。

  2. 使用可滚动的 XYDataSet。我对此还很陌生,对实现不太了解。任何示例代码以及对使用此技术的功效的评论都将受到高度赞赏。

我乐于探索新想法。请告诉我您对这个问题的看法。非常感谢!

最佳答案

对于约 106 个数据点,FastScatterPlot是一个不错的选择。对于更大的数字,您必须进行测试。为了速度,它使用内部 render()方法,而不是插件渲染器。还可以考虑使用 SwingWorker 在读取数据时增量更新图表。

关于java - 性能问题 - JFreeChart (XYDataSet),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11295538/

相关文章:

java - 在开关中使用枚举

java - 输入与多项式的CRC计算转换

PHP HTML 生成 - 使用字符串连接

java - 我可以强制 JVM 本地编译给定的方法吗?

java - 动态工具提示生成器 - Jfreechart

java - 使用jfreechart创建条形图,通过访问2个文件中的数据并以不同的颜色显示文件1和文件2的数据

java - parse.com - 使用 .include() 查询检索数组数据有多深?

java - 如果使用 API 的数据库发生变化,如何显示推送通知?

c# & java 套接字和字节数据读取开销

java - 快速绘制多个图表的计时问题