block by enjalot 4562ac558aa8fb77269c

interviewing.io: mean lines

Full Screen

Built with blockbuilder.org

index.html

<!DOCTYPE html>
<head>
  <meta charset="utf-8">
  <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/d3-legend/1.8.0/d3-legend.min.js"></script>
  <style>
    body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
    svg { width:100%; height: 100% }
    
    path {
      fill: none;
      stroke-width: 3;
      stroke-opacity: 0.4;
    }
    line.legend {
      stroke: #c4c4c4;
      stroke-width: 1;
    }
    g.cell {
      cursor: pointer;
    }
  </style>
</head>

<body>
  <script>
    // Feel free to change or delete any of the code you see!
    var svg = d3.select("body").append("svg")
    .append("g").attr({
      transform: "translate(0, -70)"
    })
    d3.json("interviews.json", function(err, interviews) {
      console.log(interviews)
      var maxLength = d3.max(interviews, function(d) { return d.length });
      console.log("maxLength", maxLength)
      
      function ranges(mean) {
        if(mean <= 4 && mean >= 3.5) {
          return 4;
        } else if(mean < 3.5 && mean >= 2.75) {
          return 3;
        } else if(mean < 2.75) {
          return 2;
        }
      }
      
      var meanData = []     ; interviews.forEach(function(interview, index) {
        var mean = d3.mean(interview);
        var points = interview.map(function(score,i) {
          return {
            score: score,
            mean: mean,
            index: index
          }
        })
        points.mean = mean;
        points.index = index;
        meanData.push(points)
      })

      var xScale = d3.scale.linear()
      	.domain([0, maxLength])
        .range([50, 700])
      
      var yScale = d3.scale.linear()
      .domain([1, 4])
      .range([500, 100])
      
      var colorScale = d3.scale.linear()
      .domain([1, 2, 3, 4])
      .range(["#ff0f5f", "#e63ba8", "#ba48d9", "#267fd3"])
      
      var meanPath = d3.svg.line()
      .x(function(d,i) {
        return xScale(i);
      })
      .y(function(d,i) {
        return yScale(d.mean)
      })
      
      var fullPath = d3.svg.line()
      .x(function(d,i) {
        return xScale(i);
      })
      .y(function(d,i) {
        return yScale(d.score)
      })//.interpolate("basis")
      
      svg.append("g")
        .attr("class", "legendOrdinal")
        .attr("transform", "translate(50,100)");

      var legendScale = d3.scale.linear()
      .domain([4,3,2,1])
      .range(colorScale.range().reverse())
      var legendOrdinal = d3.legend.color()
        .shapeWidth(40)
        .shapeHeight(40)
        .shapePadding(94)
        .cells(4)
        .scale(legendScale);

      svg.select(".legendOrdinal")
        .call(legendOrdinal);
      
      var linesX = 100;
      var linesY = 113;
      svg.selectAll("line.legend").data(d3.range(4).reverse())
      .enter().append("line").classed("legend", true)
      .attr({
        x1: function(d) { return linesX + xScale.range()[0]},
        y1: function(d) { return yScale(d) - linesY},
        x2: function(d) { return linesX + xScale.range()[1]},
        y2: function(d) { return yScale(d) - linesY},
      })
      
      var meanLines = svg.selectAll("path.mean")
      	.data(meanData, function(d) { return d.index})
      meanLines.enter().append("path").classed("mean", true)
      
      
      meanLines.attr({
        d: function(d) { return meanPath(d) },
        stroke: function(d) { return colorScale(d.mean) },
        transform: function(d,i){ 
          return "translate(" + [150 + xScale(maxLength)/2 - xScale(d.length)/2, 20] + ")";
        }
      })
      
      var useMean = {};
      function normalize() {
        meanLines
        .transition()
        .attr({
          d: function(d) { return meanPath(d) },
          stroke: function(d) { return colorScale(d.mean) },
        })
      }
      
      
      d3.selection.prototype.moveToFront = function() {  
    	  return this.each(function(){
          this.parentNode.appendChild(this);
          });
      };
      
      
      legendOrdinal.on("cellclick", function(category) {
        useMean[category] = !useMean[category]
        d3.range(4).forEach(function(i) {
          if(i === category) return;
          useMean[i] = false;
        })
        if(!useMean[category]) {
          return normalize();
        }
        var select = svg.selectAll("path.mean").data(meanData, function(d) { return d.index})
        select
          .transition()
          .attr({
            d: function(d) { return meanPath(d)},
            stroke: function(d) { return "#ececec" },
          })
        
        select
        .filter(function(d) { 
          return ranges(d.mean) === category
          //return d.mean <= category + 0.75 && d.mean >= category - 0.25
        })
        .each(function() {
          d3.select(this).moveToFront();
        })
        .transition().duration(0)
        .attr({
          stroke: function(d) { return colorScale(d.mean) },
        })
        .transition()
        .duration(950)
        .delay(function(d,i) { return i * 80})
        .attr({
          d: function(d) { return fullPath(d); },
        })
      })
      
      
    })
  </script>
</body>

interviews.json

[[3,3,4],[3,3,3,3,3,3,4,3],[2,3,3,3,3],[3,3],[2,3,3],[4,2,4],[3,2,3,4,3,2],[3,2,4,3,2,3,2,3,4,3,3,2,4,3,4,4,3],[3,4,3,1,4,3,4,3],[4,4,3],[2,3,2],[3,3,4,3,3,4,4,2,3,4,4],[3,2,2],[2,1,3,3,2,3,2,3],[4,3,3,4,4,4],[3,4,4,3,3,3,4,3,4,2,4],[3,4,3,3,4],[3,2,3,3,2],[2,2,3,3,2,2,4,4,2,3,3],[3,3,4,3,4,4,4],[2,3],[3,3,2,3],[2,2],[3,3,3,3,3,3,2,3,3,3,4,3,2],[1,2,3,2,3,2],[1,3,3,2],[2,2,3,3],[4,3],[3,3],[3,2,2,2,3,3,3,2,2],[4,3,3],[4,3,4],[3,3,3,2,2,3,4],[3,3,4,3,2,4,4,3],[2,4,2,3],[3,4,3],[3,3,4,4,3,2,4],[4,4,4,4],[3,3,3],[4,4],[3,2,4,4,4],[3,4],[3,3,2],[4,4,4],[3,3,3,3,3,3],[3,2],[3,3,2],[3,3],[2,2,3,3,3],[3,4,3,3],[3,3],[2,2],[2,2],[3,4,3,3,3],[2,2],[3,4],[4,4,4,4,4],[4,3],[2,3],[2,2,3],[3,2,4],[2,4,3,3],[3,3],[3,3],[2,3],[4,3],[4,3]]