Skip to content

Instantly share code, notes, and snippets.

@gabrielflorit
Last active June 21, 2017 20:52
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gabrielflorit/f822f40b7f20e019f381e3a266280bde to your computer and use it in GitHub Desktop.
Save gabrielflorit/f822f40b7f20e019f381e3a266280bde to your computer and use it in GitHub Desktop.
Lat/lon histogram
license: mit
height: 720
border: no

Lat/lon histogram

Made with blockup.

Display the source blob
Display the rendered blob
Raw
{"type":"Topology","arcs":[[[9769,0],[84,78],[46,-45],[-130,-33]],[[0,7510],[18,70],[153,-72],[147,-17],[46,21],[58,-58],[0,37],[27,10],[34,-81],[-46,-66],[-2,49],[-76,-152],[63,17],[-55,-6],[130,168],[18,-52],[-19,-3],[17,-52],[-15,-9],[11,-14],[-18,-59],[6,-13],[-12,-21],[-22,21],[15,29],[-21,-15],[5,-65],[-27,76],[-10,-30],[1,-33],[41,-20],[20,24],[15,36],[-5,8],[24,-16],[27,26],[-24,99],[47,114],[-39,67],[-19,-17],[27,-38],[-35,25],[-4,37],[36,12],[-42,50],[-35,6],[24,19],[30,-17],[-14,34],[25,7],[-25,56],[-18,-26],[-14,13],[-33,66],[14,19],[826,0],[893,-1],[844,0],[924,0],[925,0],[1026,1],[845,-1],[1,123],[44,-5],[32,-15],[39,-184],[183,-36],[11,-36],[123,40],[68,-4],[73,-28],[-18,-25],[58,-16],[20,-61],[25,42],[47,2],[22,-40],[91,-40],[-2,-21],[68,12],[87,53],[30,-50],[139,7],[56,-39],[93,8],[-314,-145],[-279,-245],[30,-34],[252,89],[24,-23],[-46,-93],[49,30],[68,-41],[147,82],[86,8],[100,50],[126,117],[112,35],[49,-25],[-55,-4],[-62,-60],[-61,-141],[80,67],[-32,-46],[46,31],[60,-9],[51,-35],[52,-87],[81,8],[37,-32],[34,2],[5,39],[21,-31],[96,65],[149,2],[118,31],[-6,-93],[88,1],[10,-22],[104,37],[7,-87],[-35,-26],[29,1],[57,-59],[25,8],[-12,29],[54,-6],[24,-32],[-12,-23],[-133,19],[-60,-15],[-64,39],[-21,-69],[-61,56],[-110,27],[-45,-44],[-132,-5],[-77,-107],[-23,22],[40,68],[-55,-9],[-41,-60],[-16,52],[-129,-219],[-7,-54],[-43,-9],[-37,-73],[-14,-49],[23,-12],[76,99],[51,8],[33,96],[59,39],[-111,-235],[-10,-114],[-47,-81],[3,-80],[-47,-139],[33,-148],[-14,-164],[69,-178],[46,-28],[146,71],[82,148],[24,194],[-74,222],[25,63],[-19,77],[56,92],[3,110],[38,16],[5,52],[59,14],[61,83],[-26,-115],[12,-27],[28,72],[-11,-77],[30,58],[5,108],[104,39],[-46,47],[39,54],[-14,17],[62,8],[62,-43],[56,-6],[27,-44],[163,-72],[26,-78],[-43,2],[42,-101],[-14,-119],[-47,-29],[-10,-61],[-67,-31],[-17,-67],[61,-51],[47,40],[10,54],[20,-5],[-14,16],[112,48],[62,-69],[52,-279],[-24,-115],[-38,-31],[14,48],[-43,-9],[-18,-80],[-46,-31],[-9,-65],[-73,-114],[119,-68],[23,23],[80,-65],[107,42],[62,-8],[103,86],[218,88],[268,165],[68,75],[-51,91],[1,59],[160,36],[139,-11],[47,-33],[135,10],[123,80],[42,3],[-14,104],[38,19],[-58,39],[16,51],[91,54],[209,194],[795,11],[14,72],[36,20],[34,-18],[28,32],[35,-37],[13,63],[37,-14],[-20,41],[106,120],[-8,96],[54,71],[14,89],[175,244],[42,-11],[-2,-54],[34,-25],[140,58],[113,-93],[-6,-437],[88,-35],[-14,-97],[33,-49],[14,21],[29,-10],[47,-110],[-71,-67],[-8,32],[-22,-4],[6,-21],[-47,-21],[15,-20],[-18,-16],[-41,32],[-64,-69],[-30,17],[-4,-47],[-46,5],[5,57],[-42,-9],[-9,-124],[-29,60],[12,20],[-34,15],[5,68],[-44,-32],[-18,-144],[-56,-37],[6,24],[-20,-11],[-10,19],[-17,-38],[-46,-5],[-29,-38],[-21,25],[-55,-34],[-57,-100],[-31,-12],[-60,-141],[9,-59],[42,-17],[-63,-30],[-31,-84],[28,9],[36,-32],[20,-41],[-17,-26],[68,-81],[35,-10],[57,28],[-20,74],[-34,10],[43,-8],[27,-73],[-12,-85],[-4,41],[-78,-12],[-136,-72],[66,43],[8,52],[-22,9],[-53,-70],[-55,-18],[-11,51],[0,-46],[-25,-7],[18,53],[18,18],[-21,-12],[-22,47],[-23,-132],[-242,-38],[-79,-2],[-4,17],[-45,-47],[-121,-47],[-32,-66],[68,48],[58,-13],[27,21],[108,3],[81,57],[-9,-23],[49,-30],[56,25],[-314,-142],[-160,-26],[-24,47],[-4,-32],[-47,-32],[65,-13],[-26,-218],[-174,-262],[-25,0],[19,69],[-60,10],[-87,86],[6,72],[-18,-11],[0,-60],[42,-66],[0,-60],[48,-83],[23,-3],[10,-110],[-38,-124],[-70,-84],[-33,-114],[-66,-113],[-16,55],[20,98],[63,126],[-54,-11],[16,66],[-30,1],[26,24],[-16,16],[12,31],[-24,-40],[-7,45],[-7,-50],[-51,34],[-18,53],[20,10],[-7,28],[57,-14],[-48,54],[-25,-16],[11,45],[24,-2],[-4,37],[-37,-28],[14,59],[34,-11],[4,29],[-20,-23],[-9,46],[23,54],[39,11],[7,60],[-29,-6],[8,-29],[-37,-30],[-6,31],[-7,-48],[-17,30],[3,-43],[-23,-20],[-32,21],[43,-80],[-37,-77],[54,-233],[-27,40],[-8,-19],[-26,36],[-47,7],[-7,35],[-3,-29],[-18,11],[-22,49],[-53,-20],[-3,42],[35,38],[-32,1],[-16,-80],[18,-17],[45,22],[18,-59],[79,-21],[86,-83],[-23,-74],[13,-13],[-18,-1],[-34,10],[-95,108],[88,-116],[55,-18],[-14,-13],[22,-12],[-3,-55],[-31,29],[15,-40],[-35,-13],[48,-34],[-3,-40],[-28,-10],[-51,80],[-68,3],[48,-27],[12,17],[5,-49],[44,-52],[35,1],[4,26],[69,-14],[105,-364],[-103,238],[44,-145],[-29,55],[4,-25],[-64,42],[28,-49],[-48,14],[13,-29],[-53,31],[33,-32],[-63,-27],[-32,44],[6,42],[-13,-42],[14,-64],[143,15],[7,-109],[19,98],[22,6],[31,-90],[-99,-117],[-76,14],[-23,44],[26,15],[-37,-15],[12,-39],[-101,41],[127,-76],[-30,-66],[-46,-33],[-42,30],[2,-17],[49,-27],[68,49],[15,-32],[25,10],[-54,-103],[-18,33],[-16,-23],[34,-20],[111,130],[-114,-150],[-32,33],[-71,-7],[-129,-80],[-62,-81],[-32,-102],[-94,19],[-98,-51],[-62,-82],[-23,-99],[-40,-53],[-45,4],[-4,-36],[-34,-32],[-45,-8],[9,-31],[-26,-25],[-108,-34],[2,-57],[-40,-20],[-26,16],[19,-28],[-53,-53],[14,-16],[-24,-33],[-27,-7],[0,-34],[-31,-16],[16,-30],[-29,-24],[19,-10],[-26,-98],[-46,-74],[20,-6],[-10,-145],[65,-301],[145,-349],[-18,-39],[9,-77],[122,-413],[-22,-326],[-7,-34],[-9,25],[-24,-42],[-15,-104],[44,64],[-42,-106],[-48,-64],[-22,-14],[39,44],[7,52],[-140,-29],[-48,181],[-74,66],[-17,-13],[-41,167],[-43,54],[-11,-21],[-17,63],[20,-5],[7,91],[-25,-11],[6,-40],[-27,-22],[-109,260],[21,-5],[57,114],[-17,15],[1,-34],[-19,9],[0,37],[-31,20],[-6,-29],[30,-39],[-33,-64],[-27,79],[-2,113],[17,-51],[27,136],[-5,134],[-27,77],[-56,-5],[-6,39],[-73,84],[-3,48],[-61,79],[-73,57],[-58,2],[-25,-30],[4,-36],[-37,7],[-86,-62],[-4,20],[-49,-22],[25,-30],[73,45],[-81,-56],[-70,23],[-14,58],[17,-48],[6,45],[-62,71],[-162,98],[-103,9],[-291,-54],[62,17],[-34,42],[-3,73],[-20,15],[-29,-116],[-179,23],[-84,-28],[-10,22],[-29,-63],[-90,-54],[45,-45],[40,68],[25,-7],[-13,-21],[14,-25],[35,19],[-24,-27],[19,-3],[-33,-12],[25,-26],[-26,10],[-11,-42],[-20,22],[8,-34],[-45,-1],[40,-73],[73,-13],[18,-46],[24,-7],[-24,-8],[16,-6],[-23,-46],[-25,29],[-38,-48],[28,85],[-22,-24],[-56,53],[-47,9],[-86,-74],[-19,58],[-22,-11],[-10,37],[-96,-93],[-21,40],[-78,27],[15,33],[26,-38],[-2,28],[-24,31],[-22,-14],[-5,38],[-24,-13],[-21,51],[-22,1],[6,32],[-59,-7],[12,37],[-84,-24],[21,-45],[20,1],[-60,-26],[-204,75],[-67,0],[-142,-35],[-151,-95],[58,58],[-63,-4],[20,52],[-14,28],[-31,-39],[-17,13],[-12,-46],[25,-19],[4,-60],[-61,-38],[-1,-24],[81,76],[20,-7],[-151,-148],[-190,-119],[-114,-104],[-112,-181],[-38,-198],[48,-285],[-26,148],[-20,4],[15,8],[-22,99],[9,147],[63,178],[151,160],[-56,-34],[-23,32],[-7,-59],[-31,-32],[-23,20],[-40,-31],[43,6],[-37,-90],[-75,14],[59,-55],[-34,-116],[-29,-17],[7,28],[-31,-36],[49,4],[-5,-209],[38,-107],[-3,-53],[32,-14],[1,-29],[-63,-41],[-52,57],[-124,11],[-58,52],[-50,6],[-31,42],[-63,9],[-42,142],[-41,57],[-15,173],[-75,63],[-20,69],[-81,93],[-88,263],[-88,114],[-44,20],[0,33],[-12,-15],[-25,57],[-159,11],[-47,28],[-15,-36],[-66,-9],[-47,-124],[4,-39],[-29,-15],[-28,-62],[-71,18],[-139,89],[-107,101],[-95,308],[-106,79],[-128,162],[-57,33],[-56,95],[-400,6],[0,-144],[-652,0],[-851,370],[21,71],[-548,-59],[-78,243],[-151,145],[-63,-3],[-25,91],[-65,-9],[-74,32],[-98,99],[-207,11],[-38,38],[-2,183],[-48,21],[-6,71],[-91,78],[-50,103],[-88,97],[-20,88],[37,33],[-11,79],[-55,7],[-68,77],[-26,108],[9,87],[21,-6],[2,-59],[76,-47],[-88,161],[36,35],[-50,12],[12,-73],[-21,-20],[-74,63],[-38,-7],[10,87],[-170,207],[-29,291],[-116,136],[-11,56],[62,156],[17,163],[-44,109],[12,64],[-35,42],[-10,163],[-34,68],[93,355],[46,543],[-19,180],[39,-23],[70,35],[-122,1],[3,116],[24,-82],[1,83],[29,23],[-59,10],[-11,52],[15,-14],[48,28],[-59,30],[-13,-37],[-56,258],[-47,49],[-23,89]]],"transform":{"scale":[0.004393337667274939,0.003142808130699088],"translate":[-124.731746,24.568745]},"objects":{"boundary":{"type":"GeometryCollection","geometries":[{"type":"MultiLineString","arcs":[[0],[1]],"properties":{"TYPE":0}}]}}}
.buttons{margin:0 auto;text-align:center}.map svg{display:block;margin:0 auto}.map svg circle{fill:#8f092a;fill-opacity:.25;stroke:#8f092a}
var margin={top:10,right:10,bottom:10,left:10};d3.json("./boundary.topojson",function(t){var n=topojson.feature(t,t.objects.boundary),e=(d3.geoBounds(n),d3.geoCentroid(n),d3.geoAlbers()),r=d3.geoPath().projection(e),o=r.bounds(n),a=(o[1][0]-o[0][0])/(o[1][1]-o[0][1]),i=460,u=i*a,c=u-margin.left-margin.right,f=i-margin.top-margin.bottom,l=d3.select(".map svg").attrs({width:u,height:i}).append("g").attr("transform","translate("+margin.left+", "+margin.top+")");e.fitSize([c,f],n);var d=_(n.features).map("geometry").flatten().map("coordinates").flatten().sortBy("length").map(function(t){return turf.lineString(t)}).value(),s=_(d).map(function(t){return turf.lineDistance(t)}).sum(),m=1e3,g=m,p=_(d).map(function(t){var n=turf.lineDistance(t),e=Math.ceil(n*m/s),r=Math.min(g,e);g-=r;var o=n/r,a=d3.range(r).map(function(n){return turf.along(t,n*o)});return a}).flatten().map(function(t){return e(t.geometry.coordinates)}).map(function(t,n){return{index:n,x2:t[0],y2:t[1]}}).value(),y=5,x=_(p).groupBy(function(t){return Math.round(t.y2/y)*y}).map(function(t,n){return _(t).sortBy("x2").map(function(e,r){return{index:e.index,x1:c/2+4*r-4*t.length/2,y1:+n,x2:e.x2,y2:e.y2}}).value()}).flatten().value(),v=function(){var t=l.selectAll("circle").data(x,function(t){return t.index});t.enter().append("circle").attrs({cx:function(t){return t.x1},cy:function(t){return t.y1},r:1}).merge(t).transition("enter").duration(1e3).delay(function(t,n){return 10*n}).attrs({cx:function(t){return t.x2},cy:function(t){return t.y2},r:1})},h=function(){var t=l.selectAll("circle").data(x,function(t){return t.index});t.transition("exit").duration(250).delay(function(t,n){return 2*n}).attrs({cx:function(t){return t.x1},cy:function(t){return t.y1},r:1})};v(),document.querySelector("button.enter").addEventListener("click",v),document.querySelector("button.exit").addEventListener("click",h)});
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInNjcmlwdC5qcyJdLCJuYW1lcyI6WyJjb25zdCIsIm1hcmdpbiIsInRvcCIsInJpZ2h0IiwiYm90dG9tIiwibGVmdCIsImQzIiwianNvbiIsImZlYXR1cmUiLCJ0b3BvanNvbiIsIm9iamVjdHMiLCJib3VuZGFyeSIsInByb2plY3Rpb24iLCJnZW9Cb3VuZHMiLCJnZW9DZW50cm9pZCIsImdlb0FsYmVycyIsInBhdGgiLCJnZW9QYXRoIiwiYiIsImJvdW5kcyIsImFzcGVjdCIsIm91dGVySGVpZ2h0Iiwib3V0ZXJXaWR0aCIsIndpZHRoIiwiaGVpZ2h0IiwiZyIsInNlbGVjdCIsImF0dHJzIiwiYXBwZW5kIiwiYXR0ciIsImZpdFNpemUiLCJsaW5lU3RyaW5ncyIsIl8iLCJmZWF0dXJlcyIsIm1hcCIsImZsYXR0ZW4iLCJzb3J0QnkiLCJkIiwidHVyZiIsImxpbmVTdHJpbmciLCJ2YWx1ZSIsInRvdGFsTGVuZ3RoIiwibGluZURpc3RhbmNlIiwic3VtIiwicG9pbnRzQ291bnQiLCJwb2ludHNSZW1haW5pbmciLCJwb2ludHMiLCJsaW5lIiwibGluZUxlbmd0aCIsInVwcGVyQ291bnQiLCJNYXRoIiwiY2VpbCIsImxpbmVQb2ludHNDb3VudCIsIm1pbiIsInN0ZXAiLCJsaW5lUG9pbnRzIiwicmFuZ2UiLCJhbG9uZyIsImdlb21ldHJ5IiwiY29vcmRpbmF0ZXMiLCJpbmRleCIsIngyIiwieTIiLCJ5U3RlcCIsImhpc3RvZ3JhbSIsImdyb3VwQnkiLCJyb3VuZCIsImtleSIsImkiLCJ4MSIsImxlbmd0aCIsInkxIiwiZW50ZXIiLCJjaXJjbGVzIiwic2VsZWN0QWxsIiwiZGF0YSIsImN4IiwiY3kiLCJyIiwibWVyZ2UiLCJ0cmFuc2l0aW9uIiwiZHVyYXRpb24iLCJkZWxheSIsImV4aXQiLCJkb2N1bWVudCIsInF1ZXJ5U2VsZWN0b3IiLCJhZGRFdmVudExpc3RlbmVyIl0sIm1hcHBpbmdzIjoiQUFDQUEsR0FBTUMsU0FBV0MsSUFBTyxHQUFFQyxNQUFTLEdB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LEdBQUEsTUFBQUEsR0FBQXdCLElBQ0pnQixHQUFJLFNBQUF4QyxHQUFBLE1BQUFBLEdBQUF5QixJQUNKZ0IsRUFBQyxLQUtDSyxFQUFPLFdBR1puRixHQUNHeUUsR0FBS2hELEVBQVNpRCxVQUFFLFVBQWhCQyxLQUFLWCxFQUFXLFNBQUEzQixHQUFFLE1BQUdBLEdBQUV1QixPQUcxQmEsR0FDRU8sV0FDVSxRQUNUQyxTQUFNLEtBQ05DLE1BQU0sU0FBQTdDLEVBQUErQixHQUFBLE1BQUEsR0FBQUEsSUFDTnpDLE9BQ0FpRCxHQUFJLFNBQUF2QyxHQUFBLE1BQUFBLEdBQUFnQyxJQUNKUSxHQUFJLFNBQUF4QyxHQUFBLE1BQUFBLEdBQUFrQyxJQUNKTyxFQUFDLElBS0xOLEtBSUFZLFNBQVNDLGNBQWMsZ0JBQWVDLGlCQUFpQixRQUFTZCxHQUFoRVksU0FBU0MsY0FBYyxlQUFlQyxpQkFBaUIsUUFBU0giLCJmaWxlIjoic2NyaXB0LmpzIiwic291cmNlc0NvbnRlbnQiOlsiLy8gU2V0dXAgY2hhcnQgZGltZW5zaW9ucy5cbmNvbnN0IG1hcmdpbiA9IHsgdG9wOiAxMCwgcmlnaHQ6IDEwLCBib3R0b206IDEwLCBsZWZ0OiAxMCB9XG5cbi8vIEdldCBHZW9KU09OLlxuZDMuanNvbignLi9ib3VuZGFyeS50b3BvanNvbicsIGpzb24gPT4ge1xuXG5cdGNvbnN0IGZlYXR1cmUgPSB0b3BvanNvbi5mZWF0dXJlKGpzb24sIGpzb24ub2JqZWN0cy5ib3VuZGFyeSlcblxuXHQvLyBHZXQgZmVhdHVyZSdzIGJvdW5kcywgY2VudHJvaWQsIGFuZCBwcm9qZWN0aW9uLlxuXHRjb25zdCBib3VuZHMgPSBkMy5nZW9Cb3VuZHMoZmVhdHVyZSlcblx0Y29uc3QgY2VudHJvaWQgPSBkMy5nZW9DZW50cm9pZChmZWF0dXJlKVxuXHRjb25zdCBwcm9qZWN0aW9uID0gZDMuZ2VvQWxiZXJzKClcblxuXHQvLyBHZXQgdGhlIHBhdGguXG5cdGNvbnN0IHBhdGggPSBkMy5nZW9QYXRoKCkucHJvamVjdGlvbihwcm9qZWN0aW9uKVxuXG5cdC8vIEdldCB0aGUgcGF0aCdzIGJvdW5kcyAoaS5lLiwgaW4gcGl4ZWxzKS5cblx0Y29uc3QgYiA9IHBhdGguYm91bmRzKGZlYXR1cmUpXG5cblx0Ly8gR2V0IGFzcGVjdCByYXRpby5cblx0Y29uc3QgYXNwZWN0ID0gKGJbMV1bMF0gLSBiWzBdWzBdKSAvIChiWzFdWzFdIC0gYlswXVsxXSlcblxuXHRjb25zdCBvdXRlckhlaWdodCA9IDQ2MFxuXHRjb25zdCBvdXRlcldpZHRoID0gb3V0ZXJIZWlnaHQgKiBhc3BlY3RcblxuXHRjb25zdCB3aWR0aCA9IG91dGVyV2lkdGggLSBtYXJnaW4ubGVmdCAtIG1hcmdpbi5yaWdodFxuXHRjb25zdCBoZWlnaHQgPSBvdXRlckhlaWdodCAtIG1hcmdpbi50b3AgLSBtYXJnaW4uYm90dG9tXG5cblx0Ly8gUHJlcGFyZSBzdmcuXG5cdGNvbnN0IGcgPSBkMy5zZWxlY3QoJy5tYXAgc3ZnJylcblx0XHRcdC5hdHRycyh7IHdpZHRoOiBvdXRlcldpZHRoLCBoZWlnaHQ6IG91dGVySGVpZ2h0IH0pXG5cdFx0LmFwcGVuZCgnZycpXG5cdFx0XHQuYXR0cigndHJhbnNmb3JtJywgYHRyYW5zbGF0ZSgke21hcmdpbi5sZWZ0fSwgJHttYXJnaW4udG9wfSlgKVxuXG5cdC8vIEZpdCB0aGUgZmVhdHVyZSB0byB0aGUgY29udGFpbmVyJ3Mgd2lkdGguXG5cdHByb2plY3Rpb24uZml0U2l6ZShbd2lkdGgsIGhlaWdodF0sIGZlYXR1cmUpXG5cblx0Ly8gR2V0IHRoZSBpbmRpdmlkdWFsIGxpbmUgc3RyaW5ncy5cblx0Y29uc3QgbGluZVN0cmluZ3MgPSBfKGZlYXR1cmUuZmVhdHVyZXMpXG5cdFx0Lm1hcCgnZ2VvbWV0cnknKVxuXHRcdC5mbGF0dGVuKClcblx0XHQubWFwKCdjb29yZGluYXRlcycpXG5cdFx0LmZsYXR0ZW4oKVxuXHRcdC5zb3J0QnkoJ2xlbmd0aCcpXG5cdFx0Lm1hcChkID0+IHR1cmYubGluZVN0cmluZyhkKSlcblx0XHQudmFsdWUoKVxuXG5cdC8vIENhbGN1bGF0ZSB0aGUgb3ZlcmFsbCBsaW5lIHN0cmluZyBsZW5ndGguXG5cdGNvbnN0IHRvdGFsTGVuZ3RoID0gXyhsaW5lU3RyaW5ncylcblx0XHQubWFwKGQgPT4gdHVyZi5saW5lRGlzdGFuY2UoZCkpXG5cdFx0LnN1bSgpXG5cblx0Ly8gRGVzaXJlZCBudW1iZXIgb2YgdG90YWwgcG9pbnRzLlxuXHRjb25zdCBwb2ludHNDb3VudCA9IDEwMDBcblx0bGV0IHBvaW50c1JlbWFpbmluZyA9IHBvaW50c0NvdW50XG5cblx0Y29uc3QgcG9pbnRzID0gXyhsaW5lU3RyaW5ncylcblx0XHQubWFwKGxpbmUgPT4ge1xuXG5cdFx0XHQvLyBIb3cgbWFueSBwb2ludHMgd2lsbCB0aGlzIGxpbmUgZ2V0P1xuXG5cdFx0XHQvLyBGaXJzdCwgY2FsY3VsYXRlIHRoaXMgbGluZSdzIGxlbmd0aC5cblx0XHRcdGNvbnN0IGxpbmVMZW5ndGggPSB0dXJmLmxpbmVEaXN0YW5jZShsaW5lKVxuXG5cdFx0XHQvLyBOZXh0LCBnZXQgdGhpcyBsaW5lJ3MgcG9pbnRzIHByb3BvcnRpb24sIHJvdW5kZWQgdXAuXG5cdFx0XHRjb25zdCB1cHBlckNvdW50ID0gTWF0aC5jZWlsKGxpbmVMZW5ndGggKiBwb2ludHNDb3VudCAvIHRvdGFsTGVuZ3RoKVxuXG5cdFx0XHQvLyBEb24ndCBnZXQgbW9yZSBwb2ludHMgdGhhdCBhcmUgYXZhaWxhYmxlLlxuXHRcdFx0Y29uc3QgbGluZVBvaW50c0NvdW50ID0gTWF0aC5taW4ocG9pbnRzUmVtYWluaW5nLCB1cHBlckNvdW50KVxuXG5cdFx0XHQvLyBNYWtlIHN1cmUgdG8gdXBkYXRlIHBvaW50cyByZW1haW5pbmcuXG5cdFx0XHRwb2ludHNSZW1haW5pbmcgLT0gbGluZVBvaW50c0NvdW50XG5cblx0XHRcdC8vIE5vdyB0aGF0IHdlIGtub3cgaG93IG1hbnkgcG9pbnRzIHRoaXMgbGluZSB3aWxsIGdldCxcblx0XHRcdC8vIGNhbGN1bGF0ZSB0aGUgZGlzdGFuY2UgYmV0d2VlbiBwb2ludHMgLSB0aGUgc3RlcDpcblx0XHRcdGNvbnN0IHN0ZXAgPSBsaW5lTGVuZ3RoIC8gbGluZVBvaW50c0NvdW50XG5cblx0XHRcdGNvbnN0IGxpbmVQb2ludHMgPSBkMy5yYW5nZShsaW5lUG9pbnRzQ291bnQpXG5cdFx0XHRcdC5tYXAoZCA9PiB0dXJmLmFsb25nKGxpbmUsIGQgKiBzdGVwKSlcblxuXHRcdFx0cmV0dXJuIGxpbmVQb2ludHNcblxuXHRcdH0pXG5cdFx0LmZsYXR0ZW4oKVxuXHRcdC5tYXAoZCA9PiBwcm9qZWN0aW9uKGQuZ2VvbWV0cnkuY29vcmRpbmF0ZXMpKVxuXHRcdC5tYXAoKGQsIGluZGV4KSA9PiAoe1xuXHRcdFx0aW5kZXgsXG5cdFx0XHR4MjogZFswXSxcblx0XHRcdHkyOiBkWzFdLFxuXHRcdH0pKVxuXHRcdC52YWx1ZSgpXG5cblx0Y29uc3QgeVN0ZXAgPSA1XG5cblx0Y29uc3QgaGlzdG9ncmFtID0gXyhwb2ludHMpXG5cdFx0Lmdyb3VwQnkoZCA9PiBNYXRoLnJvdW5kKGQueTIgLyB5U3RlcCkgKiB5U3RlcClcblx0XHQubWFwKCh2YWx1ZSwga2V5KSA9PlxuXHRcdFx0Xyh2YWx1ZSlcblx0XHRcdFx0LnNvcnRCeSgneDInKVxuXHRcdFx0XHQubWFwKChkLCBpKSA9PiAoe1xuXHRcdFx0XHRcdGluZGV4OiBkLmluZGV4LFxuXHRcdFx0XHRcdHgxOiAoKHdpZHRoIC8gMikgKyAoaSAqIDQpKSAtICh2YWx1ZS5sZW5ndGggKiA0KS8yLFxuXHRcdFx0XHRcdHkxOiAra2V5LFxuXHRcdFx0XHRcdHgyOiBkLngyLFxuXHRcdFx0XHRcdHkyOiBkLnkyLFxuXHRcdFx0XHR9KSlcblx0XHRcdFx0LnZhbHVlKCkpXG5cdFx0LmZsYXR0ZW4oKVxuXHRcdC52YWx1ZSgpXG5cblx0Ly8gVGhpcyBmdW5jdGlvbiBhZGRzIHRoZSBjaXJjbGVzLlxuXHRjb25zdCBlbnRlciA9ICgpID0+IHtcblxuXHRcdC8vIEpPSU4gbmV3IGRhdGEgd2l0aCBvbGQgZWxlbWVudHMuXG5cdFx0Y29uc3QgY2lyY2xlcyA9IGcuc2VsZWN0QWxsKCdjaXJjbGUnKVxuXHRcdFx0LmRhdGEoaGlzdG9ncmFtLCBkID0+IGQuaW5kZXgpXG5cblx0XHQvLyBFTlRFUiBuZXcgZWxlbWVudHMgcHJlc2VudCBpbiBuZXcgZGF0YS5cblx0XHRjaXJjbGVzLmVudGVyKCkuYXBwZW5kKCdjaXJjbGUnKVxuXHRcdFx0XHQuYXR0cnMoe1xuXHRcdFx0XHRcdGN4OiBkID0+IGQueDEsXG5cdFx0XHRcdFx0Y3k6IGQgPT4gZC55MSxcblx0XHRcdFx0XHRyOiAxLFxuXHRcdFx0XHR9KVxuXHRcdFx0Lm1lcmdlKGNpcmNsZXMpXG5cdFx0XHQudHJhbnNpdGlvbignZW50ZXInKVxuXHRcdFx0XHQuZHVyYXRpb24oMTAwMClcblx0XHRcdFx0LmRlbGF5KChkLCBpKSA9PiBpICogMTApXG5cdFx0XHRcdC5hdHRycyh7XG5cdFx0XHRcdFx0Y3g6IGQgPT4gZC54Mixcblx0XHRcdFx0XHRjeTogZCA9PiBkLnkyLFxuXHRcdFx0XHRcdHI6IDEsXG5cdFx0XHRcdH0pXG5cblx0fVxuXG5cdC8vIFRoaXMgZnVuY3Rpb24gcmVtb3ZlcyB0aGUgY2lyY2xlcy5cblx0Y29uc3QgZXhpdCA9ICgpID0+IHtcblxuXHRcdC8vIEpPSU4gbmV3IGRhdGEgd2l0aCBvbGQgZWxlbWVudHMuXG5cdFx0Y29uc3QgY2lyY2xlcyA9IGcuc2VsZWN0QWxsKCdjaXJjbGUnKVxuXHRcdFx0XHQuZGF0YShoaXN0b2dyYW0sIGQgPT4gZC5pbmRleClcblxuXHRcdC8vIFVQREFURSBvbGQgZWxlbWVudHMgcHJlc2VudCBpbiBuZXcgZGF0YS5cblx0XHRjaXJjbGVzXG5cdFx0XHQudHJhbnNpdGlvbignZXhpdCcpXG5cdFx0XHRcdC5kdXJhdGlvbigyNTApXG5cdFx0XHRcdC5kZWxheSgoZCwgaSkgPT4gaSAqIDIpXG5cdFx0XHRcdC5hdHRycyh7XG5cdFx0XHRcdFx0Y3g6IGQgPT4gZC54MSxcblx0XHRcdFx0XHRjeTogZCA9PiBkLnkxLFxuXHRcdFx0XHRcdHI6IDEsXG5cdFx0XHRcdH0pXG5cblx0fVxuXG5cdC8vIEZpcmUgdGhlIGVudGVyIGZ1bmN0aW9uIG9uIHBhZ2UgbG9hZC5cblx0ZW50ZXIoKVxuXG5cdC8vIExpc3RlbiB0byBidXR0b24gY2xpY2tzLlxuXHRkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdidXR0b24uZW50ZXInKS5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGVudGVyKVxuXHRkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdidXR0b24uZXhpdCcpLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZXhpdClcblxufSlcbiJdfQ==
<!DOCTYPE html>
<title>Lat/lon histogram</title>
<link href='dist.css' rel='stylesheet' />
<body>
<div class='map'>
<svg></svg>
</div>
<div class='buttons'>
<button class='enter'>Enter</button>
<button class='exit'>Exit</button>
</div>
<script src='https://d3js.org/d3.v4.min.js'></script>
<script src='https://d3js.org/d3-selection-multi.v1.min.js'></script>
<script src='https://d3js.org/topojson.v2.min.js'></script>
<script src='https://npmcdn.com/@turf/turf@3.10.2/turf.min.js'></script>
<script src='https://cdn.jsdelivr.net/lodash/4.17.4/lodash.min.js'></script>
<script src='dist.js'></script>
</body>
all:
rm boundary.topojson;
mapshaper -i ~/Downloads/cb_2015_us_nation_5m/cb_2015_us_nation_5m.shp name=boundary -clip bbox=-126,23,-65,50 -filter-slivers min-area=700000000 -lines -simplify dp 5% -o format=topojson boundary.topojson;
// Setup chart dimensions.
const margin = { top: 10, right: 10, bottom: 10, left: 10 }
// Get GeoJSON.
d3.json('./boundary.topojson', json => {
const feature = topojson.feature(json, json.objects.boundary)
// Get feature's bounds, centroid, and projection.
const bounds = d3.geoBounds(feature)
const centroid = d3.geoCentroid(feature)
const projection = d3.geoAlbers()
// Get the path.
const path = d3.geoPath().projection(projection)
// Get the path's bounds (i.e., in pixels).
const b = path.bounds(feature)
// Get aspect ratio.
const aspect = (b[1][0] - b[0][0]) / (b[1][1] - b[0][1])
const outerHeight = 460
const outerWidth = outerHeight * aspect
const width = outerWidth - margin.left - margin.right
const height = outerHeight - margin.top - margin.bottom
// Prepare svg.
const g = d3.select('.map svg')
.attrs({ width: outerWidth, height: outerHeight })
.append('g')
.attr('transform', `translate(${margin.left}, ${margin.top})`)
// Fit the feature to the container's width.
projection.fitSize([width, height], feature)
// Get the individual line strings.
const lineStrings = _(feature.features)
.map('geometry')
.flatten()
.map('coordinates')
.flatten()
.sortBy('length')
.map(d => turf.lineString(d))
.value()
// Calculate the overall line string length.
const totalLength = _(lineStrings)
.map(d => turf.lineDistance(d))
.sum()
// Desired number of total points.
const pointsCount = 1000
let pointsRemaining = pointsCount
const points = _(lineStrings)
.map(line => {
// How many points will this line get?
// First, calculate this line's length.
const lineLength = turf.lineDistance(line)
// Next, get this line's points proportion, rounded up.
const upperCount = Math.ceil(lineLength * pointsCount / totalLength)
// Don't get more points that are available.
const linePointsCount = Math.min(pointsRemaining, upperCount)
// Make sure to update points remaining.
pointsRemaining -= linePointsCount
// Now that we know how many points this line will get,
// calculate the distance between points - the step:
const step = lineLength / linePointsCount
const linePoints = d3.range(linePointsCount)
.map(d => turf.along(line, d * step))
return linePoints
})
.flatten()
.map(d => projection(d.geometry.coordinates))
.map((d, index) => ({
index,
x2: d[0],
y2: d[1],
}))
.value()
const yStep = 5
const histogram = _(points)
.groupBy(d => Math.round(d.y2 / yStep) * yStep)
.map((value, key) =>
_(value)
.sortBy('x2')
.map((d, i) => ({
index: d.index,
x1: ((width / 2) + (i * 4)) - (value.length * 4)/2,
y1: +key,
x2: d.x2,
y2: d.y2,
}))
.value())
.flatten()
.value()
// This function adds the circles.
const enter = () => {
// JOIN new data with old elements.
const circles = g.selectAll('circle')
.data(histogram, d => d.index)
// ENTER new elements present in new data.
circles.enter().append('circle')
.attrs({
cx: d => d.x1,
cy: d => d.y1,
r: 1,
})
.merge(circles)
.transition('enter')
.duration(1000)
.delay((d, i) => i * 10)
.attrs({
cx: d => d.x2,
cy: d => d.y2,
r: 1,
})
}
// This function removes the circles.
const exit = () => {
// JOIN new data with old elements.
const circles = g.selectAll('circle')
.data(histogram, d => d.index)
// UPDATE old elements present in new data.
circles
.transition('exit')
.duration(250)
.delay((d, i) => i * 2)
.attrs({
cx: d => d.x1,
cy: d => d.y1,
r: 1,
})
}
// Fire the enter function on page load.
enter()
// Listen to button clicks.
document.querySelector('button.enter').addEventListener('click', enter)
document.querySelector('button.exit').addEventListener('click', exit)
})
$red = #8f092a
.buttons
margin 0 auto
text-align center
.map
svg
display block
margin 0 auto
circle
fill $red
fill-opacity 0.25
stroke $red
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment