在 JFreeChart 中显示巨大的数据集

发布于 2024-12-02 10:50:51 字数 1806 浏览 2 评论 0原文

我有一个二维数组,包含超过 100k 条记录。当我尝试绘制图表时 - CPU 负载较重,并且没有其他情况发生。我已经检查了所有可能的方法,包括抗锯齿、禁用事件侦听器等。没有任何效果。我假设表演时间接近 3-5 分钟(好吧,这是相对的,但我想知道如何达到它)。

所以想问有没有办法可以正确显示数据?我有两个函数,一个用于指定图表,另一个用于绘制:

    public void plotXYChart(double dArray[][], String sPlotName, String sSeriesName,
        String sRangeName){
    XYSeries series1 = new XYSeries(sSeriesName);
    series1.clear();
    for (int i=0; i< dArray.length; i++){
        series1.add(dArray[i][0], dArray[i][1], false);
    }
    XYSeriesCollection dataset = new XYSeriesCollection();
    dataset.removeAllSeries();
    dataset.addSeries(series1);
    dataset.setAutoWidth(false);
    dataset.setIntervalWidth(2000);

    chart = ChartFactory.createXYLineChart(sPlotName, sSeriesName, sRangeName,
            dataset, PlotOrientation.VERTICAL, false,
            true, false);

    chart.setAntiAlias(false);
    XYPlot plot = (XYPlot) chart.getPlot();
    plot.getDomainAxis().setStandardTickUnits(new StandardTickUnitSource());
    plot.getRangeAxis().setStandardTickUnits(new StandardTickUnitSource());

    SamplingXYLineRenderer renderer = new SamplingXYLineRenderer();
    plot.setRenderer(renderer);
    plotChart(sPlotName, chart);
}

    private void plotChart(String sPlotName, JFreeChart chart){

    if (this.cPanel!=null) 
        cPanel.setChart(chart);
    else
        cPanel = new ChartPanel(chart);

    cPanel.setAutoscrolls(false);
    cPanel.setDomainZoomable(false);
    cPanel.setRangeZoomable(false);
    cPanel.setRefreshBuffer(false);
    cPanel.setDoubleBuffered(rootPaneCheckingEnabled);
    this.chartFrame.add(cPanel);
    this.chartFrame.pack();
    if (this.chartFrame.isVisible() == false)
        RefineryUtilities.centerFrameOnScreen(this.chartFrame);
    this.chartFrame.setVisible(true);

}

I have an two-dimension array with the over of 100k records. When I'm trying to chart it - CPU is hard loading, and nothing else is going on. I've checked all the possible ways, including anti-alias, disabling event listeners etc. Nothing is working. And I assume a performance near 3-5 minutes (ok, that's relative thing, but I'd like to know how to reach it).

Therefore, I'm asking if there is a way to display the data correctly? I'm having two functions, one for specifying the chart, and another for it's plotting:

    public void plotXYChart(double dArray[][], String sPlotName, String sSeriesName,
        String sRangeName){
    XYSeries series1 = new XYSeries(sSeriesName);
    series1.clear();
    for (int i=0; i< dArray.length; i++){
        series1.add(dArray[i][0], dArray[i][1], false);
    }
    XYSeriesCollection dataset = new XYSeriesCollection();
    dataset.removeAllSeries();
    dataset.addSeries(series1);
    dataset.setAutoWidth(false);
    dataset.setIntervalWidth(2000);

    chart = ChartFactory.createXYLineChart(sPlotName, sSeriesName, sRangeName,
            dataset, PlotOrientation.VERTICAL, false,
            true, false);

    chart.setAntiAlias(false);
    XYPlot plot = (XYPlot) chart.getPlot();
    plot.getDomainAxis().setStandardTickUnits(new StandardTickUnitSource());
    plot.getRangeAxis().setStandardTickUnits(new StandardTickUnitSource());

    SamplingXYLineRenderer renderer = new SamplingXYLineRenderer();
    plot.setRenderer(renderer);
    plotChart(sPlotName, chart);
}

    private void plotChart(String sPlotName, JFreeChart chart){

    if (this.cPanel!=null) 
        cPanel.setChart(chart);
    else
        cPanel = new ChartPanel(chart);

    cPanel.setAutoscrolls(false);
    cPanel.setDomainZoomable(false);
    cPanel.setRangeZoomable(false);
    cPanel.setRefreshBuffer(false);
    cPanel.setDoubleBuffered(rootPaneCheckingEnabled);
    this.chartFrame.add(cPanel);
    this.chartFrame.pack();
    if (this.chartFrame.isVisible() == false)
        RefineryUtilities.centerFrameOnScreen(this.chartFrame);
    this.chartFrame.setVisible(true);

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

金橙橙 2024-12-09 10:50:51

这不是 JFreeChart 问题。您只是试图绘制太多数据。如果你尝试用挥杆画 100k 线,你也会感受到同样的性能问题。减少数据集。

您也可以尝试解决方法,但我不确定它是否有效。不显示生成的 ChartPanel。相反,使用以下方法生成 ChartPanel 的图像:

Image image = chartPanel.createImage ();

在您喜欢的组件内显示生成的图像。图像的生成时间可能相当长,但一旦生成,它应该更快地显示它并调整存储它的组件的大小。这是因为它是静态图像,显示它时不会调用绘图基元。
当然,这样您将失去所有 ChartPanel 功能,只获得它的图像。

It's not a JFreeChart problem. You are simply trying to draw too many datas. If you try to draw 100k line with swing you would feel the same performances problem. Reduce your dataset.

You can also trying a work around, but I'm not sure it will work. Don't show the generated ChartPanel. Instead generate the image of your ChartPanel using:

Image image = chartPanel.createImage ();

Display the generated image inside the component you prefer. The generation time of the image could be quite high, but once generated it should be faster display it and resizing the component in which it is stored. That's because it's a static image and drawing primitives won't be called while displaying it.
Of course this way you will loose all ChartPanel functions, getting only it's image.

云归处 2024-12-09 10:50:51

为了最大限度地减少渲染工作,您可以查看此处讨论的SlidingXYDataset

附录:或者,您可以按照建议将数据的可管理部分分页到视图中 这里

To minimize rendering effort, you might look into SlidingXYDataset, discussed here.

Addendum: Alternatively, you can page manageable portions of the data into view, as suggested here.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文