block by fil 454f3daa9e8d9d47155495f78832ba77

Commutes 2012 - Oldskool style

Full Screen

This map shows the number of commuters to Dutch municipalities in 2012. Click on a municipality to see were the commuters working there are living.

Source: CBS Statline

Texture styling with [Textures.js] (http://riccardoscalco.github.io/textures/)

forked from allardw‘s block: Commutes 2012 - Oldskool style

See Françoise Bakhofen’s PhD https://halshs.archives-ouvertes.fr/tel-01273776 page 194-196 for a reference to Bertin 1973

index.html

<!DOCTYPE html>
<meta charset="utf-8">
<style>
  path.gems {
    fill: white;
    stroke: black;
    stroke-width: 0.24;
  }
</style>
<div id="viz"></div>
<script src="//d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="//d3js.org/queue.v1.min.js"></script>
<script src="textures.min.js"></script>
<script>
var width = 960,
  height = 500;

var svg = d3.select("#viz").append("svg")
  .attr("width",width)
  .attr("height",height)
  .attr("id", "root")
  .append("g")
    .call(d3.behavior.zoom().scaleExtent([1, 8]).on("zoom", zoom))
  .append("g");

var text = d3.select("#root").append("text")
  .text("Click on a municipality...")
  .attr("id","legend")
  .attr("transform","translate(10,15)");
	  
var path,
    banenByID;
    
var tl = textures.lines()
    .size(1.5)
    .strokeWidth(0.8)
    .background("white");

svg.call(tl);

var tc = textures.circles()
    .size(2)
    .radius(0.25)
    .background("white");
    
svg.call(tc);
  
var colours = ["#fef0d9","#fdd49e","#fdbb84", "#fc8d59", "#ef6548", "#d7301f", "#990000", "#990000"];

var heatmapColour = d3.scale.linear()
  .domain(d3.range(0, 1, 1.0 / (colours.length - 1)))
  .range(colours);
  
var c = d3.scale.linear().domain([0,10]).range([0,1]);  

queue()
  .defer(d3.json,"https://dl.dropboxusercontent.com/u/12712580/GIST/nlGem2012wgs.json")
  .defer(d3.tsv,"https://dl.dropboxusercontent.com/u/12712580/GIST/nlGemForens2012.tsv")
  .await(ready);
  
function ready(error, mapdata,_banen) {
  
  var gemIdByName = {};
  mapdata.features.forEach(function(d) {
    gemIdByName[d.properties.name] = d.properties.code;
  });
  
  banenByID = {};
  _banen.forEach(function(d) {
    banenByID[d.gemcode] = d;
  });
  
  var center = d3.geo.centroid(mapdata);
  var scale = 100;
  var offset = [width/2, height/2];
  var projection = d3.geo.mercator()
    .scale(scale)
    .center(center)
    .translate(offset);
    
    
  path = d3.geo.path()
    .projection(projection);
    
  var bounds  = path.bounds(mapdata);
  var hscale  = scale*width  / (bounds[1][0] - bounds[0][0]);
  var vscale  = scale*height / (bounds[1][1] - bounds[0][1]);
  var scale   = (hscale < vscale) ? hscale : vscale;
  var offset  = [width - (bounds[0][0] + bounds[1][0])/2,
    height -20 -(bounds[0][1] + bounds[1][1])/2];
    
  projection = d3.geo.mercator()
    .center(center)
    .scale(scale)
    .translate(offset);
    
  path = path.projection(projection);
  
  var cont = svg.append("g");  
  
  var conts = cont.selectAll(".cont")
    .data(mapdata.features)
   .enter().append("path")
    .attr("d", path)
    .attr("class","cont")
    .style("stroke","black")
    .style("stroke-width",2)
    .style("fill","white");
    
  var map = svg.append("g");  
  
  var gems = map.selectAll(".gems")
    .data(mapdata.features)
   .enter().append("path")
    .attr("d", path)
    .attr("class", function(d) {return "gems G"+pad(d.properties.GEMNR,4)})
    .on("mouseover",function(d){doIt(d)});
    
  var arrows = svg.selectAll("arrows")
    .data(mapdata.features).enter()
    .append("g")
    .attr("transform", function (d) {
      cx = path.centroid(d)[0];
      cy = path.centroid(d)[1];
      return "translate("+cx+","+cy+")"; });
      
  var arrow = arrows.append("g")
    .attr("class","a")
    .style("display", "none");
    
    
  arrow.append("path")
  	.attr("class",function (d) {return "arrow p" + d.properties.GEMNR})
    .attr("d", "M6 0 L1 0.5 L-6 0.5 L-6 -0.5 L1 -0.5 Z")
    .style("fill", "black");
  
};

function doIt(d) {
	  center = path.centroid(d);
      code = "G"+pad(d.properties.GEMNR,4);
      banen = banenByID[code];
         
      d3.selectAll(".gems")
      .transition()
        .style("fill", function(d) {
          co = "G"+pad(d.properties.GEMNR,4);
          b = path.bounds(d);
          v=banen[co];
          if (co == code) { color = tl.url()}
          else {color = (v=="" || v==0) ? "white":tc.url()};
          return color});
          
      d3.selectAll(".a")
        .style("display", function(d) {
        	co = "G"+pad(d.properties.GEMNR,4);
        	v=banen[co];
        	disp = (v=="" || v==0 || co == code) ? "none":"inline";
        	return disp})
        .call(compassAngle, center, 2000)
        .call(compassWidth,500);
      d3.select("#legend")
        .text(function() {return  "Commutes to "+d.properties.GEMNM})
}

function compassAngle(p, center, duration) {
	p.transition("compassAngle")
	  .duration(duration)
	  .ease("elastic-in")
	  .attr("transform", function(d) {return "rotate("+angleDeg(path.centroid(d),center)+")"});
}

function compassWidth(p, duration) {
	p.selectAll(".arrow").transition("compassWidth")
	  .duration(duration)
	  //.style("stroke-width", function(d) {return banen["G"+pad(d.properties.GEMNR,4)]})
	  .attr("transform", function(d) {
	  	v = banen["G"+pad(d.properties.GEMNR,4)];
	  	return "scale(1 " + v +")"});
}

function angleDeg(p1,p2) {
	return Math.atan2(p2[1] - p1[1], p2[0] - p1[0]) * 180 / Math.PI;
} 

function pad(num, size) {
    var s = num+"";
    while (s.length < size) s = "0" + s;
    return s;
}

function zoom() {
  svg.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
}
</script>

textures.min.js

(function(){var rand,umd,slice=[].slice;rand=function(){return(Math.random().toString(36)+"00000000000000000").replace(/[^a-z]+/g,"").slice(0,5)};umd=function(factory){if(typeof exports==="object"){return module.exports=factory()}else if(typeof define==="function"&&define.amd){return define([],factory)}else{return this.textures=factory()}};umd(function(){return{circles:function(){var background,circles,complement,fill,id,radius,size,stroke,strokeWidth;size=20;background="";radius=2;complement=false;fill="#343434";stroke="#343434";strokeWidth=0;id=rand();circles=function(){var corner,g,i,len,ref,results;g=this.append("defs").append("pattern").attr({id:id,patternUnits:"userSpaceOnUse",width:size,height:size});if(background){g.append("rect").attr({width:size,height:size,fill:background})}g.append("circle").attr({cx:size/2,cy:size/2,r:radius,fill:fill,stroke:stroke,"stroke-width":strokeWidth});if(complement){ref=[[0,0],[0,size],[size,0],[size,size]];results=[];for(i=0,len=ref.length;i<len;i++){corner=ref[i];results.push(g.append("circle").attr({cx:corner[0],cy:corner[1],r:radius,fill:fill,stroke:stroke,"stroke-width":strokeWidth}))}return results}};circles.heavier=function(_){if(!arguments.length){radius=radius*2}else{radius=_?radius*2*_:radius*2}return circles};circles.lighter=function(_){if(!arguments.length){radius=radius/2}else{radius=_?radius/(2*_):radius/2}return circles};circles.thinner=function(_){if(!arguments.length){size=size*2}else{size=_?size*2*_:size*2}return circles};circles.thicker=function(_){if(!arguments.length){size=size/2}else{size=_?size/(2*_):size/2}return circles};circles.background=function(_){background=_;return circles};circles.size=function(_){size=_;return circles};circles.complement=function(){complement=true;return circles};circles.radius=function(_){radius=_;return circles};circles.fill=function(_){fill=_;return circles};circles.stroke=function(_){stroke=_;return circles};circles.strokeWidth=function(_){strokeWidth=_;return circles};circles.id=function(_){if(!arguments.length){return id}else{id=_;return circles}};circles.url=function(){return"url(#"+id+")"};return circles},lines:function(){var background,id,lines,orientation,path,shapeRendering,size,stroke,strokeWidth;size=20;strokeWidth=2;stroke="#343434";id=rand();background="";orientation=["diagonal"];shapeRendering="auto";path=function(orientation){switch(orientation){case"0/8":return function(s){return"M "+s/2+", 0 l 0, "+s}(size);case"vertical":return function(s){return"M "+s/2+", 0 l 0, "+s}(size);case"1/8":return function(s){return"M "+s/4+",0 l "+s/2+","+s+" M "+-s/4+",0 l "+s/2+","+s+"\nM "+s*3/4+",0 l "+s/2+","+s}(size);case"2/8":return function(s){return"M 0,"+s+" l "+s+","+-s+" M "+-s/4+","+s/4+" l "+s/2+","+-s/2+"\nM "+3/4*s+","+5/4*s+" l "+s/2+","+-s/2}(size);case"diagonal":return function(s){return"M 0,"+s+" l "+s+","+-s+" M "+-s/4+","+s/4+" l "+s/2+","+-s/2+"\nM "+3/4*s+","+5/4*s+" l "+s/2+","+-s/2}(size);case"3/8":return function(s){return"M 0,"+3/4*s+" l "+s+","+-s/2+" M 0,"+s/4+" l "+s+","+-s/2+"\nM 0,"+s*5/4+" l "+s+","+-s/2}(size);case"4/8":return function(s){return"M 0,"+s/2+" l "+s+",0"}(size);case"horizontal":return function(s){return"M 0,"+s/2+" l "+s+",0"}(size);case"5/8":return function(s){return"M 0,"+-s/4+" l "+s+","+s/2+"M 0,"+s/4+" l "+s+","+s/2+"\nM 0,"+s*3/4+" l "+s+","+s/2}(size);case"6/8":return function(s){return"M 0,0 l "+s+","+s+" M "+-s/4+","+3/4*s+" l "+s/2+","+s/2+"\nM "+s*3/4+","+-s/4+" l "+s/2+","+s/2}(size);case"7/8":return function(s){return"M "+-s/4+",0 l "+s/2+","+s+" M "+s/4+",0 l "+s/2+","+s+"\nM "+s*3/4+",0 l "+s/2+","+s}(size);default:return function(s){return"M "+s/2+", 0 l 0, "+s}(size)}};lines=function(){var g,i,len,o,results;g=this.append("defs").append("pattern").attr({id:id,patternUnits:"userSpaceOnUse",width:size,height:size});if(background){g.append("rect").attr({width:size,height:size,fill:background})}results=[];for(i=0,len=orientation.length;i<len;i++){o=orientation[i];results.push(g.append("path").attr({d:path(o),"stroke-width":strokeWidth,"shape-rendering":shapeRendering,stroke:stroke,"stroke-linecap":"square"}))}return results};lines.background=function(_){background=_;return lines};lines.shapeRendering=function(_){shapeRendering=_;return lines};lines.heavier=function(_){if(!arguments.length){strokeWidth=strokeWidth*2}else{strokeWidth=_?strokeWidth*2*_:strokeWidth*2}return lines};lines.lighter=function(_){if(!arguments.length){strokeWidth=strokeWidth/2}else{strokeWidth=_?strokeWidth/(2*_):strokeWidth/2}return lines};lines.thinner=function(_){if(!arguments.length){size=size*2}else{size=_?size*2*_:size*2}return lines};lines.thicker=function(_){if(!arguments.length){size=size/2}else{size=_?size/(2*_):size/2}return lines};lines.orientation=function(){var args;args=1<=arguments.length?slice.call(arguments,0):[];orientation=args;return lines};lines.size=function(_){size=_;return lines};lines.stroke=function(_){stroke=_;return lines};lines.strokeWidth=function(_){strokeWidth=_;return lines};lines.id=function(_){if(!arguments.length){return id}else{id=_;return lines}};lines.url=function(){return"url(#"+id+")"};return lines},paths:function(){var background,d,fill,height,id,paths,shapeRendering,size,stroke,strokeWidth,svgPath,width;size=20;height=1;width=1;strokeWidth=2;stroke="#343434";background="";d="";shapeRendering="auto";fill="transparent";id=void 0;svgPath=function(_){switch(_){case"squares":return function(s){return"M "+s/4+" "+s/4+" l "+s/2+" 0 l 0 "+s/2+" l "+-s/2+" 0 Z"}(size);case"nylon":return function(s){return"M 0 "+s/4+" l "+s/4+" 0 l 0 "+-s/4+" M "+s*3/4+" "+s+" l 0 "+-s/4+"\nl "+s/4+" 0 M "+s/4+" "+s/2+" l 0 "+s/4+" l "+s/4+" 0 M "+s/2+" "+s/4+"\nl "+s/4+" 0 l 0 "+s/4}(size);case"waves":return function(s){return"M 0 "+s/2+" c "+s/8+" "+-s/4+" , "+s*3/8+" "+-s/4+" , "+s/2+" 0\nc "+s/8+" "+s/4+" , "+s*3/8+" "+s/4+" , "+s/2+" 0 M "+-s/2+" "+s/2+"\nc "+s/8+" "+s/4+" , "+s*3/8+" "+s/4+" , "+s/2+" 0 M "+s+" "+s/2+"\nc "+s/8+" "+-s/4+" , "+s*3/8+" "+-s/4+" , "+s/2+" 0"}(size);case"woven":return function(s){return"M "+s/4+","+s/4+"l"+s/2+","+s/2+"M"+s*3/4+","+s/4+"l"+s/2+","+-s/2+"\nM"+s/4+","+s*3/4+"l"+-s/2+","+s/2+"M"+s*3/4+","+s*5/4+"l"+s/2+","+-s/2+"\nM"+-s/4+","+s/4+"l"+s/2+","+-s/2}(size);case"crosses":return function(s){return"M "+s/4+","+s/4+"l"+s/2+","+s/2+"M"+s/4+","+s*3/4+"l"+s/2+","+-s/2}(size);case"caps":return function(s){return"M "+s/4+","+s*3/4+"l"+s/4+","+-s/2+"l"+s/4+","+s/2}(size);case"hexagons":return function(s){width=3;height=Math.sqrt(3);return"M "+s+",0 l "+s+",0 l "+s/2+","+s*Math.sqrt(3)/2+"\nl "+-s/2+","+s*Math.sqrt(3)/2+" l "+-s+",0\nl "+-s/2+","+-s*Math.sqrt(3)/2+" Z M 0,"+s*Math.sqrt(3)/2+"\nl "+s/2+",0 M "+3*s+","+s*Math.sqrt(3)/2+" l "+-s/2+",0"}(size);default:return _(size)}};paths=function(){var g,path;path=svgPath(d);id=rand();g=this.append("defs").append("pattern").attr({id:id,patternUnits:"userSpaceOnUse",width:size*width,height:size*height});if(background){g.append("rect").attr({width:size*width,height:size*height,fill:background})}return g.append("path").attr({d:path,fill:fill,"stroke-width":strokeWidth,"shape-rendering":shapeRendering,stroke:stroke,"stroke-linecap":"square"})};paths.background=function(_){background=_;return paths};paths.shapeRendering=function(_){shapeRendering=_;return paths};paths.heavier=function(_){if(!arguments.length){strokeWidth=strokeWidth*2}else{strokeWidth=_?strokeWidth*2*_:strokeWidth*2}return paths};paths.lighter=function(_){if(!arguments.length){strokeWidth=strokeWidth/2}else{strokeWidth=_?strokeWidth/(2*_):strokeWidth/2}return paths};paths.thinner=function(_){if(!arguments.length){size=size*2}else{size=_?size*2*_:size*2}return paths};paths.thicker=function(_){if(!arguments.length){size=size/2}else{size=_?size/(2*_):size/2}return paths};paths.d=function(_){d=_;return paths};paths.size=function(_){size=_;return paths};paths.stroke=function(_){stroke=_;return paths};paths.strokeWidth=function(_){strokeWidth=_;return paths};paths.id=function(_){if(!arguments.length){return id}else{id=_;return paths}};paths.url=function(){return"url(#"+id+")"};return paths}}})}).call(this);