JFreeChart - 如何在TimeSeries图表的X轴上显示实时 [英] JFreeChart - How to show real-time on the X-Axis of a TimeSeries chart

查看:117
本文介绍了JFreeChart - 如何在TimeSeries图表的X轴上显示实时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在TimeSeries图表上显示实时数据,其中实时显示在x轴上(或者至少具有与实时相同的时间速度)。

I want to show live data on a TimeSeries chart with real time shown on the x-axis (or at least have the speed of the time the same as real-time).

这是问题的SSCCE,随机数作为实时输入。 x轴上显示的时间比实时快得多(假设它以hh:mm:ss格式显示):

Here is a SSCCE of the problem with random numbers as the live input. The time shown on the x-axis is much faster than real-time (assuming it is shown in hh:mm:ss format):

public class DynamicTimeSeriesChart extends JPanel {

    private DynamicTimeSeriesCollection dataset;
    private JFreeChart chart = null;

    public DynamicTimeSeriesChart(final String title) {

        dataset = new DynamicTimeSeriesCollection(1, 2000, new Second());
        dataset.setTimeBase(new Second(0, 0, 0, 1, 1, 1990)); // date 1st jan 0 mins 0 secs

        dataset.addSeries(new float[1], 0, title);
        chart = ChartFactory.createTimeSeriesChart(
            title, "Time", title, dataset, true,
            true, false);
        final XYPlot plot = chart.getXYPlot();

        ValueAxis axis = plot.getDomainAxis();
        axis.setAutoRange(true);
        axis.setFixedAutoRange(200000); // proportional to scroll speed
        axis = plot.getRangeAxis();

        final ChartPanel chartPanel = new ChartPanel(chart);
        setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
        add(chartPanel);
    }

    public void update(float value) {
        float[] newData = new float[1];
        newData[0] = value;
        dataset.advanceTime();
        dataset.appendData(newData);
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame("testing");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        final DynamicTimeSeriesChart chart = new DynamicTimeSeriesChart("random numbers");
        frame.add(chart);
        frame.pack();
        frame.setVisible(true);
        Timer timer = new Timer(100, new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                EventQueue.invokeLater(new Runnable() {
                    @Override
                    public void run() {
                        chart.update((float) (Math.random() * 10));
                    }
                });
            }
        });
        timer.start();
    }
}


推荐答案

虽然 sleep()是可以接受的=nofollow noreferrer>初始线程,应在事件派发线程上构造和操作Swing GUI对象 。相反,使用 javax.swing.Timer 来调整更新速度,如此处所示。 100 ms的延迟将以大约10 Hz的速度更新。

While it is acceptable to sleep() on the initial thread, Swing GUI objects should be constructed and manipulated only on the event dispatch thread. Instead, use a javax.swing.Timer to pace the updates, as shown here. A delay of 100 ms will update at approximately 10 Hz.

如果漂移不可接受,请轮询主机的时钟来自另一个名义利率一半的线程,并使用 EventQueue.invokeLater()更新数据集。确保主机已同步到NTP服务器。

If the drift is unacceptable, poll the host's clock from another thread at half the nominal rate and update the dataset using EventQueue.invokeLater(). Ensure that the host is synchronized to an NTP server.

附录:根据您的更新,请注意必须构建所有 Swing GUI对象并且在事件派发线程上仅操作 ,而不仅仅是 javax.swing.Timer中 。 Swing Timer 的优点是它在EDT上触发。下面的变化显示了近似实时10秒的1 Hz数据。

Addendum: Based on your update, note that all Swing GUI objects must be constructed and manipulated only on the event dispatch thread, not just the javax.swing.Timer. The advantage of a Swing Timer is that it fires on the EDT. The variation below shows 10 seconds of 1 Hz data at approximately real time.

附录:您可以调整传递给 setTimeBase()的时间此处所示。

Addendum: You can adjust the time passed to setTimeBase() as shown here.

import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.SimpleDateFormat;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.plot.XYPlot;
import org.jfree.data.time.DynamicTimeSeriesCollection;
import org.jfree.data.time.Second;

/**
 * @see https://stackoverflow.com/a/21307289/230513
 */
public class DynamicTimeSeriesChart extends JPanel {

    private final DynamicTimeSeriesCollection dataset;
    private final JFreeChart chart;

    public DynamicTimeSeriesChart(final String title) {
        dataset = new DynamicTimeSeriesCollection(1, 1000, new Second());
        dataset.setTimeBase(new Second(0, 0, 0, 23, 1, 2014));
        dataset.addSeries(new float[1], 0, title);
        chart = ChartFactory.createTimeSeriesChart(
            title, "Time", title, dataset, true, true, false);
        final XYPlot plot = chart.getXYPlot();
        DateAxis axis = (DateAxis) plot.getDomainAxis();
        axis.setFixedAutoRange(10000);
        axis.setDateFormatOverride(new SimpleDateFormat("ss.SS"));
        final ChartPanel chartPanel = new ChartPanel(chart);
        add(chartPanel);
    }

    public void update(float value) {
        float[] newData = new float[1];
        newData[0] = value;
        dataset.advanceTime();
        dataset.appendData(newData);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                JFrame frame = new JFrame("testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                final DynamicTimeSeriesChart chart
                    = new DynamicTimeSeriesChart("Alternating data");
                frame.add(chart);
                frame.pack();
                Timer timer = new Timer(1000, new ActionListener() {
                    private boolean b;

                    @Override
                    public void actionPerformed(ActionEvent e) {
                        chart.update(b ? 1 : 0);
                        b = !b;
                    }
                });
                timer.start();
                frame.setVisible(true);
            }
        });
    }
}

这篇关于JFreeChart - 如何在TimeSeries图表的X轴上显示实时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆