2014-01-23 7 views
2

에 표시된 실시간으로 TimeSeries 차트의 실시간 데이터를 표시하려고합니다 (또는 적어도 시간은 실시간과 동일).JFreeChart - TimeSeries 차트의 X 축에서 실시간을 표시하는 방법

다음은 실제 입력과 같은 난수 문제에 대한 SSCCE입니다. 그것은 initial threadsleep()을 허용하면서 스윙 GUI 객체한다

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

답변

4

: X 축에 표시된 시간은 실시간 (: MM : SS 포맷이 HH에 도시 가정)보다 훨씬 빠르다 이벤트 발송 스레드에서 으로 생성되고 조작되어야합니다. 대신, here처럼 javax.swing.Timer을 사용하여 업데이트 속도를 조정하십시오.은 100 ms가 약 10 Hz로 업데이트됩니다.

드리프트가 허용되지 않는 경우 명목상 속도의 절반으로 다른 스레드에서 호스트의 클록을 폴링하고 EventQueue.invokeLater()을 사용하여 데이터 세트를 업데이트하십시오. 호스트가 NTP 서버와 동기화되었는지 확인하십시오.

부록 : 당신의 갱신을 바탕으로, 모든 스윙 GUI 개체를 구성하고 이벤트 발송 쓰레드상에서 뿐 아니라 javax.swing.Timer를 조작 할 수 있어야합니다. 스윙 Timer의 장점은 EDT에서 발생한다는 것입니다. 아래의 변형은 거의 실시간으로 1 Hz 데이터의 10 초를 보여줍니다.

부록 : setTimeBase()에 전달 된 시간을 here과 같이 조정할 수 있습니다. 난 당신이 타이머 및 EventQueue.invokeLater()로 무엇을 제안 사용하는 SSCCE 코드를 변경 한

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); 
      } 
     }); 
    } 
} 
+0

image

. 그래도 문제는 여전히 남아 있습니다. 호스트의 시계를 폴링하는 방법이나 호스트가 NTP 서버와 동기화되는지 확인하지 않습니다. 나는 차트의 시간을 정하는 방법을 모른다. –

+0

추가 정보에 대한 설명 : 예제 차트는 실시간 속도로 시간이 표시되는 것처럼 보이지만 타이머 속도를 1Hz 이외의 값으로 변경하면 차트에 다른 속도로 시간이 표시됩니다. 차트에서 데이터 업데이트 속도에 관계없이 실제 속도로 시간을 표시 할 수있게하려고합니다. 지금까지 귀하의 노력에 감사드립니다. –

+0

실시간은 1Hz입니다. 다른 속도로 도착하는 이벤트를 병합 할 수 있습니다. – trashgod