Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I'm building irregular time graphs with HighCharts that at the moment look like so:

graph

And I'm wondering if it's possible to create an 'average' line for the three (or possibly more in future) lines.

It would start following the blue line, then go closer to the green line mid-January, etc.

At the moment the code I'm working with looks like:

$('#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'
  }]
});
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
210 views
Welcome To Ask or Share your Answers For Others

1 Answer

What you are describing is called a trend or regression line. Highcharts doesn't have a built in ability to add these lines, but the math isn't too difficult (and besides, it's more fun to do it yourself). I've coded up the simplest example I can using least squared linear regression.

/////////////////////
//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;
}

The lineFit function will return the rV object (by reference) with attributes of slope and intercept. After that you can add a line to Highcharts with good old fashioned y = slope * x + intercept and minX is the starting value for the regression line and maxX is the ending value.

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

Working fiddle here.

enter image description here


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share

548k questions

547k answers

4 comments

86.3k users

...