首页 > 解决方案 > JFreeChart 及时推进?

问题描述

我正在制作一个应用程序,我需要在图表中显示捕获特定数据的实时时间它“工作”,除了它跟不上实时,它一直在计数,好像时间已经过去了!我知道它可能与此 dataset.advanceTime () 相关联,但没有它,图形将变为静态并且即使实时过去也不再前进

package com.mycompany.moveplus;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.SimpleDateFormat;
import java.time.ZoneId;
import java.util.Date;
import java.util.TimeZone;
import javax.swing.JInternalFrame;
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.ValueAxis;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.data.time.DynamicTimeSeriesCollection;
import org.jfree.data.time.Second;
import org.jfree.data.xy.XYDataset;
import oshi.SystemInfo;
import oshi.hardware.CentralProcessor;
import oshi.hardware.HardwareAbstractionLayer;

public class Atol extends JInternalFrame {

    private static final float MINMAX = 100;
    private static final int COUNT = 2 * 60;
    private Timer timer;

    public Atol() {
        SimpleDateFormat sdf = new SimpleDateFormat("hh:mm:ss");
        Date date = new Date();

        final DynamicTimeSeriesCollection dataset
                = new DynamicTimeSeriesCollection(1, 60, new Second());
        dataset.setTimeBase(new Second(date));
        dataset.addSeries(gaussianData(), 0, "Uso de CPU");
        JFreeChart chart = createChart(dataset);

        this.add(new ChartPanel(chart), BorderLayout.CENTER);
        JPanel btnPanel = new JPanel(new FlowLayout());

        SystemInfo si = new SystemInfo();             //Criando uma nova classe de infos do Sistem
        HardwareAbstractionLayer hal = si.getHardware(); //Infos de Hardware do sistema
        CentralProcessor cpu = hal.getProcessor();      //E as informações da cpu
        long[] oldTricks = cpu.getSystemCpuLoadTicks();

        timer = new Timer(100, new ActionListener() {
            
            float cpu() {

                Double stats = cpu.getSystemCpuLoadBetweenTicks(oldTricks);
                //Convertendo o valor de uso da CPU
                stats = stats * 100d;
                double teste = Math.round(stats * 100.0) / 100.0;
                double d = teste;
                float f = (float) d;
                System.out.println(f);
                return f;
            }

            float[] newData = new float[1];

            @Override
            public void actionPerformed(ActionEvent e) {

                newData[0] = cpu();
              //  dataset.advanceTime();
                dataset.appendData(newData);
            }
        });
        timer.start();
    }

    private float[] gaussianData() {

        float[] a = new float[COUNT];
        for (int i = 0; i < a.length; i++) {
            a[i] = 2;
        }
        return a;
    }

    private JFreeChart createChart(final XYDataset dataset) {
        final JFreeChart result = ChartFactory.createTimeSeriesChart(
                "", "hh:mm:ss", "CPU%", dataset, true, true, false);
        final XYPlot plot = result.getXYPlot();
        //      DateAxis axis = (DateAxis) plot.getDomainAxis();

        plot.setRangeGridlinePaint(Color.decode("#e8e8e8"));
        plot.setBackgroundPaint(Color.white);
        plot.setOutlinePaint(null);
        plot.setOutlinePaint(null);

        XYItemRenderer renderer = plot.getRenderer();
        renderer.setSeriesPaint(0, Color.decode("#1b6ca8"));

        ValueAxis domain = plot.getDomainAxis();
        domain.setAutoRange(true);
        ValueAxis range = plot.getRangeAxis();
        range.setRange(0, MINMAX);
        return result;
    }

    public void start() {
        timer.start();
    }

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

            @Override
            public void run() {
                Atol demo = new Atol();

                demo.pack();

                demo.setVisible(true);
                demo.start();
            }
        });
    }
}

只有当时间真的过去时,我如何才能让它进步?

我正在重用这段代码

标签: javachartsdatasetjfreechart

解决方案


正如这里所建议的,ajavax.swing.Timer在以连续、同步的方式收集数据时效果很好。相反,以持续的异步方式收集数据可能会阻塞 GUI 线程。切换到SwingWorker,如此处所示publish()仅在需要时提供机会。理想情况下,您选择的可能会提供合适的回调,或者您可以简单地等待新数据到达。

在任何一种情况下,数据都会有时间间隔。你如何处理这个问题的确切细节将取决于你的用例,但我已经看到了一些常见的策略:

  • 使用可用功能在信号图表中导航整个数据集,如此此处此处所示;使用这里null建议的值来中断显示,如果有必要的话;这里举例说明。

  • 将突发数据分成单独的数据集并添加导航控件,如此处和此处所示


推荐阅读