My entry for Makeover Monday week 14, which was based on the data from a Guardian article and PwC report on the affects of automation on UK jobs.
The chart is vertical marimekko chart, just using rects and manually calculating the offset of each row, rather than using the d3 treemap function, like this example.
Built with blockbuilder.org, layitout.com, and Bootstrap.
xxxxxxxxxx
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
<style>
body { text-align: center;}
p, button { text-align: center; }
path { display: none}
line { stroke: lightGrey }
#next-button { background-color: #2E8B57; background-image: linear-gradient(to bottom,#8FBC8F 0,#2E8B57 100%) }
text { fill: Black }
rect { shape-rendering: crispEdges; stroke: white; stroke-width: 1px; }
.industry-label { font-size: 14px }
</style>
</head>
<body>
<div class="container-fluid">
<div class="row">
<div class="col-xs-12">
<p id="headline" class="text-center lead">
</p>
<div id="chart"></div>
<p id="source-link">More information and analysis is available in the PwC report: <a href="https://www.pwc.co.uk/services/economics-policy/insights/uk-economic-outlook.html">UK Economic Outlook March 2017</a></p>
<button id="next-button" type="button" class="btn btn-primary btn-lg btn-block">
Next
</button>
</div>
</div>
</div>
<script>
var data = [
{
"industry": "Wholesale and retail trade",
"employmentShare": 0.15,
"jobAutomation": 0.44
},
{
"industry": "Manufacturing",
"employmentShare": 0.08,
"jobAutomation": 0.46
},
{
"industry": "Administrative and support services",
"employmentShare": 0.08,
"jobAutomation": 0.37
},
{
"industry": "Transportation and storage",
"employmentShare": 0.05,
"jobAutomation": 0.56
},
{
"industry": "Professional, scientific and technical",
"employmentShare": 0.09,
"jobAutomation": 0.26
},
{
"industry": "Human health and social work",
"employmentShare": 0.12,
"jobAutomation": 0.17
},
{
"industry": "Accommodation and food services",
"employmentShare": 0.07,
"jobAutomation": 0.26
},
{
"industry": "Construction",
"employmentShare": 0.064,
"jobAutomation": 0.24
},
{
"industry": "Public administration and defence",
"employmentShare": 0.043,
"jobAutomation": 0.32
},
{
"industry": "Information and communication",
"employmentShare": 0.041,
"jobAutomation": 0.27
},
{
"industry": "Financial and insurance",
"employmentShare": 0.032,
"jobAutomation": 0.32
},
{
"industry": "Education",
"employmentShare": 0.087,
"jobAutomation": 0.09
},
{
"industry": "Arts and entertainment",
"employmentShare": 0.029,
"jobAutomation": 0.22
},
{
"industry": "Other services",
"employmentShare": 0.027,
"jobAutomation": 0.19
},
{
"industry": "Real estate",
"employmentShare": 0.017,
"jobAutomation": 0.28
},
{
"industry": "Water, sewage and waste management",
"employmentShare": 0.006,
"jobAutomation": 0.63
},
{
"industry": "Agriculture, forestry and fishing",
"employmentShare": 0.011,
"jobAutomation": 0.19
},
{
"industry": "Electricity and gas supply",
"employmentShare": 0.004,
"jobAutomation": 0.32
},
{
"industry": "Mining and quarrying",
"employmentShare": 0.002,
"jobAutomation": 0.23
},
{
"industry": "Domestic personnel and self-subsistence",
"employmentShare": 0.003,
"jobAutomation": 0.08
}
]
var vWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
var vHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
const width = vWidth * 0.35;
const height = vHeight * 0.8;
const margin = {"top": 25, "left": vWidth * 0.3, "right": vWidth * 0.1, "bottom": 25};
var xScale = d3.scaleLinear().range([0,width]).domain([0,1]); //jobAutomation
var yScale = d3.scaleLinear().range([0,height]); //employmentShare
var totalOffset = 0;
const rowGap = 20;
const dataLength = data.length;
const expandedHeight = height + (dataLength * rowGap);
const jobs = 34766667;
const overallPercent = 0.3;
var chartNo = 2;
const duration = 1000;
const mainColour = "SeaGreen";
const backgroundColour = "PaleGoldenRod";
var sourceLink = d3.select("#source-link").style("display", "none");
data.forEach(function(d){
d.offset = totalOffset;
totalOffset = d.offset + d.employmentShare;
});
yScale.domain([0,totalOffset]);
var select = d3.select("button").on("click", updateChart)
var xAxis = d3.axisTop(xScale).tickFormat(formatPercentage);
var defaultHeadline = "There are currently " + roundMillions(jobs) + " million jobs in the UK:";
var defaultRectText = "All " + roundMillions(jobs) + " million jobs:";
/////////////////////////////////////////////////////////////////////
var headline = d3.select("#headline").text(defaultHeadline);
var svg = d3.select("#chart").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
var chart = svg.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
chart.append("rect")
.attr("id", "base-rect")
.attr("x", 0)
.attr("y", 0)
.attr("width", width)
.attr("height", height)
.style("fill", backgroundColour);
chart.append("rect")
.attr("class", "overall-automation")
.attr("x", 0)
.attr("y", 0)
.attr("width", 0)
.attr("height", height)
.style("fill", mainColour);
chart.append("text")
.attr("id", "initial-text")
.text(defaultRectText)
.attr("x", -5)
.attr("y", height/2)
.style("text-anchor", "end");
var gAxis = svg.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.call(xAxis);
gAxis.selectAll("text")
.style("fill", mainColour)
.style("opacity", 0);
gAxis.selectAll("line").remove();
var industries = chart.selectAll(".industry")
.data(data)
.enter()
.append("g")
.attr("class", "industry")
.attr("transform", function(d) { return "translate(0," + yScale(d.offset) + ")"; });
industries.append("text")
.text(function(d) { return formatPercentage(d.employmentShare * d.jobAutomation); })
.attr("x", width + 5)
.attr("y", function(d) { return (yScale(d.employmentShare)/2) + 5; })
.style("opacity", 0);
var all = industries.append("rect")
.attr("class", "all")
.attr("x", 0)
.attr("y", 0)
.attr("width", width)
.attr("height", function(d) { return yScale(d.employmentShare) < 3 ? 3 : yScale(d.employmentShare); })
.style("fill", backgroundColour)
.style("opacity",0);
industries.append("text")
.attr("class", "all-text")
.text(function(d){ return formatMillions(d.employmentShare * jobs) + " (" + formatPercentage(d.employmentShare) + ")" })
.attr("x", width/2)
.attr("y", function(d) { return 5 + yScale(d.employmentShare)/2; })
.style("opacity",0)
.style("text-anchor", "middle");
var automation = industries.append("rect")
.attr("class", "automation")
.attr("x", 0)
.attr("y", 0)
.attr("width", 0)
.attr("height", function(d) { return yScale(d.employmentShare) < 3 ? 3 : yScale(d.employmentShare); })
.style("fill", mainColour);
industries.append("text")
//.filter(function(d){ return d.industry != "Domestic personnel and self-subsistence" && d.industry != "Mining and quarrying" && d.industry != "Agriculture, forestry and fishing"; })
.attr("class", "automation-text")
//.text(function(d){ return formatPercentage(d.jobAutomation)})
.text(function(d){ return formatMillions((d.employmentShare * jobs) * d.jobAutomation) + " (" + formatPercentage(d.jobAutomation) + ")" })
//.attr("x", function(d){ return xScale(d.jobAutomation) + 5 })
.attr("x", width + 5 )
.attr("y", function(d) { return 5 + yScale(d.employmentShare)/2; })
.style("fill", mainColour)
.style("opacity",0);
var industryLabel = industries.append("text")
//.filter(function(d){ return d.industry != "Domestic personnel and self-subsistence" && d.industry != "Mining and quarrying" && d.industry != "Agriculture, forestry and fishing"; })
.attr("class", "industry-label")
.text(function(d) { return d.industry })
.attr("x", -5)
.attr("y", function(d) { return (yScale(d.employmentShare)/2) + 5; })
.style("text-anchor", "end")
.style("opacity", 0);
function updateChart() {
if (chartNo === 1) {
headline.text(defaultHeadline);
sourceLink.style("display", "none");
var t1 = d3.transition().duration(duration);
svg.transition(t1)
.attr("height", height + margin.top + margin.bottom);
industries.transition(t1)
.attr("transform", function(d, i) { return "translate(0," + yScale(d.offset) + ")"; });
automation.transition(t1)
.attr("width", 0)
.style("opacity",1);
d3.selectAll("#base-rect, #initial-text").transition(t1)
.style("opacity", 1);
d3.select("#initial-text")
.text(defaultRectText)
.style("fill", "black");
all.transition(t1)
.style("opacity", 0);
industryLabel.transition(t1)
.style("opacity", 0);
d3.selectAll(".automation-text").transition(t1)
.style("opacity", 0);
gAxis.selectAll("text").transition(t1)
.style("opacity", 0);
select.text("Next")
chartNo = chartNo + 1
} else if (chartNo === 2) {
headline.text("By 2030, " + formatPercentage(overallPercent) + " (" + roundMillions(jobs * overallPercent) + " million) of these jobs may be replaced by automation:");
var t2 = d3.transition().duration(duration)
d3.select("#initial-text").text(roundMillions(jobs * overallPercent) + " million job losses:")
.style("fill", mainColour);
d3.select(".overall-automation").transition(t2)
.attr("width", xScale(0.3));
gAxis.selectAll("text").transition(t2)
.delay(function(d){ return d * 700; })
.style("opacity", function(d) { return d < 0.4 ? 1 : 0; })
chartNo = chartNo + 1
} else if (chartNo === 3) {
headline.text("However the affect of automation will vary across industries.");
var t3 = d3.transition().duration(duration);
d3.select(".overall-automation").transition(t3)
.attr("width", 0);
d3.select("#initial-text").transition(t3)
.style("opacity", 0);
gAxis.selectAll("text").transition(t3)
.style("opacity", 0)
chartNo = chartNo + 1
} else if (chartNo === 4) {
headline.text("The current number of jobs are divided across these industries:");
var t4 = d3.transition().duration(duration);
d3.selectAll(".all, .industry-label, .all-text").transition(t4)
.style("opacity", 1);
d3.select("#base-rect").transition(t4)
.style("opacity", 0);
chartNo = chartNo + 1
} else if (chartNo === 5) {
headline.text("The estimated job losses due to automation per industry will vary:");
var t5 = d3.transition().duration(duration);
d3.selectAll(".all-text").transition(t5)
.style("opacity", 0 )
gAxis.selectAll("text").transition(t5)
.delay(function(d){ return d * 700; })
.style("opacity", 1 )
automation.transition(t5)
.attr("width", function(d) { return xScale(d.jobAutomation); });
d3.selectAll(".automation-text").transition(t5)
.style("opacity", 1 )
chartNo = chartNo + 1
} else if (chartNo === 6) {
headline.text("Over 2 million (40%) jobs in 'wholesale and retail trade' may be affected by automation:");
var t6 = d3.transition().duration(duration);
industries.selectAll(".industry-label, .automation-text").transition(t6)
.style("opacity", function(d) { return d.industry == "Wholesale and retail trade" ? 1 : 0; });
industries.selectAll(".automation").transition(t7)
.style("opacity", function(d) { return d.industry == "Wholesale and retail trade" ? 1 : 0.2; });
chartNo = chartNo + 1
} else if (chartNo === 7) {
headline.text("60% of 'water, sewage and waste management' may jobs may be affected:");
var t7 = d3.transition().duration(duration);
industries.selectAll(".industry-label, .automation-text").transition(t7)
.style("opacity", function(d) { return d.industry == "Water, sewage and waste management" ? 1 : 0; });
industries.selectAll(".automation").transition(t7)
.style("opacity", function(d) { return d.industry == "Water, sewage and waste management" ? 1 : 0.2; });
chartNo = chartNo + 1;
} else if (chartNo === 8) {
headline.text("Over half of these potential job losses are in four key industry sectors: wholesale and retail trade, manufacturing, administrative and support services, and transport and storage.");
var t8 = d3.transition().duration(duration);
svg.transition(t8)
.attr("height", expandedHeight + margin.top + margin.bottom);
industries.transition(t8)
.attr("transform", function(d, i) { return "translate(0," + (yScale(d.offset) + (i * rowGap)) + ")"; });
industries.selectAll(".industry-label, .automation, .automation-text").transition(t8)
.style("opacity", 1);
sourceLink.style("display", "inherit");
select.text("Restart");
chartNo = 1;
};
};
function formatPercentage(n) {
var roundedN = Math.round(n * 1000);
return roundedN/10 + "%";
};
function roundMillions(n) {
var roundedN = Math.round(n/10000)/100;
return roundedN;
};
function formatMillions(n) {
return roundMillions(n) + "M";
};
</script>
</body>
https://d3js.org/d3.v4.min.js