|
<!DOCTYPE html> |
|
<meta charset="utf-8"> |
|
<head> |
|
<style> |
|
svg { |
|
} |
|
|
|
table { |
|
width: 100%; |
|
} |
|
td { |
|
|
|
vertical-align: top; |
|
} |
|
|
|
path { |
|
stroke: #fff; |
|
stroke-width: .5px; |
|
} |
|
|
|
path:hover { |
|
stroke: black; |
|
stroke-width: 2px |
|
} |
|
|
|
#main .zoom { |
|
fill: steelblue !important; |
|
} |
|
|
|
.caption { |
|
font-size: 30px; |
|
font-family: Verdana, Geneva, sans-serif; |
|
} |
|
|
|
circle { |
|
fill: #f03b20; |
|
stroke: black; |
|
} |
|
|
|
line { |
|
stroke: black; |
|
stroke-opacity: 0.4 |
|
} |
|
|
|
.base { |
|
fill: #ccc; |
|
} |
|
|
|
.overlay { |
|
fill: #fa9fb5; |
|
} |
|
|
|
#andel { |
|
font-weight: bold; |
|
font-size: 1.2em; |
|
} |
|
|
|
.home { |
|
stroke: steelblue; |
|
stroke-width: 4px; |
|
} |
|
|
|
.description { |
|
font-family: Arial, Helvetica, sans-serif; |
|
} |
|
|
|
</style> |
|
|
|
<script src="//d3js.org/d3.v3.min.js"></script> |
|
<script src="//d3js.org/topojson.v1.min.js"></script> |
|
</head> |
|
|
|
<body> |
|
<div class='description'> |
|
<p> |
|
Normaliserat data för hur många som flyttar från sin hemkommun till stad vald i drop down. <br/> |
|
Färgintensitet (röd) motsvarar hur stor andel av befolkningen i en kommun som flyttat. |
|
</p> |
|
<p> |
|
Visualiseringen visar endast de kommuner där andelen som flyttat är större än <span id='andel'>XXX</span>. |
|
</p> |
|
</div> |
|
|
|
<table> |
|
<tr> |
|
<td colspan="2"> |
|
Stad: |
|
<select id="city"> |
|
<option value="0">Stockholm</option> |
|
<option value="1">Göteborg</option> |
|
<option value="2">Malmö</option> |
|
</select> |
|
</td> |
|
</tr> |
|
<tr> |
|
<td colspan=2> |
|
Kommun: <input id="search" type="search" style="width: 300px"> |
|
<input type="button" value="hitta" onclick="setKommun(this)" data-target="search"> |
|
</td> |
|
</tr> |
|
<tr> |
|
<td> |
|
<svg id='main' /> |
|
</td> |
|
<td> |
|
<pre id='detail'></pre> |
|
</td> |
|
</tr> |
|
</table> |
|
|
|
<script> |
|
|
|
// helpers |
|
d3.selection.prototype.moveToFront = function() { |
|
return this.each(function(){ |
|
this.parentNode.appendChild(this); |
|
}); |
|
}; |
|
|
|
function setKommun(d) { |
|
d3.select(".home").classed("home", false); |
|
var input = d3.select('#' + d.dataset.target); |
|
var home = d3.select('#' + (input[0][0].value)); |
|
home.classed("home", true); |
|
d3.select(home.parentNode).moveToFront(); |
|
} |
|
|
|
var distance = function distance (firstObject, secondObject) { |
|
return Math.sqrt( |
|
( firstObject[0] - secondObject[0] ) * |
|
( firstObject[0] - secondObject[0] ) + ( firstObject[1] - secondObject[1] ) * |
|
( firstObject[1] - secondObject[1] ) ); |
|
} |
|
|
|
// main code |
|
var width = 400, |
|
height = 900, |
|
min_bound = 0.05, |
|
cities = [["Stockholm","Stockholm"], |
|
["Goteborg","Göteborg"],["Malmo","Malmö"]], |
|
city = cities[0], |
|
centered; |
|
|
|
d3.select("#andel").html(min_bound*100 + '%'); |
|
|
|
var projection = d3.geo.mercator() |
|
.scale(1200) |
|
.translate([width / 2, (height / 2) - 150]) |
|
.center([0, 55]) |
|
.rotate([-17, -7.4]); |
|
|
|
var path = d3.geo.path() |
|
.projection(projection); |
|
|
|
var svg = d3.select("#main") |
|
.attr("width", width) |
|
.attr("height", height); |
|
|
|
var features = ''; |
|
|
|
function update() { |
|
d3.select("#main").html(''); |
|
|
|
var point = features.find(function(x) { |
|
return x.properties.KnNamn == city[1]; |
|
}); |
|
|
|
features.forEach(function(x) { console.log(x.properties.KnNamn); }); |
|
|
|
// setup scale |
|
var max = d3.max(features, |
|
function(d) { |
|
if(d.properties.KnNamn == city[0]) return 0; |
|
return +d.properties[city[0] + "_ANDELFR_NF"]; |
|
}); |
|
|
|
// scales |
|
var sizeScale = d3.scale.linear() |
|
.domain([0, max]) |
|
.range([1, 20]) |
|
.clamp(true); |
|
|
|
var colorScale = d3.scale.linear() |
|
.domain([0, max]) |
|
.range(['#ccc', 'red']); |
|
|
|
var groups = svg.append('g').classed('container',true).selectAll("g") |
|
.data(features) |
|
.enter() |
|
.append("g") |
|
.on("mouseover", function(d) { |
|
d3.select(this).moveToFront(); d3.select("#detail").html(JSON.stringify(d3.select(this).datum().properties, null, 2)); |
|
}); |
|
|
|
groups |
|
.classed("base", function(d) { return +d.properties[city[0] + "_ANDELFR_NF"] < min_bound; }) |
|
.classed("overlay", function(d) { return +d.properties[city[0] + "_ANDELFR_NF"] >= min_bound; }) |
|
.append("path") |
|
.attr("d", path) |
|
.style("fill", function(d) { |
|
if(+d.properties[city[0] + "_ANDELFR_NF"] < min_bound) return colorScale.range()[0]; |
|
return colorScale(+d.properties[city[0] + "_ANDELFR_NF"]); |
|
}) |
|
.attr("id", function(d) { return d.properties.KnNamn; }) |
|
.on("click", clicked);; |
|
|
|
/* |
|
var lines = svg.selectAll("g.lines") |
|
.data(features) |
|
.enter() |
|
.append("g") |
|
.classed("lines", true); |
|
|
|
lines.each(function (d) { |
|
var me = d3.select(this); |
|
|
|
if(+d.properties[city[0] + "_ANDELFR_NF"] >= min_bound) |
|
me |
|
.append("line") |
|
.attr({ |
|
x1: projection(d3.geo.centroid(point))[0] , |
|
y1: projection(d3.geo.centroid(point))[1], |
|
x2: projection(d3.geo.centroid(d))[0], |
|
y2: projection(d3.geo.centroid(d))[1] |
|
}); |
|
}) |
|
*/ |
|
/* |
|
var circles = svg.selectAll("g.circles") |
|
.data(features) |
|
.enter() |
|
.append("g") |
|
.classed("circles", true); |
|
|
|
circles.each(function (d) { |
|
var me = d3.select(this); |
|
|
|
if(+d.properties[city[0] + "_ANDELFR_NF"] >= min_bound) |
|
me |
|
.append("circle") |
|
.attr({ |
|
cx: function(d) { return projection(d3.geo.centroid(d))[0]; }, |
|
cy: function(d) { return projection(d3.geo.centroid(d))[1]; }, |
|
r: function(d) { |
|
return sizeScale(+d.properties[city[0] + "_ANDELFR_NF"]); } , |
|
}) |
|
.style("fill", '#d7191c'); |
|
}) |
|
*/ |
|
} |
|
|
|
d3.json("alla_lan(1).json", function(error, topology) { |
|
if (error) throw error; |
|
console.log(topology); |
|
features = topojson.feature(topology, topology.objects.svenskarna_kommun).features; |
|
update(); |
|
}); |
|
|
|
d3.select("#city").on("change", function() { |
|
city = cities[d3.select(this).node().value]; |
|
update(); |
|
}) |
|
|
|
|
|
function clicked(d) { |
|
var x, y, k; |
|
|
|
if (d && centered !== d) { |
|
var centroid = path.centroid(d); |
|
x = centroid[0]; |
|
y = centroid[1]; |
|
k = 7; |
|
centered = d; |
|
} else { |
|
x = width / 2; |
|
y = height / 2; |
|
k = 1; |
|
centered = null; |
|
} |
|
|
|
var container = d3.select('.container'); |
|
|
|
container.selectAll("path") |
|
.classed("active", centered && function(d) { return d === centered; }); |
|
|
|
container.transition() |
|
.duration(500) |
|
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")scale(" + k + ")translate(" + -x + "," + -y + ")") |
|
.style("stroke-width", 1.5 / k + "px"); |
|
} |
|
|
|
|
|
</script> |