Javascript点数组如何进行曲线拟合?

Javascript array of points how to curve fit?

我有一个点数组,每个点由一个x和y组成,x是时间戳,y是实际数据。

我在 Javascript 中创建了一个时间序列图,我想对数据进行曲线拟合并绘制曲线。

谁能帮我实现这个目标?

我的积分榜:

    {fltX: 0, fltY: 55.932203389830505}
    {fltX: 1.8237082066869301, fltY: 55.932203389830505}
    {fltX: 3.6474164133738602, fltY: 55.932203389830505}
    {fltX: 5.47112462006079, fltY: 55.932203389830505}
    {fltX: 7.2948328267477205, fltY: 81.35593220338983}

X坐标已经缩放到X轴。我不是在找人为我编写代码,但是非常感谢一个好的教程或指南。

您可能对 genetic-js 感兴趣。从项目页面引用:

From a plot of vertices, this genetic algorithm optimizes a continious function to best fit the data (aka least squared error). Genetic.js automatically runs the algorithm in the background with web workers so that the UI experience isn't compromised.

提供了详细示例here

HTML5 canvas 可能会满足您的需求:

Javascript:

var hpms = {};

hpms.Graph = function( canvasId ) {
   this.MARGIN  = 30;
   this.canvas  = document.getElementById( canvasId );
   this.ctx     = this.canvas.getContext("2d");
   this.offsetY = this.canvas.height - this.MARGIN;
};

hpms.Graph.prototype.drawAxis = function( canvas ) {
   this.ctx.beginPath();
   this.ctx.moveTo( 0                , this.offsetY );
   this.ctx.lineTo( this.canvas.width, this.offsetY );
   this.ctx.moveTo( this.MARGIN, this.canvas.height );
   this.ctx.lineTo( this.MARGIN, 0 );

   var dx     = ( this.canvas.width - 2*this.MARGIN ) / 3;
   var yText  = this.offsetY + 3*this.MARGIN/4;

   var x      = this.MARGIN + dx;
   var legend = "1 year";
   this.ctx.moveTo( x, 0 );
   this.ctx.lineTo( x, this.offsetY + this.MARGIN/2 );
   x -= this.ctx.measureText( legend ).width/2;
   this.ctx.strokeText( legend, x, yText );

   x = this.MARGIN + 2*dx;
   this.ctx.moveTo( x, 0 );
   this.ctx.lineTo( x, this.offsetY + this.MARGIN/2 );
   legend = "2 years";
   x -= this.ctx.measureText( legend ).width/2;
   this.ctx.strokeText( legend, x, yText );

   x = this.MARGIN + 3*dx;
   this.ctx.moveTo( x, 0 );
   this.ctx.lineTo( x, this.offsetY + this.MARGIN/2 );
   legend = "3 years";
   x -= this.ctx.measureText( legend ).width/2;
   this.ctx.strokeText( legend, x, yText );

   var dy = 4;
   for( var y = 0; y < this.offsetY; y += 100 ) {
      this.ctx.moveTo( this.MARGIN/2    , this.offsetY - y );
      this.ctx.lineTo( this.canvas.width, this.offsetY - y );
      legend = "" + y;
      this.ctx.strokeText( legend, 0, this.offsetY - y + dy );
   }

   this.ctx.closePath();
   this.ctx.lineCap     = "round";
   this.ctx.lineWidth   = 1;
   this.ctx.strokeStyle = "lightgray";
   this.ctx.stroke();
};

hpms.Graph.prototype.drawLinear = function( fn, color ) {
   this.ctx.beginPath();
   this.ctx.strokeStyle = color;
   this.ctx.lineWidth   = 5;
   this.ctx.moveTo( this.MARGIN, this.offsetY - fn.b );
   var x = this.canvas.width - 2*this.MARGIN;
   var y = fn.a*x + fn.b;
   this.ctx.lineTo( this.MARGIN + x, this.offsetY - y );
   this.ctx.closePath();
   this.ctx.stroke();
}

function draw() {
   var g = new hpms.Graph("canvas");
   g.drawAxis  ();
   g.drawLinear({a:0.25, b:200}, "darkgray");
   g.drawLinear({a:0.80, b: 30}, "rgb(16,65,96)");
}

HTML:

<!doctype html>
<html lang="en-US">
<head>
    <meta charset="UTF-8" />
    <title>Canvas</title>
    <script type="text/javascript" src="canvas.js"></script>
</head>
<body>
   <canvas id="canvas" width="1000" height="400"></canvas>
    <script type="text/javascript">
        draw();
    </script>
</body>
</html>