block by jeremycflin f262078e50e21a549317349b54d34851

Directional dot plot

Full Screen

A technique I sometimes use to indicate direction on a dot plot is connecting the dots with a triangle as an svg path and add a gradient to it. I think it stresses the direction more than a simple arrow because the direction is present on the whole shape (and in the colors), while arrows have only arrowheads to show the direction.

This is a remake of a remake by Jon Schwabish, with data from PEW. As Jon and others suggested: this type of dot plot might be more suited for data that really shows an evolution (fe values for 2015 with values for 2016) then for data that shows a comparison (Trump vs Obama).

forked from maartenzam‘s block: Directional dot plot

index.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Directional dots</title>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>

<body>
    <h2 style='font-family: sans-serif;'>The World is Questioning Trump's Leadership</h2>
    <p style='font-family: sans-serif; font-size: 20px; margin-top: -20px;'>Share confident the President's doing the right thing globally (%)</p>
    <div id="viz"></div>

    <script>
        var margin= {top: 50, right: 30, bottom: 30, left: 50};
        var width = 600;
        var height = 400;

        var svg = d3.select('#viz').append('svg')
          .attr('height', height)
          .attr('width', width);
      
        var chart = svg.append('g')
          .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')')
          .attr('id', 'chart');

        var obamacolor = '#4286F4';
        var trumpcolor = '#E91D0E';
        
        //Gradients to use on the triangles
        var defs = svg.append('defs')
        var linearGradient = defs
          .append('linearGradient')
          .attr('id', 'gradient');
        linearGradient.append('stop')
          .attr('offset', '10%')
          .attr('stop-color', trumpcolor);
        linearGradient.append('stop')
          .attr('offset', '90%')
          .attr('stop-color', obamacolor);
      
        var negativeGradient = defs
          .append('linearGradient')
          .attr('id', 'negative-gradient');
        negativeGradient.append('stop')
          .attr('offset', '10%')
          .attr('stop-color', obamacolor);
        negativeGradient.append('stop')
          .attr('offset', '90%')
          .attr('stop-color', trumpcolor);

        d3.csv('trumpobama.csv', function(data){

            data.forEach(function(d) {
                d.Obama = +d.Obama;
                d.Trump = +d.Trump;
                d.diff = d.Obama - d.Trump;
              });

            var y = d3.scaleBand()
                .domain(data.map(function(d) { return d.Country; }))
                .range([0, (height - margin.bottom)])
                .round(false);
            var x = d3.scaleLinear()
                .domain([0,100])
                .range([0, width - margin.left]);

            chart.selectAll('path.triangle')
                .data(data)
                .enter().append('path')
                .attr('class', 'triangle')
                .attr('d', function(d){
                  return 'M ' + x(d.Obama) +' '+ y(d.Country) + ' l ' + x(-d.diff) + ' -10 l 0 20 z';
                })
                .style('fill', function(d){
                  if (d.diff >= 0) {return 'url(#gradient)'; }
                  else {return 'url(#negative-gradient)'; }
                });

            chart.selectAll('circle.obama')
                .data(data)
                .enter().append('circle')
                .attr('cx', function(d){return x(d.Obama); })
                .attr('cy', function(d){return y(d.Country); })
                .attr('r', 10)
                .style('fill', obamacolor)
                .style('stroke', 'white')
                .style('stroke-width', 2);
            chart.selectAll('text.obama')
                .data(data)
                .enter().append('text')
                .text(function(d){ return d.Obama; })
                .attr('x', function(d){
                    if(d.diff >= 0) {
                        return x(d.Obama) + 12
                        }
                    else { return x(d.Obama) - 30}
                })
                .attr('dy', '0.35em')
                .attr('y', function(d){return y(d.Country); })
                .style('fill', obamacolor)
                .style('font-family', 'sans-serif');

            chart.selectAll('circle.trump')
                .data(data)
                .enter().append('circle')
                .attr('cx', function(d){return x(d.Trump); })
                .attr('cy', function(d){return y(d.Country); })
                .attr('r', 10)
                .style('fill', trumpcolor)
                .style('stroke', 'white')
                .style('stroke-width', 2);
            chart.selectAll('text.trump')
                .data(data)
                .enter().append('text')
                .text(function(d){ return d.Trump; })
                .attr('x', function(d){
                    if(d.diff >= 0) {
                        return x(d.Trump) - 30
                        }
                    else { return x(d.Trump) + 12}
                })
                .attr('dy', '0.35em')
                .attr('y', function(d){return y(d.Country); })
                .style('fill', trumpcolor)
                .style('font-family', 'sans-serif');

            chart.selectAll('text.country')
                .data(data)
                .enter().append('text')
                .text(function(d){ return d.Country})
                .attr('x', -50)
                .attr('y', function(d){return y(d.Country); })
                .attr('dy', '0.35em')
                .style('text-anchor', 'start')
                .style('font-family', 'sans-serif')
                .style('font-weight', 700);

            chart.append('text')
                .text('Trump')
                .attr('x', x(56))
                .attr('y', -30)
                .attr('text-anchor', 'start')
                .style('font-family', 'sans-serif')
                .style('font-weight', 700)
                .style('fill', trumpcolor);
            chart.append('text')
                .text('Obama')
                .attr('x', x(49))
                .attr('y', -30)
                .attr('text-anchor', 'end')
                .style('font-family', 'sans-serif')
                .style('font-weight', 700)
                .style('fill', obamacolor);
        });
    </script>

</body>

</html>

trumpobama.csv

Country,Obama,Trump
Israel,49,56
Russia,11,53
Australia,84,29
Canada,84,29
Japan,79,24
India,78,24
United Kingdom,79,22
South Korea,88,17
France,84,14
Germany,86,11