riccardoscalco
6/8/2015 - 3:09 PM

Area chart with a closed line.

Area chart with a closed line.

.line {
  fill: none;
  stroke: #333;
  stroke-width: 1px;
  shape-rendering: crispEdges;
}
(function () {

  var margin = {top: 40, right: 40, bottom: 40, left: 40},
      width = 500 - margin.left - margin.right,
      height = 500 - margin.top - margin.bottom;
  
  // box 1
  
  var svg1 = d3.select("#box1").append("svg")
      .attr("id","box1SVG")
      .attr("viewBox", "0 0 500 500")
      .attr("preserveAspectRatio", "xMidYMid")
      .attr("width", width + margin.left + margin.right)
      .attr("height", height + margin.top + margin.bottom)
    .append("g")
      .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
  
  var c1 = {};
  var g1 = svg1.append("g");
  
  c1.xScale = d3.scale.ordinal()
        .domain(["06","07","08","09","10","11","12","13","14"])
        .rangeRoundBands([0, width - margin.left - margin.right],0,0);

  c1.yScale = d3.scale.linear()
        .range([height / 2, 0]);
  
  c1.line = d3.svg.line();
        
  c1.path = g1.append("path")
        .attr("class","line");
  
  c1.dataLine = function(data, x, y) {
    var h, new_data, s;
    s = x.range()[1] - x.range()[0];
    h = y.range()[0];
    new_data = data.reduce(function(dd, d, i) {
      return dd.concat([[i * s, y(d.total)], [(i + 1) * s, y(d.total)]]);
    }, [[0, h]]);
    return new_data.concat([[(new_data.length - 1)/2 * s, h]]);
  };
  
  // update
  
  update = function(data) {
    
    c1.yScale
        .domain([0,d3.max(data, function(d) { return d.total })]);

    c1.path
        .datum(c1.dataLine(data,c1.xScale,c1.yScale))
        .attr("d", function(d) { return c1.line(d) + "Z"; }); 
   
  }
  
  update(getRandomData());
  
  d3.select("button")
      .on("click",function(){
    var data = getRandomData();
    update(data);
  });

  function getRandomInt(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
  }

  function getRandomArbitrary(min, max) {
      return Math.random() * (max - min) + min;
  }

  function getRandomData() {
    return [
      {
        "year": "06",
        "total": getRandomInt(0, 100),
        "ratio": getRandomArbitrary(0.3, 0.9)
      },
      {
        "year": "07",
        "total": getRandomInt(0, 100),
        "ratio": getRandomArbitrary(0.3, 0.9)
      },
      {
        "year": "08",
        "total": getRandomInt(0, 100),
        "ratio": getRandomArbitrary(0.3, 0.9)
      },
      {
        "year": "09",
        "total": getRandomInt(0, 100),
        "ratio": getRandomArbitrary(0.3, 0.9)
      },
      {
        "year": "10",
        "total": getRandomInt(0, 100),
        "ratio": getRandomArbitrary(0.3, 0.9)
      },
      {
        "year": "11",
        "total": getRandomInt(0, 100),
        "ratio": getRandomArbitrary(0.3, 0.9)
      },
      {
        "year": "12",
        "total": getRandomInt(0, 100),
        "ratio": getRandomArbitrary(0.3, 0.9)
      },
      {
        "year": "13",
        "total": getRandomInt(0, 100),
        "ratio": getRandomArbitrary(0.3, 0.9)
      }
    ];
  }
  
})()
<button>update</button>
<div id="box1"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>

Area chart with a closed line.

I am pretty sure there is a better way to do the same.

A Pen by Riccardo Scalco on CodePen.

License.