Mohamed Ali JAMAOUI
Mohamed Ali JAMAOUI

Reputation: 14689

D3.js map with HTML5 canvas not showing

I am trying to understand how to create a minimalistic example of a country map using d3.js and HTML5 canvas. I managed to implement the following code,

<html>
<head>
<title></title>
</head>
<body>

</body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://d3js.org/topojson.v1.min.js"></script>
<script type="text/javascript">
// drawing a map in a canvas 
    var width = 960, height = 500; 
    var canvas = d3.select("body").append("canvas")
                            .attr("width", width)
                            .attr("height",height); 

    var context = canvas.node().getContext("2d"); 

    var projection = d3.geo.mercator();


    var path = d3.geo.path()
        .projection(projection)
        .context(context);


    d3.json("tunisia.json", function(error, topology) {


     canvas
      .datum(topojson.object(topology, topology.objects.governorates))
     .transition(); 

    });

</script>
</html>

But, no results have shown in the browser and no error received in the console, could you please check. Also, is there any minimalistic example of US map with canvas in d3.js

Upvotes: 0

Views: 1464

Answers (1)

Roger Veciana
Roger Veciana

Reputation: 993

You aren't drawing anything inside the canvas, that's why it fails.

enter image description here

The following code will work and will give the result in the image, and you can play with it at this jsbin:

<html>
<head>
<title></title>
</head>
<body>

</body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://d3js.org/topojson.v0.min.js"></script>
<script type="text/javascript">
// drawing a map in a canvas 
    var width = 960, height = 500; 
    var canvas = d3.select("body").append("canvas")
                            .attr("width", width)
                            .attr("height",height); 

    var context = canvas.node().getContext("2d"); 

    var projection = d3.geo.mercator();


    var path = d3.geo.path()
        .projection(projection)
        .context(context);


    d3.json("https://cdn.rawgit.com/mbostock/4090846/raw/8a7f176072d508218e120773943b595c998991be/world-50m.json", function(error, data) {
      var land = topojson.object(data, data.objects.land);


      context.strokeStyle = '#000000';  

      context.fillStyle = '#aaaaaa';  

      context.beginPath();
      path(land);
      context.fill();

    });

</script>
</html>

Let's see how does it work:

  • The only part that changes is after loading the json
  • I've changed your Tunisia.json file for another one, since I don't have your file. If it's a correct JSON, your file should work, although you'll see Tunisia quite small. To change this, change the scale property at the projection object.
  • The variable land has all the polygons from the topojson file
  • context is the object that used to draw elements in the canvas. It has many functions, to draw lines, erase, etc. You have all theme here.
  • Then we set the line color to black and the fill color to a grey using strokeStyle and fillStyle. When you call any function from this point, those values will be used
  • Now a path is initiated with the method beginPath(), so all the following operations will add properties to this path
  • The next order actually draws everything:
    • You added the context to the path definition, so all the data you pass to this path will be added to the context. Since the land variable has polygons, the polygons will be drawn.
  • the fill method fills the polygons with the defined color. If you don't call it, nothing will be drawn

Upvotes: 1

Related Questions