JFreeChart:DynamicTimeSeries,周期为n毫秒

时间:2011-07-28 09:45:41

标签: java jfreechart

我正在尝试定义一个接口,我想在其中绘制外部设备接收的一些值。 接收这些值的频率可以通过接口设置。当然,绘图的周期应该根据用户定义的周期而改变。 所以我开始定义followint图表:

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是以下类,如建议的here

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 个答案:

答案 0 :(得分:4)

我想因为你有这个:

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];

答案 1 :(得分:2)

这是我实施的解决方案。 我只报告了我改变的方法。这是一个愚蠢的错误: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;

  } 
}

现在我在5秒内有10个样本,我将周期设置为500毫秒

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

答案 2 :(得分:1)

相反,请使用原始的MilliDTSC&amp; Millisecond,并在附加新数据之前调用advanceTime()并根据需要附加旧数据。以200 ms为例,做一下这样的事情:

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