Skip to content

Instantly share code, notes, and snippets.

@milkbread
Last active July 20, 2018 16:12
Show Gist options
  • Save milkbread/5940675 to your computer and use it in GitHub Desktop.
Save milkbread/5940675 to your computer and use it in GitHub Desktop.
HTML: D3: TopoJSON: Sorted polygons of german states - dynamic visualisation I
<!DOCTYPE html>
<html>
<head>
<title>Testmap</title>
<meta charset="utf-8" />
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://d3js.org/topojson.v1.min.js"></script>
<style>
#states{
overflow-x: auto;
overflow-y: auto;
padding-bottom: 15px;
max-width: 100%;
}
</style>
</head>
<body>
<div id='states'></div>
<div>Sorted list of german states</div>
<div id='infos'></div>
<script>
var sWidth = 50
var width = 16*sWidth,
height = sWidth+20
duration = 2000;
var svg = d3.select("#states").append("svg")
.attr("width", width)
.attr("height", height);
var svgInfos = d3.select("#infos").append("svg")
.attr("width", width)
.attr("height", 350);
var path = d3.geo.path().projection(normalize_projection);
var bounds;
var scaleLat = d3.scale.linear();
var scaleLng = d3.scale.linear();
d3.json("vg1000_topo.json", function(error, topology) {
var states = topojson.feature(topology, topology.objects.vg1000_bld);
var geoms_ = states.features;
//add a ID to the geometries, as I need it for the .enter()
geoms_ = geoms_.map(function(d,i){d.ID=i; return d;})
showGeoms();
svg.on('mousedown',showGeoms)
function showGeoms(){
//dummy re-creation of geoms array ... replace this by a filtering
var geoms = geoms_.slice(0, Math.floor(Math.random() * 16))
console.log(geoms)
//sort geometry for a certain property of the input geometry
geoms = sortPolygons(geoms,'EWZ'); //Possible values: Length EWZ Area
var elements = geoms.map(function(d){return d.ID})
//1. JOIN ... strangly, it doesn't work with the 'objects'
var states = svg.selectAll('path').data(elements, function(d) { return d; });
//2. UPDATE
states.transition().duration(duration)
.attr("transform",function(d,i){return "translate("+(i+1)*sWidth+",0) scale(-1,1)"})
.attr('stroke','#0f0');
//3. ENTER
states.enter().append('g').append("path")
.attr("d",setPath) //see function...
.attr('fill','#aaa')
.attr('stroke','#f00')
.transition().duration(duration)
.attr("transform",function(d,i){return "translate("+(i+1)*sWidth+",0) scale(-1,1)"});
//5. EXIT
states.exit()
.transition().duration(duration)
.attr("transform",function(d,i){return "translate("+sWidth*16+",0) scale(1,1)"})
.remove();
showInfo(geoms, elements, 'EWZ');
function setPath(d,i){
var geometry = geoms[i].geometry;
bounds=d3.geo.bounds(geometry); //save bounds globally
var new_path = path({type: geometry.type, coordinates: geometry.coordinates})
return new_path;
}
}
function showInfo(geoms__, elements_, prop){
var startX = -500, yOffset = 20;
//1. JOIN
var infos = svgInfos.selectAll('text').data(elements_, function(d) { return d; });
//2. UPDATE
infos.text(function (d,i){var props = geoms__[i].properties; return i + ". " + props.GEN + " has " + props.EWZ + " inhabitants!"}).transition().duration(duration)
.attr('y',function(d,i){return (i+1)*yOffset})
.attr('fill','#000')
//3. ENTER
infos.enter().append('text')
.attr('y',function(d,i){return (i+1)*yOffset})
.attr('x',startX)
.text(function (d,i){var props = geoms__[i].properties; return (i+1) + ". " + props.GEN + " has " + props.EWZ + " inhabitants!"})
.transition().duration(duration)
.attr('x',20)
.attr('fill','#f00');
//5. EXIT
infos.exit().transition().duration(duration).attr('x',startX).remove();
}
})
function sortPolygons(data, attrib){
//push all values to an array
if(attrib==='EWZ')var new_array = data.map(function(d){return d.properties.EWZ});
else if(attrib==='Area')var new_array = data.map(function(d){return d.properties.SHAPE_AREA});
else if(attrib==='Length')var new_array = data.map(function(d){return d.properties.LENGTH});
//sort the new array --> Help:http://www.javascriptkit.com/javatutors/arraysort.shtml
new_array=new_array.sort(function(a,b){return b - a});
//find the related attribute in the data an push it to a new data-array
var new_data = new_array.map(function(value){
var cache;
data.forEach(function(d){
if(attrib==='EWZ'){if(value===d.properties.EWZ)cache=d}
else if(attrib==='Area'){if(value===d.properties.SHAPE_AREA)cache=d}
else if(attrib==='Length'){if(value===d.properties.LENGTH)cache=d}
})
//return the found dataset to the new data-array
return cache;
})
//return the sorted data-array
return new_data;
}
//this projection normalizes the geometry...to fit into the div-svg
function normalize_projection(x) {
scaleLat.domain([bounds[0][0],bounds[1][0]])
.range([sWidth,0]);
scaleLng.domain([bounds[0][1],bounds[1][1]])
.range([sWidth,0]);
return [scaleLat(x[0]), scaleLng(x[1])]
}//[x[0]-bounds[1][0],x[1]-bounds[1][1]];}
</script>
</body>
</html>
Display the source blob
Display the rendered blob
Raw
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment