Saltar al contenido

Gráficos en tiempo real en Java

Solución:

Si su variable se actualiza tan rápido, no tiene sentido actualizar un gráfico cada vez.

¿Ha pensado en almacenar en búfer los cambios de variable y actualizar el gráfico en un hilo diferente, digamos, cada 5 segundos? Debería encontrar que JFreeChart puede manejar bien tales tasas de actualización.

Dado que JFreeChart es una biblioteca de escritorio normal, puede integrarla con una aplicación estándar de Swing muy fácilmente. O bien, puede usarlo para crear gráficos a través de una aplicación web (renderizándolo en un JPEG / PNG, etc. JFreeChart también puede generar mapas de imágenes automáticamente, por lo que puede usar el mouse, etc.)

Para que su CPU esté muy por debajo del 100% y permitir que su GUI siga respondiendo, debe reducir la velocidad de actualización de su gráfico. Una tasa de actualización máxima de alrededor de 24 cuadros por segundo tiene sentido para un gráfico en tiempo real; cualquiera más rápido es más o menos indistinguible de todos modos. Si sus datos llegan más rápido que esa tasa, solo necesita almacenarlos en un búfer en segundo plano y actualizar su gráfico en primer plano a la tasa de actualización deseada. En el siguiente ejemplo, utilizo XChart junto con un SwingWorker hilo de fondo. La captura de datos se simula a una velocidad de una por cada 5 ms y el gráfico se actualiza a 24 fotogramas por segundo. Este concepto debería funcionar con JFreeCharts o cualquier otra biblioteca de gráficos también con una ligera modificación. Descargo de responsabilidad: soy el desarrollador principal de XChart.

import java.util.LinkedList;
import java.util.List;

import javax.swing.SwingWorker;

import org.knowm.xchart.QuickChart;
import org.knowm.xchart.SwingWrapper;
import org.knowm.xchart.XYChart;

/**
 * Creates a real-time chart using SwingWorker
 */
public class SwingWorkerRealTime {

  MySwingWorker mySwingWorker;
  SwingWrapper<XYChart> sw;
  XYChart chart;

  public static void main(String[] args) throws Exception {

    SwingWorkerRealTime swingWorkerRealTime = new SwingWorkerRealTime();
    swingWorkerRealTime.go();
  }

  private void go() {

    // Create Chart
    chart = QuickChart.getChart("SwingWorker XChart Real-time Demo", "Time", "Value", "randomWalk", new double[] { 0 }, new double[] { 0 });
    chart.getStyler().setLegendVisible(false);
    chart.getStyler().setXAxisTicksVisible(false);

    // Show it
    sw = new SwingWrapper<XYChart>(chart);
    sw.displayChart();

    mySwingWorker = new MySwingWorker();
    mySwingWorker.execute();
  }

  private class MySwingWorker extends SwingWorker<Boolean, double[]> {

    LinkedList<Double> fifo = new LinkedList<Double>();

    public MySwingWorker() {

      fifo.add(0.0);
    }

    @Override
    protected Boolean doInBackground() throws Exception {

      while (!isCancelled()) {

        fifo.add(fifo.get(fifo.size() - 1) + Math.random() - .5);
        if (fifo.size() > 500) {
          fifo.removeFirst();
        }

        double[] array = new double[fifo.size()];
        for (int i = 0; i < fifo.size(); i++) {
          array[i] = fifo.get(i);
        }
        publish(array);

        try {
          Thread.sleep(5);
        } catch (InterruptedException e) {
          // eat it. caught when interrupt is called
          System.out.println("MySwingWorker shut down.");
        }

      }

      return true;
    }

    @Override
    protected void process(List<double[]> chunks) {

      System.out.println("number of chunks: " + chunks.size());

      double[] mostRecentDataSet = chunks.get(chunks.size() - 1);

      chart.updateXYSeries("randomWalk", null, mostRecentDataSet, null);
      sw.repaintChart();

      long start = System.currentTimeMillis();
      long duration = System.currentTimeMillis() - start;
      try {
        Thread.sleep(40 - duration); // 40 ms ==> 25fps
        // Thread.sleep(400 - duration); // 40 ms ==> 2.5fps
      } catch (InterruptedException e) {
      }

    }
  }
}

Gráfico de Java en tiempo real de XChart SwingWorker

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *