block by harrystevens 974ee8aadb9d1676d62202ef5e367577

Joyplot Update Pattern II

Full Screen

Another updating joyplot, this one with labels and an axis and some more reasonable design decisions. See also Joyplot Update Pattern.

index.html

<!DOCTYPE html>
<html>
<head>
  <style>
    body {
      margin: 0;
      font-family: "Helvetica Neue", sans-serif;
    }
    .area {
      fill: steelblue;
      stroke: #fff;
    }
    .area:nth-child(odd){
      fill: lightskyblue;
    }
    .line {
      fill: #fff;
    }
    .baseline {
      stroke: #000;
      shape-rendering: crispEdges;
    }
    .baseline:last-of-type {
      display: none;
    }
    .line-label {
      text-anchor: end;
      font-size: .8em;
    }
    .line-label:nth-child(odd){
      fill: #888;
    }
  </style>
</head>
<body>
  <script src="https://d3js.org/d3.v4.min.js"></script>
  <script src="https://unpkg.com/jeezy@1.11.0/lib/jeezy.min.js"></script>
  <script>

  var alpha = "Annie,Bob,Christina,Dylan,Elizabeth,Fred,Gertrude,Isaiah,Jennifer".split(",");

  var margin = {top: 50, left: 75, bottom: 50, right: 10}, width = window.innerWidth - margin.right - margin.left, height = window.innerHeight - margin.top - margin.bottom;

  var svg = d3.select("body").append("svg")
      .attr("width", width + margin.left + margin.right)
      .attr("height", height + margin.top + margin.bottom)
    .append("g")
      .attr("transform", "translate(" + margin.left + ", " + margin.top + ")");

  var y_wrapper = d3.scaleBand()
      .rangeRound([0, height])
      .domain(alpha);

  var y = d3.scaleLinear()
      .range([y_wrapper.bandwidth(), 0])
      .domain([0, 100]);

  var x = d3.scaleLinear()
      .range([0, width])
      .domain([0, 100]);

  var area = d3.area()
      .x(function(d){ return x(d.day); })
      .y1(function(d) { return y(d.value * 2); })
      .y0(y(0))
      .curve(d3.curveBasis);

  svg.append("g")
    .attr("class", "axis x")
    .attr("transform", "translate(0, " + (height - 2) + ")")
    .call(d3.axisBottom(x))
  
  drawChart(makeData());

  d3.interval(function(){drawChart(makeData())}, 1000);

  function drawChart(data){

    // labels
    svg.selectAll(".line-label")
        .data(data, function(d){ return d.id; })
      .enter().append("text")
        .attr("class", "line-label")
        .attr("x", -5)
        .attr("y", function(d) { return y_wrapper(d.id) + y_wrapper.bandwidth() - 3; })
        .text(function(d){ return d.id; });

    // baselines
    svg.selectAll(".baseline")
        .data(data, function(d){ return d.id; })
      .enter().append("line")
        .attr("class", "baseline")
        .attr("x1", 0)
        .attr("x2", width)
        .attr("y1", function(d) { return y_wrapper(d.id) + y_wrapper.bandwidth(); })
        .attr("y2", function(d) { return y_wrapper(d.id) + y_wrapper.bandwidth(); });

    // JOIN
    var area_path = svg.selectAll(".area")
        .data(data, function(d){ return d.id; });

    // UDATE
    area_path
      .transition()
        .attr("d", function(d){ return area(d.data); });
    
    // ENTER
    area_path.enter().append("path")
        .attr("class", "area")
        .attr("transform", function(d) { return "translate(0, " + (y_wrapper(d.id) - 1.5) + ")"; })
        .attr("d", function(d){ return area(d.data); });

  }

  function makeData(){
    return alpha.map(function(letter){
      var arr = [];
      for (var i = 0; i <= 100; i++){
        arr.push({day: i, value: jz.num.randBetween(10, 90)})
      }
      return {
        id: letter,
        data: arr
      }
    });
  }

  </script>

</body>
</html>