java - 使用 JFreeChart 的故障绘图

标签 java graph jfreechart

我正在使用 JFreeChart 绘制多个 TimeSeries 图表。它似乎工作正常,但截至今天,所有图表似乎都在闪烁并且随机出现故障,使它们无法看到。如果我最小化和最大化,问题会在几秒钟内得到解决,直到下一次更新或单击鼠标。有没有人知道问题可能是什么?

alt text

代码非常简单:

TimeSeries ts = new TimeSeries("Graph", Millisecond.class);
TimeSeriesCollection dataset = new TimeSeriesCollection(ts);
JFreeChart Graph = createChart(dataset);
ChartPanel panel_Graph = new ChartPanel(Graph);

....

JFrame newWindow = new JFrame("Graph");
newWindow.setLayout(new GridLayout());
newWindow.setContentPane(panel_Graph);
newWindow.setMinimumSize(new Dimension(600, 480));
newWindow.setLocationRelativeTo(null);
newWindow.setVisible(true);


static private JFreeChart createChart(TimeSeriesCollection dataset) {
        JFreeChart chart = ChartFactory.createTimeSeriesChart(
            "Graph",
            "Time",
            "Value",
            dataset,
            false,
            true,
            false
        );
        final XYPlot plot = chart.getXYPlot();
        ValueAxis timeaxis = plot.getDomainAxis();
        timeaxis.setAutoRange(true);
        timeaxis.setFixedAutoRange(60000.0);
        return chart;
}

最佳答案

如果您看到不一致/损坏的图像,有时表明在事件调度线程以外的线程上更新了数据集。我建议您添加一些断言语句来验证这一点:

断言 SwingUtilities.isEventDispatchThread();

另外,请注意 JFreeChart 并不是特别有效,因为它会在添加新数据点时重新呈现整个图形。您可以在此处进行的一项优化是:

  • 如果您的应用包含多个图表,则只传播当前显示的图表的 DatasetChangeEvent。如果图表被隐藏(例如在不同的选项卡上),则只需记录它已过时并且需要在选择选项卡时重新呈现的事实。

编辑

根据您对 Dan 回复的评论,听起来您的 I/O 线程接收消息也在更新 JFreeChart 数据集,而实际上更新应该在事件调度线程上执行(并且消息应该在单独的 I 上执行/O 线程)。为实现这一点,我建议您使用基于限制的方法,将 I/O 事件集中在一起。您可以使用 BlockingQueue 来实现此目的;例如

// Message definition containing update information.
public interface Message { ... }

// BlockingQueue implementation used to enqueue updates received on I/O thread.
BlockingQueue<Message> msgQ = ...

// Method called by I/O thread when a new Message is received.
public void msgReceived(Message msg) {
  boolean wasEmpty = msgQ.isEmpty();

  msgQ.add(msg);

  // Queue was empty so need to re-invoke Swing thread to process queue.
  if (wasEmpty) {
    // processUpdates is a re-useable Runnable defined below.
    SwingUtilities.invokeLater(processUpdates);
  }
}

// Runnable that processes all enqueued events.  Much more efficient than:
// a) Creating a new Runnable each time.
// b) Processing one Message per call to run().
private final Runnable processUpdates = new Runnable() {
  public void run() {
    Message msg;

    while ((msg = msgQ.poll) != null) {
      // Add msg to dataset within Event Dispatch thread.
    }
  }
}

关于java - 使用 JFreeChart 的故障绘图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1559958/

相关文章:

java - 如何在 Java 1.4 中向自定义类添加迭代器的示例?

python-2.7 - 通过两个属性从列表聚类相关项目构建图形的更好方法

java - 我可以根据比例缩放ValueAxis吗?

java - 线性 yAxis 上的指数刻度 - JFreeChart

java - getSize 期间出现 NullPointerException

java - 关闭命令窗口时如何在生产模式下启动 grail 应用程序而不终止 session ?

java - java中的欧拉方法

algorithm - 修改距离以违反三角不等式

python - 如何使用networkx在两个图之间执行树交叉?

java - 如何正确使用 JFreeChart 自动范围?