2012-08-15 34 views
7

Tìm cách vẽ cốt truyện/di chuyển trung bình trong d3 mà không phải thao tác dữ liệu trước. Vì vậy, tôi muốn làm mịn dòng bằng cách lấy trung bình mỗi điểm dữ liệu với hai điểm sau đó. Mã của tôi giống như thế nàyÂm mưu cán/di chuyển trung bình trong d3.js

var data = [3, 66, 2, 76, 5, 20, 1, 3, 8, 90, 2, 5, 70]; 

var w = 20, 
    h = 80; 

var x = d3.scale.linear() 
    .domain([0, 1]) 
    .range([0, w]); 
var y = d3.scale.linear() 
    .domain([0, 100]) 
    .rangeRound([h, 0]); 

var chart = d3.select("body").append("svg") 
    .attr("class", "chart") 
    .attr("width", w * data.length -1) 
    .attr("height", h); 

var line = d3.svg.line() 
    .x(function(d,i) { return x(i); }) 
    .y(function(d) { return y(d); }) 


var movingAverageLine = d3.svg.line() 
    .x(function(d,i) { return x(i); }) 
    .y(function(d) { return y(d); }) 

chart.append("svg:path").attr("d", line(data)); 
chart.append("svg:path").attr("d", movingAverageLine(data)); 

Tôi có thể chỉ định movingAverageLine để tính trung bình của các điểm dữ liệu sau không? Tôi không thể nghĩ ra cách để truy cập chúng trong hàm đó.

Tôi đã thiết lập một ví dụ về jsfiddle. http://jsfiddle.net/tjjjohnson/XXFrg/2/#run

Trả lời

0

Không chắc chắn những gì bạn có ý nghĩa bởi "cán trung bình", nhưng nếu bạn muốn chỉ có một dòng cho thấy giá trị trung bình của dữ liệu của bạn, đây là một cách tiếp cận:

chart.append("svg:line") 
    .attr("x1", x(0)) 
    .attr("x2", x(1)) 
    .attr("y1", d3.mean(data)) 
    .attr("y2", d3.mean(data)) 
    .style('stroke', 'blue') 
    .style('stroke-width', 1) 

Bạn có thể xem jsfiddle tại đây: http://jsfiddle.net/XXFrg/3/. Hy vọng rằng sẽ giúp,

+0

Edited câu hỏi để làm rõ một chút. Bằng cách "lăn", tôi có nghĩa là sử dụng trung bình một vài điểm vào mỗi ngày, ví dụ: trung bình ba ngày. Điều này là để mịn ra dòng. – tjjjohnson

+0

Tôi nghĩ bạn sẽ phải thay đổi dữ liệu - khi bạn chuyển mảng sang hàm d3, nó sẽ lặp qua 1 mục tại một thời điểm. Bất kỳ lý do bạn không thể chỉ tạo ra một mảng để vượt qua? – mike

+0

không có lý do tôi không thể sửa đổi dữ liệu, tôi chỉ tự hỏi nếu có một số khiếp sợ d3 awesomeness mà có thể làm điều đó tốt – tjjjohnson

2

Chức năng dòng sau đây sẽ làm những gì bạn muốn. Công thức dựa trên http://en.wikipedia.org/wiki/Moving_average#Cumulative_moving_average.

var _movingSum; 
var movingAverageLine = d3.svg.line() 
.x(function(d,i) { return x(i); }) 
.y(function(d,i) { 
    if (i == 0) { 
     return _movingSum = 0; 
    } else { 
     _movingSum += d; 
    } 
    return y(_movingSum/i); 
}) 
.interpolate("basis"); 

8

Một trước kết quả giải pháp trong một đường trung bình động tích lũy.

I modified the fiddle do John O'Connor để cung cấp một n-moving average bằng cách thông qua một chức năng tùy chỉnh nội suy để d3.svg.line():

movingAvg = function(n) { 
    return function (points) { 
     points = points.map(function(each, index, array) { 
      var to = index + n - 1; 
      var subSeq, sum; 
      if (to < points.length) { 
       subSeq = array.slice(index, to + 1); 
       sum = subSeq.reduce(function(a,b) { 
        return [a[0] + b[0], a[1] + b[1]]; 
       }); 
       return sum.map(function(each) { return each/n; }); 
      } 
      return undefined; 
     }); 
     points = points.filter(function(each) { return typeof each !== 'undefined' }) 
     // Note that one could re-interpolate the points 
     // to form a basis curve (I think...) 
     return points.join("L"); 
    } 
} 
var movingAverageLine = d3.svg.line() 
    .x(function(d,i) { return x(i); }) 
    .y(function(d,i) { return y(d); }) 
    .interpolate(movingAvg(6)); 
+0

Great làm việc ở đó. Tuy nhiên, tôi không thể làm cho nó hoạt động với một nội suy khác (như "đơn điệu"). Bất kỳ ý tưởng về làm thế nào để đi với điều đó? – Cystack

+0

@Cystack lưu ý fiddle được cập nhật: http://jsfiddle.net/plmrry/ktLtN/ –

+1

chào mọi người trong tương lai. đây là bản cập nhật cho d3 v4. xin cảm ơn người trả lời. http://stackoverflow.com/questions/41386083/plot-rolling-moving-average-in-d3-js-v4/41388581#41388581 – swyx