block by curran 5cb71249dcbfd635c794520aff45b89d

Extremist Murders in the US

Full Screen

This bar chart was inspired by this original hand-drawn visualization by Mona Chalabi posted on Twitter (also on instagram). Data from Anti-Defamation League report “WITH HATE IN THEIR HEARTS: The State of White Supremacy in the United States”.

Built with blockbuilder.org

index.html

<!DOCTYPE html>
<head>
  <meta charset="utf-8">
  <script src="https://d3js.org/d3.v4.min.js"></script>
  <style>
    body {
      margin:0px;
    }
    .label {
      font-size: 30pt;
      font-family: 'sans-serif';
      alignment-baseline: middle;
      fill: white;
    }
    .number, .subtitle {
      font-size: 20pt;
      font-family: 'sans-serif';
      alignment-baseline: middle;
      fill: #890000;
    }
    .bar {
      fill: #890000;
    }
  </style>
</head>

<body>
  <script>
    const width = 960;
    const height = 500;
    const margin = {
      left: 50,
      right: 200,
      top: 90,
      bottom: 52
    }
    
    const svg = d3.select("body").append("svg")
        .attr("width", width)
        .attr("height", height);
    
    svg.append('text')
        .attr('class', 'subtitle')
        .attr('x', margin.left)
        .attr('y', 86)
        .text('Murders in the US from July 2005 through June 2015.');
    
    
    const g = svg.append('g')
      .attr('transform', `translate(${margin.left}, ${margin.top})`)
    
    const data = [
      {
        name: "Total with extremist connection",
        value: 279
      },
      {
        name: "right-wing extremism",
        value: 260
      },
      {
        name: "white supremacists",
        value: 215
      }
    ];
    
    const innerWidth = width - margin.left - margin.right;
    const innerHeight = height - margin.top - margin.bottom;
    
    const xValue = d => d.value;
    const yValue = d => d.name;
    
    const xScale = d3.scaleLinear()
      .domain([0, d3.max(data, xValue)])
      .range([0, innerWidth]);
    
    const yScale = d3.scaleBand()
      .domain(data.map(yValue).reverse())
      .range([innerHeight, 0])
      .padding(0.272);
    
    const groups = g.selectAll('g').data(data);
    const groupsEnter = groups
      .enter().append('g')
        .attr('transform', d => `translate(0, ${yScale(yValue(d))})`);
    
    groupsEnter
      .append('rect')
        .attr('class', 'bar')
        .attr('width', d => xScale(xValue(d)))
        .attr('height', yScale.bandwidth())
        .attr('fill', 'black');
    
    groupsEnter
      .append('text')
        .attr('class', 'label')
        .attr('x', 15)
        .attr('y', yScale.bandwidth() / 2)
        .text(yValue);
    
    const percentFormat = d3.format(",.1%");
    const xPercent = d => percentFormat(xValue(d) / xScale.domain()[1]);
    
    groupsEnter
      .append('text')
        .attr('class', 'number')
        .attr('x', d => xScale(xValue(d)) + 8)
        .attr('y', yScale.bandwidth() / 2)
        .text(d => `${xValue(d)} (${xPercent(d)})`);

  </script>
</body>