block by HarryStevens 4f21797e13c4dcb6baf39bd16d7b648d

The Wave

Full Screen

A somewhat unusual bar chart.

index.html

<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
      
    <style>
      body {
        margin: 0 auto;
      }
      .label {
        fill: #fff;
        text-anchor: middle;
        font-family: "Helvetica Neue", sans-serif;
        font-size: .8em;
      }
    </style>
  </head>
  <body>
    <script src="https://d3js.org/d3.v4.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/chroma-js/1.3.4/chroma.min.js"></script>
    <script>
      var alpha = "abcdefghijklmnopqrstuvwxyz".split(""),
        odd = true,
        interval = 300,
        y_max = 2;

      var margin = {top: 0, bottom: 20, left: 0, right: 1},
        width = window.innerWidth - margin.left - margin.right,
        height = window.innerHeight - margin.top - margin.bottom,
        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 x = d3.scaleBand()
          .rangeRound([0, width])
          .domain(alpha)
          .padding(.2);

      var y = d3.scaleLinear()
          .range([height, 0])
          .domain([0, y_max]);

      var c = chroma.scale(["steelblue", "violet", "tomato"]).domain([1, y_max]);

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

      redraw(makeData());

      d3.interval(function(){
        redraw(makeData());  
      }, interval);

      function redraw(data){

        var bar = svg.selectAll(".bar")
            .data(data, function(d){ return d.name; });

        var label = svg.selectAll(".label")
            .data(data, function(d){ return d.name; });

        bar.transition().delay(calcDelay)
            .attr("y", calcY)
            .attr("height", calcHeight)
            .style("fill", function(d){ return c(d.value); });

        label.transition().delay(calcDelay)
            .attr("y", calcY)
            .text(function(d){ return d.value; });

        bar.enter().append("rect")
            .attr("class", "bar")
            .attr("x", function(d){ return x(d.name); })
            .attr("width", x.bandwidth())
            .attr("y", calcY)
            .attr("height", calcHeight)
            .style("fill", function(d){ return c(d.value); })

        label.enter().append("text")
            .attr("class", "label")
            .attr("x", function(d){ return x(d.name) + x.bandwidth() / 2; })
            .attr("y", calcY)
            .attr("dy", 18)
            .text(function(d){ return d.value; });

        function calcY(d){
          return y(d.value);
        }
        function calcHeight(d){
          return height - y(d.value);
        }
        function calcDelay(d, i){
          return i * interval * 4 / data.length;
        }

      }

      function makeData(){
        odd = odd ? false : true;
        return alpha.map(function(d, i){
          return {
            name: d,
            value: odd ? +((alpha.length - i) / (alpha.length / y_max)).toFixed(2) : +((i + 1) / (alpha.length / y_max)).toFixed(2)
          }
        });
      }      
    </script>
  </body>
</html>