2014-03-01 30 views
1

我建立不規則的時間曲線圖與HighCharts,在目前看起來像這樣:如何爲不規則時間圖創建平均線?

graph

我想知道,如果它可以創建三個一「平均」線(或可能更多未來)線路。

它會開始後的藍線,然後去接近綠線月中旬,等

目前我與看起來像工作代碼:

$('#chart').highcharts({ 
    chart: { type: 'spline' }, 
    title: { text: '' }, 
    xAxis: { type: 'datetime' }, 
    yAxis: { 
    title: { text: '' } 
    } 
    series: [{ 
    name: 'Line 1', 
    data: [ 
     [Date.UTC(2014,0,16), 173.33], 
     [Date.UTC(2014,0,23), 163.33], 
     [Date.UTC(2014,0,30), 137.67], 
     [Date.UTC(2014,1,6), 176.33], 
     [Date.UTC(2014,1,13), 178.67], 
     [Date.UTC(2014,1,27), 167.33], 
    ], 
    color: 'purple' 
    }, 
    { 
    name: 'Line 2', 
    data: [ 
     [Date.UTC(2014,0,11), 156.33], 
     [Date.UTC(2014,1,15), 167.67], 
    ], 
    color: 'green' 
    }, 
    { 
    name: 'Line 3', 
    data: [ 
     [Date.UTC(2014,0,1), 135], 
     [Date.UTC(2014,0,5), 146.33], 
     [Date.UTC(2014,0,27), 146.75], 
    ], 
    color: 'blue' 
    }] 
}); 

回答

2

根據從馬克的回答提供的想法,我寫了一些代碼來生成定製的第四線,採用從所有三行數據,並計算每個點所需的值。

我的新代碼如下:

line1 = [ 
    [Date.UTC(2014,0,16), 173.33], 
    [Date.UTC(2014,0,23), 163.33], 
    [Date.UTC(2014,0,30), 137.67], 
    [Date.UTC(2014,1,6), 176.33], 
    [Date.UTC(2014,1,13), 178.67], 
    [Date.UTC(2014,1,27), 167.33], 
    ]; 

    line2 = [ 
    [Date.UTC(2014,0,11), 156.33], 
    [Date.UTC(2014,1,15), 167.67], 
    ]; 

    line3 = [ 
    [Date.UTC(2014,0,1), 135], 
    [Date.UTC(2014,0,5), 146.33], 
    [Date.UTC(2014,0,27), 146.75], 
    [Date.UTC(2014,2,2), 168.75] 
    ]; 

    function average(array, index) { 
    sum = array[0][1]; 
    for(var i = 1; i <= index; i++) { 
     sum += array[i][1]; 
    } 

    value = sum/(index + 1); 
    return parseFloat(value.toFixed(2)); 
    } 

    // Make a fourth line with all of the data points for the other 
    // three lines, sorted by date  
    all_lines = line1.concat(line2).concat(line3); 
    all_lines.sort(function(a, b) { return a[0] - b[0]}); 

    // Calculate the value for each data point in the fourth line - 
    // the average of all the values before it 
    average_line = []; 
    for(var i = 0; i < all_lines.length; i++) { 
    average_line.push([all_lines[i][0], average(all_lines, i)]) 
    } 

    $('#chart').highcharts({ 
    chart: { type: 'spline' }, 
    title: { 
     text: '', 
    }, 
    xAxis: { 
     type: 'datetime' 
    }, 
    yAxis: { 
     title: { 
      text: '' 
     } 
    }, 
    legend: { 
     layout: 'vertical', 
     align: 'right', 
     verticalAlign: 'middle', 
     borderWidth: 0 
    }, 
    series: [{ 
     name: 'Line 1', 
     data: line1, 
     color: 'purple' 
    }, 
    { 
     name: 'Line 2', 
     data: line2, 
     color: 'green' 
    }, 
    { 
     name: 'Line 3', 
     data: line3, 
     color: 'blue' 
    }, 
    { 
     name: 'Average', 
     data: average_line, 
     color: 'red' 
    }] 
    }); 

,因爲它現在看起來(與藍線一個額外的數據點)圖爲:

enter image description here

7

什麼你所描述的名字叫做trend or regression line。 Highcharts沒有內置的添加這些線的能力,但是數學並不太難(此外,自己做這件事更有趣)。我編寫了最簡單的例子,我可以使用最小平方線性迴歸。

///////////////////// 
//utility functions// 
//////////////////// 
// linear regression 
// given array of x values and array of y values 
// returns rV object with slope/intercept 
lineFit = function(xs, ys, rV){ 
    rV.slope = 0.0; 
    rV.intercept = 0.0; 
    rV.rSquared = 1.0; // assume perfection 

    if (xs.length < 2) 
    { 
     return false; 
    } 

    if (xs.Count != ys.Count) 
    { 
     return false; 
    } 

    var N = xs.length; 
    var sumX = sumFunc(xs,null); 
    var sumY = sumFunc(ys,null); 
    var funcSq = function(i){return (i*i);} 
    var funcSq2 = function(i,j){return (i*j);} 
    var sumXx = sumFunc(xs, funcSq); 
    var sumYy = sumFunc(ys, funcSq); 
    var sumXy = sumFunc(zip(xs,ys),funcSq2); 

    rV.slope = ((N * sumXy) - (sumX * sumY))/(N * sumXx - (sumX*sumX)); 
    rV.intercept = (sumY - rV.slope * sumX)/N; 
    rV.rSquared = Math.abs((rV.slope * (sumXy - (sumX * sumY)/N))/(sumYy - ((sumY * sumY)/N))); 
    return true; 
} 

// sums arrays with optional function transformation 
sumFunc = function(arr, func){ 
    var total = 0; 
    $.each(arr, function(i,k){ 
     if ($.isArray(k)){ 
      if (func == null){ 
       k = k[0] + k[1]; 
      }else{     
       k = func(k[0],k[1]); 
      } 
     } else { 
      if (func != null){ 
       k = func(k); 
      } 
     } 
     total += k; 
    }); 
    return total; 
} 

// python style zip function 
// to pair to array together 
zip = function(arr1,arr2) { 
    var rV = []; 
    for(var i=0; i<arr1.length; i++){ 
     rV.push([arr1[i],arr2[i]]); 
    } 
    return rV; 
} 

lineFit函數將返回具有斜率和截距屬性的rV對象(通過引用)。在此之後,您可以添加一個線條,以老式的y = slope * x + intercept和minX爲迴歸線的起始值,maxX爲結束值。

{ 
    name: 'Regression Line', 
    data: [[minX, reg.slope * minX + reg.intercept], 
      [maxX, reg.slope * maxX + reg.intercept]], 
    color: 'red', 
    marker:{enabled:false}, 
    lineWidth: 5 
    } 

工作fiddle here

enter image description here

+0

我喜歡這個,但這不是我正在尋找的,我想要一段時間的平均水平。我很高興知道我可以很容易地將這些自定義的東西插入到Highcharts中 - 我可能必須將所有的點加在一起構成我自己的系列,然後在每個點上計算出新的平均值,並以此方式進行。 – sevenseacat