Skip to content

Instantly share code, notes, and snippets.

@trygu
Last active February 11, 2016 13:00
Show Gist options
  • Save trygu/6509355 to your computer and use it in GitHub Desktop.
Save trygu/6509355 to your computer and use it in GitHub Desktop.
Norwegian import of goods and services using d3

This bubble chart is just a simple way of visualizing norwegian import of goods and services for a 13 month period. It's partly based on Mike Bostock's Bubble Chart. Each color of the bubble represent an SITC grouping.

Description of the dataset used is here

This bubble chart requires a modern web browser. No IE support.

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
text {
font: 10px sans-serif;
font-weight:bold
}
</style>
<script src="http://www.ssb.no/_public/skins/advanced/ssb.no/scripts/visual/json-stat.js"></script>
<script src="http://d3js.org/d3.v3.min.js"></script>
</head>
<body>
<p id="buttonrow"/>
<div class="bubble"/>
<script>
var j = JSONstat('http://data.ssb.no/api/v0/dataset/1140.json?lang=en'),
ds = j.Dataset(0),
time = ds.Dimension('Tid').id[0],
classification = '1'
var contentscode = 'Verdi',
diameter = 1080,
format = d3.format(",d"),
color = d3.scale.category20c(),
pack = d3.layout.pack()
.sort(null)
.size([diameter, diameter])
.padding(1.5),
svg = d3.select(".bubble").insert("svg")
.attr("width", diameter)
.attr("height", diameter)
.attr("class", "pack"),
node = svg.selectAll(".node")
.data(pack.nodes(createData(time))
.filter(function(d) { return !d.children }))
.enter().append("g")
.attr("class", "node")
.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")" })
node.append("title")
.text(function(d) { return d.className + ": " + format(d.value) })
node.append("circle")
.attr("r", function(d) { return d.r; })
.style("fill", function(d) { return color(d.packageName) })
node.append("text")
.attr("dy", ".3em")
.style("text-anchor", "middle")
.text(function(d) { return d.className.substring(0, d.r / 3); })
d3.select(self.frameElement).style("height", diameter + "px")
// Add row of switch buttons
ds.Dimension('Tid').id.forEach( function(t) {
var button = document.createElement("input")
button.id = t
button.type = "button"
button.value = t
button.setAttribute("class", "button")
button.setAttribute("onclick", "switchPeriodTo('" + t + "')")
if (time == t) {
button.style = "color: red"
}
document.getElementById("buttonrow").appendChild( button )
} )
// Works for 1 switch at a time. Switches in series need a lot more handling in relation to the
// end-events applied to each transition.
function switchPeriodTo(p) {
var n = svg.selectAll(".node")
.data(pack.nodes(createData(p))
.filter(function(d) { return !d.children }))
n.transition()
.duration(350)
.ease("linear")
.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")" })
n.select("circle")
.transition()
.ease("linear")
.duration(500)
.attr("r", function(d) { return d.r; })
n.select("title")
.text(function(d) { return d.className + ": " + format(d.value) })
n.select("text")
.transition()
.ease("linear")
.duration(500)
.attr("dy", ".3em")
.style("text-anchor", "middle")
.text(function(d) { return d.className.substring(0, d.r / 3); })
switchHilight(p)
}
// Todo: Maybe a slider would be better.
function switchHilight(time) {
var inputs = document.getElementsByTagName("input")
for (var i=0; i<inputs.length;i++) {
inputs[i].style = ""
}
document.getElementById(time).style = "color: red"
}
// Build datastructure
function createData(time) {
var tc = ds.Dimension("SITC"),
data = {}
data.children = []
for (var i = 0; i < tc.length; i++) {
var id = tc.id[i],
c = id.substring(0,1),
value = ds.Data( { "SITC": id,
"Tid": time,
"ContentsCode": contentscode,
"ImpEks": classification } ).value
data.children.push ( { "className": tc.Category( id ).label,
"packageName": c.toString(),
"value": value } )
}
return data
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment