<!DOCTYPE html> <html> <head> <script data-require=" d3@4.0.0 " data-semver="4.0.0" src="https://d3js.org/d3.v4.min.js"></script> <script> function NMoveAvg(context, N) { this._context = context; this._points = { x: [], y: [] }; this._N = N; } NMoveAvg.prototype = { areaStart: function() { this._line = 0; }, areaEnd: function() { this._line = NaN; }, lineStart: function() { this._point = 0; }, lineEnd: function() { if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath(); this._line = 1 - this._line; }, point: function(x, y) { x = +x, y = +y; this._points.x.push(x); this._points.y.push(y); if (this._points.x.length < this._N) return; var aX = this._points.x.reduce(function(a, b) { return a + b; }, 0) / this._N, aY = this._points.y.reduce(function(a, b) { return a + b; }, 0) / this._N; this._points.x.shift(); this._points.y.shift(); switch (this._point) { case 0: this._point = 1; this._line ? this._context.lineTo(aX, aY) : this._context.moveTo(aX, aY); break; case 1: this._point = 2; </script> </head> <body> <script> var data = [3, 66, 2, 76, 5, 20, 1, 30, 50, 9, 80, 5, 7]; var w = 500, h = 500; var x = d3.scaleLinear() .domain([0, 12]) .range([0, w]); var y = d3.scaleLinear() .domain([0, 100]) .range([0, h]); var svg = d3.select("body") .append("svg") .attr("width", w) .attr("height", h); var line = d3.line() .x(function(d, i) { return x(i); }) .y(function(d, i) { return y(d); }); svg.append("path") .datum(data) .attr("d", line.curve(curveNMoveAge.N(3))) .style("fill", "none") .style("stroke", "steelblue"); svg.append("path") .datum(data) .attr("d", line.curve(d3.curveLinear)) .style("fill", "none") .style("stroke", "black"); </script> </body> </html>