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
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment