Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stuwilmur/9ac70b9ddd1bd9c97a871e6f18dc2635 to your computer and use it in GitHub Desktop.
Save stuwilmur/9ac70b9ddd1bd9c97a871e6f18dc2635 to your computer and use it in GitHub Desktop.
terminations-categorised: marimekko/mosaic chart

termination-marimekko

Marimekko chart of Scottish termination statistics

HB16CD HB16NM OBJECTID
S08000015 Ayrshire and Arran 0
S08000016 Borders 1
S08000017 Dumfries and Galloway 2
S08000029 Fife 3
S08000019 Forth Valley 4
S08000020 Grampian 5
S08000031 Greater Glasgow and Clyde 6
S08000022 Highland 7
S08000032 Lanarkshire 8
S08000024 Lothian 9
S08000025 Islands 10
S08000030 Tayside 12
S00000000 Other / Unknown 13
<!DOCTYPE html>
<html lang="en">
<head>
<title>Scotland termination of pregnancy figures by Health board Marimekko chart</title>
<meta charset="utf-8">
<!-- Load d3.js -->
<script src="https://d3js.org/d3.v4.js"></script>
<!-- Color Scale -->
<script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script>
<!-- Font -->
<link href="https://fonts.googleapis.com/css?family=Merriweather&display=swap" rel="stylesheet">
<style>
body {
font: 12px Merriweather, sans-serif;
position: relative;
}
.caption {
font-size : 150%;
}
.subcaption {
font-size : 80%;
}
.node {
box-sizing: border-box;
line-height: 1em;
overflow: hidden;
position: absolute;
white-space: pre;
background: #ddd;
}
.node-value {
font-weight: bold;
}
.tooltip {
pointer-events: none;
}
</style>
</head>
<body>
<!-- Create a div where the graph will take place -->
<div id="my_dataviz"></div>
<div>
<select id="measureButton"></select>
<select id="yearButton"></select>
</div>
<p class="caption">Termination of pregnancy in Scotland across health board categorised by age, deprivation, estimated gestation, method of termination and parity.<br /><strong>Click on the map</strong> to select/deselect health boards. Use the menus below to select categorisation and year.</p>
<p class="subcaption">Data from the <a href="https://beta.isdscotland.org/find-publications-and-data/population-health/sexual-health/termination-of-pregnancy-statistics/">Termination of Pregnancy report, Public Health Scotland Data and Intelligence, published 29 June 2021</a>.</p>
<script>
var width = 800;
var pageWidth = 1600;
var height = 800;
var measuresMap = new Map();
// append the svg object to the body of the page
var svg = d3.select("#my_dataviz")
.append("svg")
.attr("id", "thesvg")
.attr("width", pageWidth )
.attr("height", height)
// create a tooltip
var Tooltip = d3.select("#my_dataviz")
.append("div")
.style("opacity", 0)
.attr("class", "tooltip")
.style("background-color", "white")
.style("border", "solid")
.style("border-width", "1px")
.style("border-radius", "0px")
.style("padding", "5px")
.style("position", "absolute")
.style("font-family", "Merriweather")
.style("font-size", "130%")
// create a tooltip for the map
var mapTooltip = d3.select("#my_dataviz")
.append("div")
.style("opacity", 0.1)
.attr("class", "tooltip")
.style("background-color", "white")
.style("border", "none")
.style("border-width", "1px")
.style("border-radius", "0px")
.style("padding", "5px")
.style("position", "absolute")
.style("font-family", "Merriweather")
.style("font-size", "150%")
// Three functions that change the tooltip when user hover / move / leave a cell
var mouseover = function(d) {
Tooltip
.style("opacity", .8)
}
var mousemove = function(d) {
Tooltip
.html(getNodeText(d, true))
.style("left", d3.event.pageX + 10 + "px")
.style("top", d3.event.pageY + 10 + "px")
.style("z-index", 2)
}
var mouseleave = function(d) {
Tooltip
.style("opacity", 0)
d3.select("svg").selectAll("text.data").remove();
}
// Parse the csv file
function parseData(d) {
d.Year = +d.Year;
d.Value = d.Value == "*" ? 0 : d.Value = +d.Value; //!! handle the missing data.
return d;
}
var measure = "Age";
var year = "2020";
var boards = new Map();
function getNodeText(d, value = false)
{
var text = boards.get(d.data.ID) + "\n" + d.data.Group;
if (value)
{
text += "<br /><strong>" + d.data.Value + "</strong>";
}
return text;
}
var IDs
var measuresList
var rolled
var nested
var theData;
var years;
var year;
var durationTime = 1000;
var geojson;
d3.csv("terminations data.csv", parseData, function(inData) {
d3.csv("measures_descriptors.csv", function(measures) {
//Read and parse the data
d3.csv('Health_Boards_May_2016_Names_and_Codes_in_Scotland.csv', function(lookup){
lookup.reduce(function(map, obj) {
boards.set(obj.HB16CD, obj.HB16NM);
}, {});
d3.json('sco_nhs_boards.geojson', function(err, json) {
theData = inData;
geojson = json;
d3.csv("measures_descriptors.csv", function(measuresData) {
measuresData.reduce(function(map, obj) {
measuresMap.set(obj.measure, obj);
}, {});
IDs = ["S00000000"];
//console.log(IDs);
measures.reduce(function(map, obj) {
measuresMap.set(obj.measure, obj);
}, {});
measuresList = Array.from(measuresMap.keys());
// add the options to the measures button
d3.select('#measureButton')
.on('change', function(d)
{
update();
})
.selectAll('option')
.data(measuresList)
.enter()
.append('option')
.attr('value', function(d) {return d;})
.text(function(d) {return measuresMap.get(d).description;});
rolled = d3.nest()
.key(function(d) { return d.Measure; })
.key(function(d) { return d.Year; })
.key(function(d) { return d.ID; })
.rollup(function(v) { return d3.sum(v, function(d) { return d.Value; }); })
.entries(theData);
nested = d3.nest()
.key(function(d) { return d.Measure; })
.key(function(d) { return d.Year; })
.key(function(d) { return d.ID; })
.entries(theData);
var yearNested = d3.nest()
.key(function(d) { return d.Year; })
.entries(theData);
//console.log(yearNested);
years = yearNested.map(function(d) { return d.key;}).sort()
console.log(years);
// add the options to the measures button
d3.select('#yearButton')
.on('change', function(d)
{
update();
})
.selectAll('option')
.data(years)
.enter()
.append('option')
.attr('value', function(d) {return d;})
.text(function(d) {return d;});
//console.log(rolled);
update();
})
})
})
})
})
function update()
{
measure = d3.select("#measureButton").property("value");
//console.log(measure);
year = d3.select("#yearButton").property("value");
updateGeo(geojson);
var rolledSelect = rolled
.filter(function(e) {return e.key == measure; })
[0]
.values
.filter(function(e) {return e.key == year; })
[0]
.values
.filter(function(e) {return IDs.includes(e.key); });
var nestedSelect = nested
.filter(function(e) {return e.key == measure; })
[0]
.values
.filter(function(e) {return e.key == year; })
[0]
.values
.filter(function(e) {return IDs.includes(e.key); });
//console.log(nestedSelect);
//console.log(root);
var nestedData = {name : "data", values : nestedSelect};
//console.log(nestedData);
//console.log(data);
var treemapLayout = d3.treemap()
.size([width, height])
.tile(d3.treemapSliceDice)
.padding(1)
.round(true);
var myroot = d3.hierarchy(nestedData, function(d) { return d.values; }).sum(function(d) { return d.Value; });
treemapLayout(myroot);
//console.log(root);
//console.log(myroot);
catNestedData = d3.nest()
.key(function(d) { return d.Measure; })
.key(function(d) { return d.Group; })
.entries(theData);
var allCategories = catNestedData.filter(function(f)
{ return f['key'] == measure;
});
var categories = allCategories[0].values.map( function(d) { return d.key; });
//console.log(categories);
color = d3.scaleOrdinal()
.domain(categories)
.range(d3.schemeSet3)
var node = d3.select("#my_dataviz").selectAll(".node").data(myroot.leaves());
//console.log(myroot.leaves());
node
.enter()
.append("div")
.on("mouseover", mouseover)
.on("mousemove", mousemove)
.on("mouseleave", mouseleave)
.merge(node)
.transition()
.duration(durationTime)
.attr("class", "node")
.text(function(d) {return getNodeText(d, false) + "\n" + d.data.Value;})
.style("left", function(d) { return d.x0 + "px"; })
.style("top", function(d) { return d.y0 + "px"; })
.style("width", function(d) { return d.x1 - d.x0 + "px"; })
.style("height", function(d) { return d.y1 - d.y0 + "px"; })
.style("background", function(d,i) {
//console.log(d.data.Group);
//console.log(color(d.data.Group));
return color(d.data.Group);
})
node.exit().remove();
}
var projection = d3.geoMercator()
.scale(3000)
.translate([pageWidth * .75, height / 2])
.center([-4, 58]);
var geoGenerator = d3.geoPath()
.projection(projection);
var colours = { teal : "#69b3a2", grey : "#aaa" };
function getRegionColour(d) {
return IDs.includes(d.properties.HBCode) ? colours.teal : colours.grey;
}
var mapmouseenter = function(d) {
mapTooltip
.style("opacity", .8)
d3.select(this)
.style('fill', colours.teal)
.style("opacity", 0.5)
}
var mapmousemove = function(d) {
mapTooltip
.html(boards.get(d.properties.HBCode))
.style("left", (d3.mouse(this)[0] + 20) + "px")
.style("top", (d3.mouse(this)[1]) + "px")
}
var mapmouseleave = function(d) {
mapTooltip
.style("opacity", 0)
d3.select(this)
.style('fill', getRegionColour(d))
.style("opacity", 1)
}
var mapmouseclick = function(d) {
var hb = d.properties.HBCode;
if (IDs.includes(hb))
{
if (IDs.length > 1)
{
IDs.splice(IDs.indexOf(hb), 1);
}
}
else
{
IDs.push(hb)
}
d3.select(this)
.style('fill', getRegionColour(d))
.style("opacity", 1)
update();
}
function updateGeo(geojson) {
var u = d3.select('svg')
.selectAll('path.region')
.data(geojson.features);
u.enter()
.append('path')
.attr("class", "region")
.attr('d', geoGenerator)
.style("fill", getRegionColour)
.on("mouseenter", mapmouseenter)
.on("mousemove", mapmousemove)
.on("mouseleave", mapmouseleave)
.on("click", mapmouseclick)
}
</script>
</body>
</html>
measure description unit
Age Age group Number
Gestation Estimated gestation in completed weeks Number
Parity Previous completed pregnancies Number
Method Method of termination (medical or surgical) Number
Previous Previous terminations of pregnancy (none, 1 or more) Number
SIMD Scottish Index of Multiple Deprivation quintile (1 = least deprived, 5 = most deprived) Number
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment