block by curran af72fd9c1fb61d2133d273cd8a3ca557

Reusable Bar Chart

Full Screen

A pseudo-bar chart demonstrating conventional margins with the D3 Towards Reusable Charts pattern. Uses:

Built with blockbuilder.org

forked from curran‘s block: Pseudo Bar Chart V

forked from curran‘s block: Pseudo Bar Chart VI

index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Pseudo Bar Chart IV</title>
    <script src="https://d3js.org/d3.v4.min.js"></script>
    <style>
      body {
        margin: 0;
      }
    </style>
  </head>
  <body>
    <svg id="bar-chart"></svg>
    <script>
      
      function BarChart(){
        var width,
            height,
            xScale = d3.scaleBand(),
            yScale = d3.scaleLinear(),
            x,
            y,
            margin = { top: 15, bottom: 20, left: 30, right: 20 },
            xAxis = d3.axisBottom(xScale),
            yAxis = d3.axisLeft(yScale);
            
        function my(selection){
          
          if(!x) throw new Error("Bar Chart x column must be defined.");
          if(!y) throw new Error("Bar Chart y column must be defined.");
          if(!width) throw new Error("Bar Chart width must be defined.");
          if(!height) throw new Error("Bar Chart height must be defined.");
          
          selection.each(function(data) {
            
            var svg = d3.select(this)
                .attr("width", width)
                .attr("height", height);
            
            var g = svg.selectAll("g")
              .data([1]);
            g = g.enter().append("g")
              .merge(g)
                .attr("transform",
                      "translate(" + margin.left + "," + margin.top +")");
            
            var innerWidth = width - margin.left - margin.right;
            var innerHeight = height - margin.top - margin.bottom;
        
            xScale
              .domain(data.map(function (d){ return d[x]; }))
              .range([0, innerWidth]);
            
            yScale
              .domain([0, d3.max(data, function (d){ return d[y] })])
              .range([innerHeight, 0]);
            
            var xAxisG = g.selectAll(".x-axis").data([1]);
            xAxisG.enter().append("g")
                .attr("class", "x-axis")
              .merge(xAxisG)
                .attr("transform", "translate(0," + innerHeight +")")
                .call(xAxis);
            
            var yAxisG = g.selectAll(".y-axis").data([1]);
            yAxisG.enter().append("g")
                .attr("class", "y-axis")
              .merge(yAxisG)
                .call(yAxis);
            
            var rects = g.selectAll("rect")
              .data(data);
            rects.exit().remove();
            rects.enter().append("rect")
              .merge(rects)
                .attr("x", function (d){ return xScale(d[x]); })
                .attr("y", function (d){ return yScale(d[y]); })
                .attr("width", xScale.bandwidth())
                .attr("height", function (d){
                  return innerHeight - yScale(d[y]);
                });
          });
        }
        
        my.x = function (_){
          return arguments.length ? (x = _, my) : x;
        };
        
        my.y = function (_){
          return arguments.length ? (y = _, my) : y;
        };
        
        my.width = function (_){
          return arguments.length ? (width = _, my) : width;
        };
        
        my.height = function (_){
          return arguments.length ? (height = _, my) : height;
        };
        
        my.padding = function (_){
          return arguments.length ? (xScale.padding(_), my) : xScale.padding();
        };

        return my;
      }
      
      function main(){

        var barChart = BarChart()
          .width(960)
          .height(500)
          .x("name")
          .y("value")
          .padding(0.1);

        function parseRow(d){
          d.value = +d.value; // Parses String to Number.
          return d;
        }

        d3.csv("data.csv", parseRow, function (data){
          
          d3.select("#bar-chart")
            .datum(data)
            .call(barChart);
          
          setInterval(function (){
            d3.select("#bar-chart")
              .datum(data.filter(function (d, i){
                return Math.random() < 0.8;
              }))
              .call(barChart);
          }, 1000);
        });
      }
      main();
    </script>
  </body>
</html>

data.csv

name,value
A,5
B,4
C,3
D,2
E,1