JFreeChart advancing in time?

﹥>﹥吖頭↗ 提交于 2021-01-28 06:06:53

问题


I am making an application in which I need to show in a chart the real time of capturing a certain data And it "works" except that it doesn’t keep up with the real time, it keeps counting as if time has passed! I know that it is possibly linked to this dataset.advanceTime () but without it the graph becomes static and does not advance any more even if the real time passes

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();
            }
        });
    }
}

how do i make it progress ONLY when time really passes?

I'm reusing this code


回答1:


As suggested here, a javax.swing.Timer works well when collecting data in a continuous, synchronous manner. In contrast, collecting data in an ongoing, asynchronous manner may block the GUI thread. Switching to SwingWorker, as shown here, offers the chance to publish() only when needed. Ideally, your chosen library may offer a suitable callback, or you can simply wait for new data to arrive.

In either case, there will be time gaps in the data. The precise details of how you deal with this will depend on you use case, but I've seen some common strategies:

  • Use available features to navigate the entire dataset in a signal chart, as shown here, here and here; use null values, as suggested here, to interrupt the display if warranted; an example is illustrated here.

  • Segregate bursts of data into separate datasets and add navigation controls, as shown here and here.



来源:https://stackoverflow.com/questions/65243226/jfreechart-advancing-in-time

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!