Javascript 如何为不规则时间图创建平均线?

Javascript 如何为不规则时间图创建平均线?,javascript,jquery,highcharts,Javascript,Jquery,Highcharts,我正在用高图构建不规则的时间图,目前看起来是这样的: 我想知道是否有可能为这三条线(或者将来可能更多)创建一条“平均”线 它将沿着蓝线开始,然后在一月中旬靠近绿线,等等 目前,我正在使用的代码如下所示: $('#chart').highcharts({ chart: { type: 'spline' }, title: { text: '' }, xAxis: { type: 'datetime' }, yAxis: { title: { text: '' } }

我正在用高图构建不规则的时间图,目前看起来是这样的:

我想知道是否有可能为这三条线(或者将来可能更多)创建一条“平均”线

它将沿着蓝线开始,然后在一月中旬靠近绿线,等等

目前,我正在使用的代码如下所示:

$('#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'
  }]
});

你所描述的被称为a。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;
}
工作


根据Mark提供的答案,我编写了一些代码来生成自定义的第四行,使用所有三行中的数据,并计算每个点所需的值

我的新代码如下:

  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'
    }]
  });
line1=[
[UTC日期(2014,0,16),173.33],
[UTC日期(2014,0,23),163.33],
[UTC日期(2014,0,30),137.67],
[UTC日期(2014年1月6日),176.33],
[UTC日期(2014年1月13日),178.67],
[UTC日期(2014年1月27日),167.33],
];
第2行=[
[UTC日期(2014,0,11),156.33],
[UTC日期(2014年1月15日),167.67],
];
第3行=[
[UTC日期(2014,0,1),135],
[UTC日期(2014,0,5),146.33],
[UTC日期(2014,0,27),146.75],
[UTC日期(2014年2月2日),168.75]
];
函数平均值(数组、索引){
总和=数组[0][1];

对于(var i=1;我喜欢这个,但它不是我想要的,我想要的是一段时间内的平均值。很高兴知道我可以很容易地将这些自定义的东西插入到Highcharts中-我可能需要通过将所有的点加在一起,然后在每个点计算出新的平均值来构建我自己的系列,然后这样做。
  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'
    }]
  });