JFreechart 替代方案

发布于 2024-10-26 00:48:00 字数 283 浏览 1 评论 0原文

我在我的一个 java 应用程序中使用 JFreeChart,但它的问题是,当您对图表模型进行任何更改时,它会再次绘制整个图表。

我知道我们可以删除 ChartChangeListener 并根据我们的需要添加它们,这样它就不会每次都触发 ChartChangeEvent,但这并不能解决我的问题。

就我而言,XYSeries 超出了 X 轴上的图表边界。可见的 x 轴为 6 厘米。因此,当系列超过 6 厘米时,我将丢弃 1 厘米初始可见数据并再次绘制下一个 6 厘米数据。

在这种情况下,它开始闪烁。

I am using JFreeChart in one of my java applications but the problem with it is that it paints the whole chart again when you make any changes to the chart model.

I know that we can remove the ChartChangeListener and add them according to our needs so that it don't fire chartChangeEvent everytime but it doesn't solve my problem.

In my case, the XYSeries goes beyond the chart boundary on the X-axis. The visible x-axis is 6cm. So when the series goes beyond 6cm, I am discarding the 1cm initial visible data and plotting the next 6cm data again.

In that case, it starts blinking.

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

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

发布评论

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

评论(1

So尛奶瓶 2024-11-02 00:48:06

仅绘制可见区域是错误的想法。一般来说,您真正想要的是创建一个包含整个图表的 BufferedImage,然后您不需要每秒重新绘制整个图表 1000 次。如果您无法缓冲整个图表(例如,您正在绘制实时数据),则至少应该保存以缓冲单个点(如果它大于 1 像素)。
在java中填充形状是非常昂贵的操作。

下面的代码非常慢(当绘制太多点时)

   for(int x=0; x < max; x++){
     Ellipse2D.Double ellipse = new Ellipse2D.Double(x - 1.5, f(x) -1.5, 3, 3);
     g.setPaint(color);
     g.draw(ellipse);
     g.fill(ellipse);
   }

它应该被替换为

   private BufferedImage createBufferedImage(Color color) {
        BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
        Graphics2D buff = bufferedImage.createGraphics();
        Ellipse2D.Double ellipse = new Ellipse2D.Double(0, 0, 3, 3);
        buff.setPaint(color);
        buff.draw(ellipse);
        buff.fill(ellipse);
        return bufferedImage;
    }

   AffineTransform at = new AffineTransform();
   at.scale(1, 1);
   createBufferedImage(Color.RED);
   for(int x=0; x < max; x++){
            at.setToIdentity();
            at.translate(x - 2, y - 2);
            g.drawImage(bufferedImage, at, null);
   }

具有相同功能的代码,只是速度快很多倍。 AFAIK 在 JFreeChart 中他们没有正确使用缓冲,这是它如此慢的原因之一。

Plotting just visible area is a wrong idea. Generally what you really want is to create a BufferedImage which will contain the whole chart and then you don't need to repaint the whole chart 1000 times per second. If you can't buffer the whole chart (e.g. you're plotting a real-time data) you should at least save to buffer a single point if it's bigger than 1px.
Filling shapes is very expensive operation in java.

Following code is terribly slow (when plotting too many points)

   for(int x=0; x < max; x++){
     Ellipse2D.Double ellipse = new Ellipse2D.Double(x - 1.5, f(x) -1.5, 3, 3);
     g.setPaint(color);
     g.draw(ellipse);
     g.fill(ellipse);
   }

It should be replaced by

   private BufferedImage createBufferedImage(Color color) {
        BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
        Graphics2D buff = bufferedImage.createGraphics();
        Ellipse2D.Double ellipse = new Ellipse2D.Double(0, 0, 3, 3);
        buff.setPaint(color);
        buff.draw(ellipse);
        buff.fill(ellipse);
        return bufferedImage;
    }

   AffineTransform at = new AffineTransform();
   at.scale(1, 1);
   createBufferedImage(Color.RED);
   for(int x=0; x < max; x++){
            at.setToIdentity();
            at.translate(x - 2, y - 2);
            g.drawImage(bufferedImage, at, null);
   }

which does the same, just many times faster. AFAIK in JFreeChart they don't use buffering properly, which is one of reasons why it is so slow.

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