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).
xxxxxxxxxx
<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>
https://d3js.org/d3.v4.min.js