Most basic background map in d3.js and canvas





This post describes how to build a very basic background map of the world with d3.js and canvas. Note that the same kind of code would work with any geospatial data stored in geojson format. You can see many other examples in the background map section of the gallery. This example works with d3.js v4 and v6


Background map section

Steps:

  • The Html part of the code just creates a canvas. Rest of the code adds stuff in it.

  • Canvas is an alternative to svg to draw shapes in javascript. Read an intro to canvas here.

  • The spirit is very close to a background map built with svg (see here). But once the projection anc the path generator are ready, shapes are drawn with fill() and stroke().
|
<!DOCTYPE html>
<meta charset="utf-8">

<!-- Load d3.js -->
<script src="https://d3js.org/d3.v4.js"></script>
<script src="https://d3js.org/d3-geo-projection.v2.min.js"></script>

<!-- Create an element where the map will take place -->
<canvas id="my_dataviz" width="440" height="320"></canvas>

<!DOCTYPE html>
<meta charset="utf-8">

<!-- Load d3.js -->
<script src="https://d3js.org/d3.v6.js"></script>

<!-- Create an element where the map will take place -->
<canvas id="my_dataviz" width="440" height="320"></canvas>

<script>

// select the canvas element created in the html.
var canvas = document.getElementById('my_dataviz');

// Actual width and height. No idea if clienWidth would be a better option..?
var width = canvas.offsetWidth
var height = canvas.offsetHeight

// Set a projection for the map. Projection = transform a lat/long on a position on the 2d map.
var projection = d3.geoNaturalEarth1()
    .scale(width / 1.3 / Math.PI)
    .translate([width / 2, height / 2])

// Get the 'context'
var ctx = canvas.getContext('2d');

// geographic path generator for given projection and canvas context
const pathGenerator = d3.geoPath(projection, ctx);

// Draw a background
// ctx.fillStyle = '#ddd';
// ctx.fillRect(0, 0, width, height);

// Load external data and boot
d3.json("https://raw.githubusercontent.com/holtzy/D3-graph-gallery/master/DATA/world.geojson", function(data){

  // initialize the path
  ctx.beginPath();

  // Got the positions of the path
  pathGenerator(data);

  // Fill the paths
  ctx.fillStyle = "#999";
  ctx.fill();

  // Add stroke
  ctx.strokeStyle = "#69b3a2";
  ctx.stroke()

})

</script>
<script>

// select the canvas element created in the html.
const canvas = document.getElementById('my_dataviz');

// Actual width and height. No idea if clienWidth would be a better option..?
const width = canvas.offsetWidth
const height = canvas.offsetHeight

// Set a projection for the map. Projection = transform a lat/long on a position on the 2d map.
const projection = d3.geoNaturalEarth1()
    .scale(width / 1.3 / Math.PI)
    .translate([width / 2, height / 2])

// Get the 'context'
const ctx = canvas.getContext('2d');

// geographic path generator for given projection and canvas context
const pathGenerator = d3.geoPath(projection, ctx);

// Draw a background
// ctx.fillStyle = '#ddd';
// ctx.fillRect(0, 0, width, height);

// Load external data and boot
d3.json("https://raw.githubusercontent.com/holtzy/D3-graph-gallery/master/DATA/world.geojson").then( function(data){

  // initialize the path
  ctx.beginPath();

  // Got the positions of the path
  pathGenerator(data);

  // Fill the paths
  ctx.fillStyle = "#999";
  ctx.fill();

  // Add stroke
  ctx.strokeStyle = "#69b3a2";
  ctx.stroke()

})
</script>

Related blocks →

  • Mapping with Canvas - link

  • Projection Transitions - link