带孔数据的dygraph滚动平均值

时间:2014-08-01 20:47:41

标签: javascript dygraphs

Dygraphs选项提供' rollPeriod'支持滚动平均值和' stepPlot'支持步骤图。如果在两者之间缺少某些数据时设置在一起,则会产生非常意外的结果。例如,附加图像链接显示原始数据(rollPeriod = 1)和rollPeriod = 5的图形。 (http://imgur.com/a/9ajh8

例如,在40,000时,滚动平均值必须为零。但是,dygraphs平均最后5个数据点而不是最后5个

是否有可能获得维持时间概念而不是数据点的滚动平均值。提前谢谢!

PS-对不起图片链接。由于缺乏声誉,我不允许直接发布图片。 :(

2 个答案:

答案 0 :(得分:0)

正如您所注意到的,dygraphs平均最后五个数据点,而不是最后五秒。这就是它所能做的一切,因为它不知道你的数据的节奏。幸运的是,您可以通过添加显式缺失值来解决此问题:

Datetime,Value
2014-08-01 12:34:55,0
2014-08-01 12:34:56,
2014-08-01 12:34:57,0
2014-08-01 12:34:58,
2014-08-01 12:34:59,0

零是值,空白缺少值。

有关详细信息,请参阅http://dygraphs.com/data.html,或参阅these two个演示中的一个示例。

答案 1 :(得分:0)

由于缺乏此功能,我自己实现了它。我在这里把代码放在类似情况的人身上。代码在dygraph库和Queue.js中使用内部函数extractSeries_。请谨慎使用!

  function calcAvg_(minDate, maxDate, dispData){
    var windowSize = Math.round((maxDate-minDate)/100);
    if(windowSize <= 1){ 
        return dispData;
    }
    var energy = 0;
    var lastS = new Queue();

    var series = dispData;

    var lastAvg = 0;
    // Initially lastS elements are all 0
    // lastS shall always be maintained of windowSize.
    // Every enqueue after initialization in lastS shall be matched by a dequeue
    for(j=0; j<windowSize; j++){
        lastS.enqueue(0);
    }

    var avg_series = [];

    var prevTime = minDate - windowSize;
    var prevVal = 0;
    avg_series.push([prevTime, prevVal]);

    //console.log( "calcAvg_ min: " + minDate + " max: " + maxDate + " win: " + windowSize );
    for(j=0; j<series.length; j++){
        var time = series[j][0];
        var value = series[j].slice(1);
        if(time > minDate){
            var k = 0;
            while(k < windowSize && prevTime + k < time){
                var tail = lastS.dequeue();
                lastS.enqueue(prevVal);
                lastAvg = lastAvg + (prevVal - tail)/windowSize;
                avg_series.push([prevTime+k, lastAvg]);
                k++;
            }
        }
        prevTime = time;
        prevVal = value;
        if(time > maxDate){
            break;
        }
    }
    if(j == series.length){
        //console.log("Fix last value");
        var k = 0;
        while(k < windowSize && prevTime + k < maxDate){
            var tail = lastS.dequeue();
            lastS.enqueue(prevVal);
            lastAvg = lastAvg + (prevVal - tail)/windowSize;
            avg_series.push([prevTime+k, lastAvg]);
            k++;
        }
    }
    //console.log(avg_series);
    avg_series.push([maxDate, 0]);
    return avg_series;
  }

  var blockRedraw = false;
  myDrawCallback_ = function(gs, initial) {
    if (blockRedraw) return;
    blockRedraw = true;
    var range = gs.xAxisRange();
    var yrange = gs.yAxisRange();
    var series = calcAvg_(range[0], range[1], 
                    gs.extractSeries_(gs.rawData_, 0, false));
    gs.updateOptions( { 
        dateWindow: range, 
        valueRange: yrange, 
        file: series } );
    blockRedraw = false;
  }