JFreeChart: DynamicTimeSeries с периодом n миллисекунд - PullRequest
2 голосов
/ 28 июля 2011

Я пытаюсь определить интерфейс, в котором я хочу отобразить некоторые значения, полученные внешним устройством.Эти значения принимаются с частотой, которая может быть установлена ​​через интерфейс.Конечно, период сюжета должен меняться в зависимости от периода, определенного пользователем.Поэтому я начал определять следующую диаграмму:

int periodMs = 200;
MilliDTSC dataset = new MilliDTSC(1,100, new MultipleOfMillisecond(periodMs));
dataset.setTimeBase(new MultipleOfMillisecond(periodMs))
dataset.addSeries(zeroSeries()),0,"Zero data") // zeroSeries returs a series with values set to 0
JFreeChart chart = createChart(dataset) // create the chart and set ranges and legends
ChartPanel panel = new ChartPanel(panel);

MilliDTSC - следующий класс, как предлагается здесь :

public class MilliDTSC extends DynamicTimeSeriesCollection{
  public MilliDTSC(int nSeries, int nMoments, RegularTimePeriod timeSample){
    super(nSeries, nMoments, timeSample);
    if(timeSample instanceof Millisecond)
      this.pointsInTime = new Millisecond[nMoments]
    else if (timeSample instanceof MultipleOfMillisecond)
      this.pointsInTime = new MultipleOfMillisecond[nMoments]
  }
}

MultipleOfMillisecond - этоследующий класс:

public class MultipleOfMilliseconds extends Millisecond{
  MulitpleOfMilliseconds(int periodMs){
    this.periodMs = periodMs
  }

  public RegularTimePeriod previous(){
    RegularTimePeriod result = null;
    if(getMillisecond() - periodMs >= FIRST_MILLISECOND_IN_SECOND)
      result = new Millisecond((int)getMillisecond - periodMs, getSecond());
    else{
      Second previous = (Second)getSecond().previous();
      if(previous!=null)
        result = new Millisecond((int)(getMillisecond() - periodMS + LAST_MILLISECOND_IN_SECOND + 1), previous);
    }
    return result;
  }
  // similar for next()
}

Я добавляю выборку в серию следующим образом:

dataset.advanceTime();
dataset.appendData(newData);

Я ожидал, что после того, как я установил период в 200 мс, график отобразит отчетX обозначает более или менее 5 значений времени:

00:00:00.000 00:00:05.000 00:00:10.000 00:00:15.000 00:00:20.000

И я ожидал 25 выборок в каждом «пространстве».

Вместо этого у меня есть 25 выборок для каждого «пространства», нодиаграмма показывает следующие значения на метке X:

00:00:00.000 00:00:00.025 00:00:00.050 00:00:00.075 00:00:00.100

Кажется, что период составляет 1 мс, но я добавляю выборки очень 200 мс.

Как я могу решить проблему?Если мне было непонятно, пожалуйста, скажите мне.Спасибо !!

Ответы [ 3 ]

4 голосов
/ 28 июля 2011

Я думаю, потому что у вас есть это:

public class MultipleOfMilliseconds extends Millisecond
//                                          ^^^^^^^^^^^

это true:

if(timeSample instanceof Millisecond)

Если вы измените порядок тестов, вам повезет больше:*

if(timeSample instanceof MultipleOfMillisecond)
  this.pointsInTime = new MultipleOfMillisecond[nMoments];
else if (timeSample instanceof Millisecond)
  this.pointsInTime = new Millisecond[nMoments];
2 голосов
/ 28 июля 2011

Это решение, которое я реализовал.Я сообщил только методы, которые я изменил.Это была глупая ошибка: D

public MilliDTSC(int nSeries, int nMoments, RegularTimePeriod timeSample) {
  super(nSeries, nMoments, timeSample);
  if(timeSample instanceof MultipleOfMillisecond){
    this.pointsInTime = new MultipleOfMillisecond[nMoments];
  }else if (timeSample instanceof Millisecond) {
    this.pointsInTime = new Millisecond[nMoments];
  } 
}

public class MultipleOfMillisecond extends Millisecond {

  private static final long serialVersionUID = 1L;
  private int periodMs = 100;

  public MultipleOfMillisecond(int periodMs){
    super();
    this.periodMs = periodMs;
  }

  public MultipleOfMillisecond(int periodMs, int millisecond, Second second){
    super(millisecond, second);
    this.periodMs = periodMs;
  }

  @Override
  public RegularTimePeriod next() {

    RegularTimePeriod result = null;
    if(getMillisecond() + periodMs <= LAST_MILLISECOND_IN_SECOND){
        result = new MultipleOfMillisecond( periodMs, (int)(getMillisecond() + periodMs), getSecond());
    }else{
        Second next = (Second)getSecond().next();
        if(next != null){
            result = new MultipleOfMillisecond(periodMs, (int)(getMillisecond() + periodMs - LAST_MILLISECOND_IN_SECOND - 1), next);
        }
    }
    return result;

  }

  @Override
  public RegularTimePeriod previous() {

    RegularTimePeriod result = null;
    if(getMillisecond() - periodMs >= FIRST_MILLISECOND_IN_SECOND){
        result = new MultipleOfMillisecond(periodMs, (int)getMillisecond() - periodMs, getSecond());
    }else{
        Second previous = (Second)getSecond().previous();
        if(previous != null){
            result = new MultipleOfMillisecond(periodMs, (int)(getMillisecond() - periodMs + LAST_MILLISECOND_IN_SECOND + 1), previous);
        }
    }
    return result;

  } 
}

Теперь у меня есть 10 выборок за 5 секунд, я установил период на 500 мс

Now I have 10 samples in 5 seconds, i set the period to 500 ms

1 голос
/ 28 июля 2011

Вместо этого используйте исходные MilliDTSC & Millisecond, и вызовите advanceTime() и добавьте старые данные, как требуется, перед добавлением новых данных. Используя 200 мс в качестве примера, сделайте что-то вроде этого:

float[] newData = new float[1];
float[] oldData = new float[1];

@Override
public void actionPerformed(ActionEvent e) {
    newData[0] = randomValue();
    oldData[0] = newData[0];
    for (int i = 0; i < 200; i++) {
        dataset.advanceTime();
        dataset.appendData(oldData);
    }
    dataset.appendData(newData);
}

Обратите внимание, что теперь есть 5 выборок в секунду, с интервалом 200 мсек.

enter image description here

...