Skip to content

Instantly share code, notes, and snippets.

@tlfrd
Last active January 1, 2020 08:44
Show Gist options
  • Save tlfrd/8b7ba7dd660503dbe3a3b79893a170bd to your computer and use it in GitHub Desktop.
Save tlfrd/8b7ba7dd660503dbe3a3b79893a170bd to your computer and use it in GitHub Desktop.
Visualising Ratios
license: mit

Experimenting with ways to visualise ratios for a story exploring the pay ratios between the lowest and highest paid at a company.

<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<style>
text {
font-family: monospace;
}
rect {
stroke: #a5b98c;
}
</style>
</head>
<body>
<script>
var margin = {top: 70, right: 20, bottom: 20, left: 20};
var width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var ratios = [
{min: 34, median: 8},
{min: 14.1, median: 7.6},
{min: 15, median: 9},
{min: 12.9, median: 5.8},
{min: 10.6, median: 4.2},
{min: 40, median: 5.9},
{min: 14.3, median: 5.58}
];
// might use this at some point
// ratios.sort(function(a, b) {
// return b.min - a.min;
// })
var xSpacing = 20,
ySpacing = 30;
var legend = svg.append("g").attr("class", "legend");
legend.append("text")
.attr("x", margin.left)
.attr("y", 0)
.text("For every -- the lowest paid employee earns the highest earns");
legend.append("rect")
.attr("x", margin.left + 81)
.attr("y", -10.5)
.attr("width", 15)
.attr("height", 12)
.attr("fill", "#6c7c59")
legend.append("text")
.attr("x", margin.left + 84.5)
.attr("y", -0.5)
.text("£")
.style("font-size", 10)
legend.append("g").selectAll("rect")
.data([0, 1, 2])
.enter().append("rect")
.attr("x", function(d) { return margin.left + 500 + (d * xSpacing)})
.attr("y", -10.5)
.attr("width", 15)
.attr("height", 12)
.attr("fill", "#e1e7d8")
legend.append("g").selectAll("text")
.data([0, 1, 2])
.enter().append("text")
.attr("x", function(d) { return margin.left + 503.5 + (d * xSpacing)})
.attr("y", -0.5)
.text("£")
.style("font-size", 10);
var ratioGroups = svg.append("g")
.attr("class", "ratio-groups")
.selectAll("g")
.data(ratios)
.enter().append("g")
.attr("class", "ratio");
var counter = 0;
// add rectangles and fade in
ratioGroups.selectAll("rect")
.data(function(d, i) {
var range = d3.range(0, Math.round(d.min) + 1, 1);
return range.map(function(x) {
return {x: x, i: i};
})
})
.enter().append("rect")
.attr("x", function(d) {
if (d.x == 0) {
return margin.left;
} else {
return margin.left + 10 + d.x * xSpacing;
}
})
.attr("y", function(d) { return margin.top + d.i * ySpacing })
.attr("width", 15)
.attr("height", 12)
.attr("fill", function(d) {
if (d.x == 0) {
return "#6c7c59";
} else {
return "#e1e7d8";
}
})
.attr("opacity", function(d) {
if (d.x == 0) {
return 1;
} else {
return 0;
}
})
.transition()
.delay(function(d) {
return (d.x * 25) + (d.i * 100);
})
.attr("opacity", 1);
// add text and fade in
ratioGroups.selectAll("text")
.data(function(d, i) {
var range = d3.range(0, Math.round(d.min) + 1, 1);
return range.map(function(x) {
return {x: x, i: i};
})
})
.enter().append("text")
.attr("x", function(d) {
if (d.x == 0) {
return margin.left;
} else {
return margin.left + 10 + d.x * xSpacing;
}
})
.attr("y", function(d) { return margin.top + d.i * ySpacing })
.attr("dx", xSpacing / 5)
.attr("dy", ySpacing / 3)
.style("font-size", 10)
.attr("opacity", function(d) {
if (d.x == 0) {
return 1;
} else {
return 0;
}
})
.text("£")
.transition()
.delay(function(d) {
return (d.x * 25) + (d.i * 100);
})
.attr("opacity", 1)
// delay by the amount of time each ratio takes to animate
ratioGroups
.append("text")
.attr("x", function(d) { return margin.left + 10 + (Math.round(d.min) + 1) * xSpacing})
.attr("y", function(d, i) { return margin.top + i * ySpacing })
.attr("dx", "0.7em")
.attr("dy", "0.8em")
.text(function(d) { return d.min + ":1"; })
.attr("opacity", 0)
.transition()
.delay(function(d, i) { return (Math.round(d.min) * 25) + (i * 100) })
.attr("opacity", 1);
ratioGroups
.append("text")
.attr("x", margin.left + 10)
.attr("y", function(d, i) { return margin.top + i * ySpacing })
.attr("dx", "0.6em")
.attr("dy", "0.7em")
.text(":")
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment