block by curran 40f0f319001394b5f8af

Lynchings by State Pie Charts

Full Screen

A small multiples visualization of pie charts showing the proportion and total number of lynchings by US State and by Race from 1882-1968. Area of the pie slices corresponds to the number of people lynched. The data from the Archives at Tuskegee Institute.

Inspired by

forked from curran‘s block: Lynchings by State Pie Charts First Attempt

web counter

index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>D3 Example</title>
    <script src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/d3-legend/1.1.0/d3-legend.js"></script>
    <link href='https://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'>
    <style>
    
      .axis text {
        font-family: 'Open Sans', sans-serif;
        font-size: 12pt;
      }

      .axis path, .axis line {
        fill: none;
        stroke: none;
      }

      .color-legend text {
        font-family: 'Open Sans', sans-serif;
        font-size: 12pt;
      }

    </style>
  </head>
  <body>
    <script>

      var outerWidth = 960;
      var outerHeight = 500;
      var margin = { left: 153, top: 1, right: 23, bottom: 1 };

      var yColumn = "state";
      var xColumn = "group";
      var colorColumn = "race";
      var areaColumn = "lynchings";
      var radiusMax = 57;
      var numGroups = 6;

      var innerWidth  = outerWidth  - margin.left - margin.right;
      var innerHeight = outerHeight - margin.top  - margin.bottom;

      var svg = d3.select("body").append("svg")
        .attr("width",  outerWidth)
        .attr("height", outerHeight);
      var g = svg.append("g")
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
      
      var colorLegendG = svg.append("g")
        .attr("class", "color-legend")
        .attr("transform", "translate(24, 224)");

      var yScale = d3.scale.ordinal().rangePoints([0, innerHeight], 1);
      
      var radiusScale = d3.scale.sqrt().range([0, radiusMax]);
      var colorScale = d3.scale.ordinal()
        .range(["#ffcda8", "#a35400"]);

      var yAxis = d3.svg.axis().scale(yScale).orient("left");

      var pie = d3.layout.pie();
      var arc = d3.svg.arc();
      arc.innerRadius(0);

      var colorLegend = d3.legend.color()
        .scale(colorScale)
        .shapePadding(29)
        .shapeWidth(25)
        .shapeHeight(25)
        .labelOffset(9)
        .orient("horizontal");

      function render(data, group){
        
        var groupG = g.append("g")
          .attr("transform", "translate(" + group * (innerWidth / (numGroups - 1)) + ", 0)");

        var nested = d3.nest()
          .key(function (d){ return d[yColumn]; })
          .entries(data);
        
        // Compute sums for the radius field,
        // for setting the size of each pie.
        nested.forEach(function (xEntry){
          xEntry.areaColumnSum = d3.sum(xEntry.values, function (d){
            return d[areaColumn];
          });
        });

        yScale.domain(nested.map( function (d){ return d.key; }));
        colorScale.domain(nested[0].values.map(function (d){ return d[colorColumn]; }));
        pie.value(function(d) { return d[areaColumn]; });
        
        var pies = groupG.selectAll(".pie").data(nested);
        pies.enter().append("g").attr("class", "pie");
        pies.attr("transform", function (d){
          var y = yScale(d.key);
          return "translate(0," + y + ")";
        });
        pies.exit().remove();

        var slices = pies.selectAll("path").data(function (d){
          return pie(d.values);
        });

        slices.enter().append("path");
        slices
          .attr("d", function (d, i, j){
            arc.outerRadius(radiusScale(nested[j].areaColumnSum));
            return arc(d);
          })
          .attr("fill", function (d){ return colorScale(d.data[colorColumn]); });
        slices.exit().remove();

        var yAxisG = groupG.append("g")
          .attr("class", "y axis");
        yAxisG.call(yAxis)
          .selectAll("text")
          .attr("dx", (-0.687379488768002 * (numGroups - group)) + 0.49152 + "em")
          //.attr("dy", "-0.2736816128em")
          //.style("text-anchor", "end")
          //.attr("transform", "rotate(-90)" )
       
        colorLegendG.call(colorLegend);
      }

      function type(d){
        d.name = "World";
        d.population = +d.population;
        return d;
      }

      d3.csv("lynchings-1882-1968-by-state-and-race.csv", type, function (data){
        
        // Sort by total
        data = data.sort(function (a, b){
          return b.Total - a.Total;
        });
        
        // Transform the data so it works with the nest logic.
        var transformed = [];
        
        data.forEach(function(d, i){
          
          // The "group" is the vertical column.
          var group = Math.floor(Math.sqrt(i) / 1.12);
          
          transformed.push({
            state: d.State,
            race: "White",
            lynchings: d.White,
            group: group
          });
          transformed.push({
            state: d.State,
            race: "Black",
            lynchings: d.Black,
            group: group
          });
        });
        
        var nested = d3.nest()
          .key(function (d){ return d[yColumn]; })
          .entries(transformed);
        
        // Compute sums for the radius field,
        // for setting the size of each pie.
        nested.forEach(function (xEntry){
          xEntry.areaColumnSum = d3.sum(xEntry.values, function (d){
            return d[areaColumn];
          });
        });

        radiusScale.domain([
          0,
          d3.max(nested, function (xEntry){
            return xEntry.areaColumnSum;
          })
        ]);
        
        var groups = d3.nest()
          .key(function (d){ return d.group; })
          .entries(transformed);
        
        groups.forEach(function (groupData, i){
          render(groupData.values, i);
        });
        
        
      });

    </script>
  </body>
</html>

lynchings-1882-1968-by-state-and-race.csv

State,White,Black,Total
Alabama,48,299,347
Arizona,31,0,31
Arkansas,58,226,284
California,41,2,43
Colorado,65,3,68
Delaware,0,1,1
Florida,25,257,282
Georgia,39,492,531
Idaho,20,0,20
Illinois,15,19,34
Indiana,33,14,47
Iowa,17,2,19
Kansas,35,19,54
Kentucky,63,142,205
Louisiana,56,335,391
Maine,1,0,1
Maryland,2,27,29
Michigan,7,1,8
Minnesota,5,4,9
Mississippi,42,539,581
Missouri,53,69,122
Montana,82,2,84
Nebraska,52,5,57
Nevada,6,0,6
New Jersey,1,1,2
New Mexico,33,3,36
New York,1,1,2
North C.,15,86,101
North Dakota,13,3,16
Ohio,10,16,26
Oklahoma,82,40,122
Oregon,20,1,21
Pennsylvania,2,6,8
South C.,4,156,160
South Dakota,27,0,27
Tennessee,47,204,251
Texas,141,352,493
Utah,6,2,8
Vermont,1,0,1
Virginia,17,83,100
Washington,25,1,26
West Virginia,20,28,48
Wisconsin,6,0,6
Wyoming,30,5,35