Hexagonal world map, that draws based hexagons on the generated canvas map (comment out display: hidden, in css, to see the canvas rendering)
Reference sources:
- Rendering a map as canvas
- Hexbin Heightmap based from Heightmap
Hexagonal world map, that draws based hexagons on the generated canvas map (comment out display: hidden, in css, to see the canvas rendering)
Reference sources:
| <!DOCTYPE html> | |
| <meta charset="utf-8"> | |
| <style> | |
| body { | |
| background: #000; | |
| } | |
| canvas { | |
| display: none; | |
| } | |
| </style> | |
| <!-- http://www.basscss.com/ --> | |
| <link href="//npmcdn.com/[email protected]/css/basscss.min.css" rel="stylesheet"> | |
| <!-- http://clrs.cc/ --> | |
| <link href="//s3-us-west-2.amazonaws.com/colors-css/2.2.0/colors.min.css" rel="stylesheet"> | |
| <section id="vis"></section> | |
| <!-- dependencies --> | |
| <script src="//d3js.org/d3.v3.min.js" charset="utf-8"></script> | |
| <script src="//rawgit.com/mbostock/7833311/raw/27d0f5623105fd8815e1a42b80cbd4d27d292d53/d3.hexbin.min.js"></script> | |
| <script src="//d3js.org/topojson.v1.min.js"></script> | |
| <script src="//d3js.org/d3.geo.projection.v0.min.js"></script> | |
| <script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/4.6.1/lodash.min.js" charset="utf-8"></script> | |
| <!-- d3 code --> | |
| <script src="script-compiled.js" charset="utf-8"></script> | |
| <script> | |
| // call chart | |
| let chart = hexmap(); | |
| // apply chart to DOM | |
| d3.select('#vis') | |
| .call(chart); | |
| </script> | |
| 'use strict'; | |
| var hexmap = function hexmap() { | |
| //________________________________________________ | |
| // GET/SET defaults | |
| //________________________________________________ | |
| // private variables | |
| var svg = undefined; | |
| var dispatch = d3.dispatch('customHover'); | |
| // getter setter defaults | |
| var opts = { | |
| width: 960, | |
| height: 500, | |
| margin: { top: 20, right: 10, bottom: 20, left: 10 } | |
| }; | |
| var hexbin = d3.hexbin().size([opts.width, opts.height]).radius(5); | |
| var color = d3.scale.linear().domain([14, 15, 35, 132]).range(['#000', '#bae4b3', '#74c476', '#238b45']).interpolate(d3.interpolateHcl); | |
| //________________________________________________ | |
| // RENDER | |
| //________________________________________________ | |
| function exports(_selection) { | |
| var canvas = _selection.append('canvas').attr('width', opts.width).attr('height', opts.height).attr('id', 'mapCanvas'); | |
| var context = canvas.node().getContext('2d'); | |
| var points = []; | |
| var hexagons = []; | |
| var projection = d3.geo.wagner7().rotate([0, 0]).scale(180).center([0, 0]); | |
| context.fillStyle = 'tomato'; | |
| context.strokeStyle = 'none'; | |
| var path = d3.geo.path().projection(projection).context(context); | |
| d3.json('world-110m.json', function (error, world) { | |
| if (error) throw error; | |
| path(topojson.feature(world, world.objects.land)); | |
| context.fill(); | |
| // use the canvas as the image | |
| var image = document.getElementById('mapCanvas');; | |
| context.drawImage(image, 0, 0, opts.width, opts.height); | |
| image = context.getImageData(0, 0, opts.width, opts.height); | |
| // rescale the colors | |
| for (var c, i = 0, n = opts.width * opts.height * 4, d = image.data; i < n; i += 4) { | |
| points.push([i / 4 % opts.width, Math.floor(i / 4 / opts.width), d[i]]); | |
| } | |
| hexagons = hexbin(points); | |
| hexagons.forEach(function (d) { | |
| d.mean = d3.mean(d, function (p) { | |
| return p[2]; | |
| }); | |
| }); | |
| var svg = _selection.append('svg').attr('width', opts.width).attr('height', opts.height); | |
| var hexagon = svg.append('g').attr('class', 'hexagons') | |
| .selectAll('path') | |
| .data(hexagons).enter() | |
| .append('path') | |
| .attr('d', hexbin.hexagon(8)).attr('transform', function (d) { | |
| return 'translate(' + d.x + ',' + d.y + ')'; | |
| }).style('fill', function (d) { | |
| return color(d.mean); | |
| }); | |
| }); | |
| } // exports | |
| function getImage(path, callback) { | |
| var image = new Image(); | |
| image.onload = function () { | |
| callback(image); | |
| }; | |
| image.src = path; | |
| } | |
| //________________________________________________ | |
| // GET/SET | |
| //________________________________________________ | |
| function getSet(option, component) { | |
| return function (_) { | |
| if (!arguments.length) { | |
| return this[option]; | |
| } | |
| this[option] = _; | |
| return component; | |
| }; | |
| } | |
| // api for chart, all items in `opts` object made into get-set | |
| for (var key in opts) { | |
| exports[key] = getSet(key, exports).bind(opts); | |
| } | |
| d3.rebind(exports, dispatch, 'on'); | |
| return exports; | |
| }; |