title: d3.js moving average with previous and next data values
body: <p>I'm new to D3 and trying to do a moving average of previous and next values on my data in order to smooth it out.</p>
  
  <p>Currently, I have it working using the 2 previous values + the current value. It does work but 1) how would I also use the next values, and 2) what if I wanted to use the 15 previous and 15 next values? (it would be crazy to have 30 individual vars for storing all of them)</p>
  
  <p>I'm used to traditional javascript but lost as to how to traverse the data this way in D3.
  Hope someone can enlighten me, thanks.</p>
  
  <p>See the whole code on bl.ocks.org:
  <a href="http://bl.ocks.org/jcnesci/7439277" rel="nofollow">http://bl.ocks.org/jcnesci/7439277</a></p>
  
  <p>Or just the data parsing code here:</p>
  
  <pre><code>d3.json("by_date_mod.json", function(error, data) {
  
  // Setup each row of data by formatting the Date for X, and by converting to a number for Y.
  data = data.rows;
  data.forEach(function(d) {
    d.key = parseDate(String(d.key));
    d.value = +d.value;
  });
  
  x.domain(d3.extent(data, function(d) { return d.key; }));
  y.domain([0, d3.max(data, function(d) { return d.value; })]);
  
  // Setup the moving average calculation.
  // Currently is a hacky way of doing it by manually storing and using the previous 3 values for averaging.
  // Looking for another way to address previous values so we can make the averaging window much larger (like 15 previous values).
  var prevPrevVal = 0;
  var prevVal = 0;
  var curVal = 0
  var movingAverageLine = d3.svg.line()
  .x(function(d,i) { return x(d.key); })
  .y(function(d,i) {
      if (i == 0) {
          prevPrevVal  = y(d.value);
          prevVal = y(d.value);
          curVal =  y(d.value);
      } else if (i == 1) {
          prevPrevVal = prevVal;
          prevVal = curVal;
          curVal = (prevVal + y(d.value)) / 2.0;
      } else {
          prevPrevVal = prevVal;
          prevVal = curVal;
          curVal = (prevPrevVal + prevVal + y(d.value)) / 3.0;
      }
      return curVal;
  })
  .interpolate("basis");
  
  // Draw the moving average version of the data, as a line.
  graph1.append("path")
    .attr("class", "average")
    .attr("d", movingAverageLine(data));
  
  // Draw the raw data as an area.
  graph1.append("path")
      .datum(data)
      .attr("class", "area")
      .attr("d", area);
  
  // Draw the X-axis of the graph.
  graph1.append("g")
      .attr("class", "x axis")
      .attr("transform", "translate(0," + height + ")")
      .call(xAxis);
  
  // Draw the Y-axis of the graph.
  graph1.append("g")
      .attr("class", "y axis")
      .call(yAxis)
    .append("text")
      .attr("transform", "rotate(-90)")
      .attr("y", 6)
      .attr("dy", ".71em")
      .style("text-anchor", "end")
      .text("Value");
  });
  </code></pre>