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/6f9687b7e34efd7767f7d6e782b61437 to your computer and use it in GitHub Desktop.
Save stuwilmur/6f9687b7e34efd7767f7d6e782b61437 to your computer and use it in GitHub Desktop.
gonorrhoea-statistics
HB16CD HB16NM OBJECTID
S08000015 Ayrshire and Arran 0
S08000016 Borders 1
S08000017 Dumfries and Galloway 2
S08000018 Fife 3
S08000019 Forth Valley 4
S08000020 Grampian 5
S08000021 Greater Glasgow and Clyde 6
S08000022 Highland 7
S08000023 Lanarkshire 8
S08000024 Lothian 9
S08000025 Orkney 10
S08000026 Shetland 11
S08000027 Tayside 12
S08000028 Western Isles 13
<!DOCTYPE html>
<html lang="en">
<head>
<title>Scotland gonorrhoea figures</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-family: 'Merriweather', serif;
}
.yaxis {
font-family: 'Merriweather', serif;
}
.xaxis {
font-family: 'Merriweather', serif;
}
.ylabel {
font-size : 80%;
}
.caption {
font-size : 120%;
}
.subcaption {
font-size : 80%;
}
.notes {
font-size: 70%;
}
a {
text-decoration: none;
color : black;
}
a:hover {
text-decoration: underline;
}
a:active {
color: black;
}
a:visited {
color: black;
}
</style>
</head>
<body>
<!-- Create a div where the graph will take place -->
<div id="my_dataviz"></div>
<p class="caption">Episodes of gonorrhoea in men and women in Scotland, by NHS board, 2013-2017</p>
<p class="subcaption">Figures from the <a href="https://hpsmicrosites.scot.nhs.uk/shbbv-framework-data-portal.aspx">Scottish Government's Sexual Health and Blood Borne Virus (SHBBV) open access Data Portal</a>.</p>
<p class="subcaption"> Map data originally from <a href = "https://data.gov.uk/dataset/27d0fe5f-79bb-4116-aec9-a8e565ff756a/nhs-health-boards">Scottish Government SpatialData.gov.scot</a>.</p>
<p class="subcaption">Includes all diagnoses i.e. genital, rectal, pharyngeal and conjunctival in those aged >10 years.</p>
<p class="notes">* An episode is defined as a six week period.</p>
<p class="notes">&#8224; Values < 5 have been masked in line with National Services Scotland's <a href="https://www.isdscotland.org/About-ISD/Confidentiality/">Statistical Disclosure Control Policy to prevent deductive disclosure</a>.</p>
<script>
var codesMap = new Map();
// set the dimensions and margins of the graph
var margin = {top: 20, right: 100, bottom: 30, left: 70},
width = 1200 - margin.left - margin.right,
height = 600 - margin.top - margin.bottom;
chartWidth = width / 2;
// append the svg object to the body of the page
var svg = d3.select("#my_dataviz")
.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 + ")");
// 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", "80%")
// 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", "80%")
// Three function that change the tooltip when user hover / move / leave a cell
var mouseover = function(d) {
Tooltip
.style("opacity", 1)
}
var mousemove = function(d) {
var output = d.value == -1 ? "no data&#8224;" : d.value
Tooltip
.html(d.gender + " " + d.year + ": " + output)
.style("left", (d3.mouse(this)[0]+70) + "px")
.style("top", (d3.mouse(this)[1]) + "px")
}
var mouseleave = function(d) {
Tooltip
.style("opacity", 0)
}
// Three function that change the map tooltip when user hover / move / leave a feature
var mapmouseover = function(d) {
mapTooltip
.style("opacity", 1)
d3.select(this)
.style('fill', colours.teal)
.style("opacity", d.properties.HBCode == selectedRegion ? 1 : 0.5)
}
var mapmousemove = function(d) {
mapTooltip
.html(codesMap.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) {
selectedRegion = d.properties.HBCode;
optionsAndUpdate();
updateRegionColours();
}
var projection = d3.geoMercator()
.scale(2600)
.translate([width, height / 2])
.center([-4, 58]);
var geoGenerator = d3.geoPath()
.projection(projection);
function getRegionColour(d) {
return d.properties.HBCode == selectedRegion ? colours.teal : colours.grey;
}
function updateGeo(geojson) {
var u = d3.select('svg')
.selectAll('path')
.data(geojson.features);
u.enter()
.append('path')
.attr("class", "region")
.attr('d', geoGenerator)
.style("fill", getRegionColour)
.on("mouseover", mapmouseover)
.on("mousemove", mapmousemove)
.on("mouseleave", mapmouseleave)
.on("click", mapmouseclick)
}
function updateRegionColours()
{
var u = d3.select('svg')
.selectAll('path.region')
.transition()
.duration(500)
.style("opacity", 1)
.style("fill", getRegionColour);
}
var colours = { teal : "#69b3a2", grey : "#aaa", pink : "#b3669b" };
var men_data;
var women_data;
var line;
var line_w;
var dot;
var dot_w;
var x;
var y;
var selectedRegion;
var yLabel;
var chartLabel;
var geojson;
var squareside = 18;
var theMax = 800;
var calc_max = false;
function optionsAndUpdate()
{
// run the updateChart function with this selected option
update(selectedRegion)
}
// A function that updates the chart
function update(selectedGroup) {
// Create new data with the selection?
var theData = men_data ;
var dataFilter = theData.map(function(d){return {year: d.year, value:d[selectedGroup], gender : "men"} })
var dataFilter_w = women_data.map(function(d){return {year: d.year, value:d[selectedGroup], gender : "women"} })
var max_m = d3.max(dataFilter.map(function(d) {return +d.value;}));
var max_w = d3.max(dataFilter_w.map(function(d) {return +d.value;}));
var max = d3.max([max_w, max_m, 5]);
if (calc_max) {
theMax = max;
}
// Y axis
var y = d3.scaleLinear()
.domain( [0,theMax])
.range([ height, 0 ]);
svg.select(".yaxis")
.transition()
.duration(1000)
.call(d3.axisLeft(y));
// Give these new data to update line
line_w
.datum(dataFilter_w)
.transition()
.duration(1000)
.attr("d", d3.line()
.x(function(d) { return x(+d.year) })
.y(function(d) { return y(+d.value) })
)
dot_w
.data(dataFilter_w)
.transition()
.duration(1000)
.attr("x", function(d) { return x(+d.year) - squareside / 2 })
.attr("y", function(d) { return y(+d.value) - squareside / 2})
// Give these new data to update line
line
.datum(dataFilter)
.transition()
.duration(1000)
.attr("d", d3.line()
.x(function(d) { return x(+d.year) })
.y(function(d) { return y(+d.value) })
)
dot
.data(dataFilter)
.transition()
.duration(1000)
.attr("cx", function(d) { return x(+d.year) })
.attr("cy", function(d) { return y(+d.value) })
// update chart label
chartLabel
.transition()
.duration(500)
.style("opacity",0)
chartLabel
.transition()
.delay(500)
.duration(500)
.style("opacity",1)
.text(codesMap.get(selectedRegion));
}
//Read the data
d3.csv('Health_Boards_May_2016_Names_and_Codes_in_Scotland.csv', function(lookup)
{
lookup.reduce(function(map, obj) {
codesMap.set(obj.HB16CD, obj.HB16NM);
}, {});
selectedRegion = lookup[0].HB16CD;
d3.json('sco_nhs_boards.geojson', function(err, json) {
d3.csv("sh-1_1_men.csv", function(m_data) {
d3.csv("sh-1_1_women.csv", function(w_data) {
geojson = json;
updateGeo(json);
men_data = m_data;
women_data = w_data;
// Create data usng initial selection
var theData = men_data;
var theData_w = women_data;
var theMax = 800;
var dataFilter = theData.map(function(d){return {year: d.year, value:d[selectedRegion], gender : "men"} })
var dataFilter_w = women_data.map(function(d){return {year: d.year, value:d[selectedRegion], gender : "women"} })
var max_m = d3.max(dataFilter.map(function(d) {return +d.value;}));
var max_w = d3.max(dataFilter_w.map(function(d) {return +d.value;}));
var max = d3.max([max_w, max_m, 5]);
if (calc_max) {
theMax = max;
}
// List of groups (here I have one group per column)
var allGroup = men_data.columns.slice(1)
// Add X axis --> it is a date format
x = d3.scaleLinear()
.domain([2013,2017])
.range([ 0, chartWidth ]);
svg.append("g")
.attr("class", "xaxis")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x).ticks(5).tickFormat(d3.format("d")));
// Add Y axis
y = d3.scaleLinear()
.domain( [0,theMax])
.range([ height, 0 ]);
svg.append("g")
.attr("class", "yaxis")
.call(d3.axisLeft(y));
// Initialize line with group a
line_w = svg
.append('g')
.append("path")
.datum(dataFilter_w)
.attr("d", d3.line()
.x(function(d) { return x(+d.year) })
.y(function(d) { return y(+d.value) })
)
.attr("stroke", "black")
.style("stroke-width", 4)
.style("fill", "none")
// Initialize dots with group a
dot_w = svg
.selectAll('rect.w')
.data(dataFilter_w)
.enter()
.append('rect')
.attr("class", "w")
.attr("x", function(d) { return x(+d.year) - squareside / 2 })
.attr("y", function(d) { return y(+d.value) - squareside / 2})
.attr("width", squareside)
.attr("height", squareside)
.style("fill", colours.teal)
.on("mouseover", mouseover)
.on("mousemove", mousemove)
.on("mouseleave", mouseleave)
// Initialize line with group a
line = svg
.append('g')
.append("path")
.datum(dataFilter)
.attr("d", d3.line()
.x(function(d) { return x(+d.year) })
.y(function(d) { return y(+d.value) })
)
.attr("stroke", "black")
.style("stroke-width", 4)
.style("fill", "none")
// Initialize dots with group a
dot = svg
.selectAll('circle.m')
.data(dataFilter)
.enter()
.append('circle')
.attr("class", "m")
.attr("cx", function(d) { return x(+d.year) })
.attr("cy", function(d) { return y(+d.value) })
.attr("r", 7)
.style("fill", colours.pink)
.on("mouseover", mouseover)
.on("mousemove", mousemove)
.on("mouseleave", mouseleave)
ylabel = svg
.append("text")
.attr("class", "ylabel")
.attr("text-anchor", "end")
.attr("y", -margin.left)
.attr("dy", ".75em")
.attr("transform", "rotate(-90)")
.text("Episodes of gonorrhoea*");
chartLabel = svg
.append("text")
.attr("class", "chartlabel")
.attr("y", 0)
.attr("dy", ".75em")
.attr("x", 0)
.attr("dx", "1em")
.text(codesMap.get(selectedRegion));
})
})
})
})
</script>
</body>
</html>
MIT License
Copyright (c) 2019 stuwilmur
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
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