Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to control the order of the layers on a map in d3js

I have a simple question about making maps with d3js. I want to make a map with two layers. One layer is the contour of the map (geoJson) and the other layer contains the streets (topoJson). My problem is that streets layer always is loaded in front of the layer of contour, no matter which one is written before in the code. I would like the opposite situation: the contour layer in front of the streets. I think this problem happen because both request are asynchronous and the contour layer is loaded before because is the lightest.

Here is the code...

//Width and height
            var w = 900;
            var h = 500;

            //Define map projection
            var projection = d3.geo.transverseMercator()
                                   .center([2.5, -34.65])
                                   .rotate([61.5, 0])
                                   .scale((h * 750.5) / 3)
                                   .translate([(w/2), (h/2)]);

            //Define path generator
            var path = d3.geo.path()
                             .projection(projection);

            //Create SVG element
            var svg = d3.select("body")
                        .append("svg")
                        .attr("width", w)
                        .attr("height", h);

            //Load in TopoJSON data
            d3.json("streets.json", function(error, topology) {


                svg.selectAll("path")
                   .data(topojson.feature(topology, topology.objects.layer1).features)
                   .enter()
                   .append("path")
                   .attr("d", path)
                   .style("fill", "white")
                   .style("stroke", "#cccccc");

            });

            //Load in GeoJSON data
            d3.json("contour.geojson", function(json) {

                //Bind data and create one path per GeoJSON feature
                svg.selectAll("path")
                   .data(json.features)
                   .enter()
                   .append("path")
                   .attr("d", path)
                   .style("fill","white")
                   .style("stroke","black")
                   .style("stroke-width",4);

            });

Is it possible load first the layer of streets, wait until the streets were drawn and then load the layer of contour? Thanks in advance.

like image 451
Pablo Avatar asked Feb 04 '14 07:02

Pablo


1 Answers

I would create two separate g elements for the layers in the beginning. This way you can control their order:

var countourG = svg.append("g"),
    streetG = svg.append("g");

d3.json("streets.json", function(error, topology) {
  streetG.selectAll("path")...
});

d3.json("contour.json", function(error, topology) {
  contourG.selectAll("path")...
});
like image 131
Lars Kotthoff Avatar answered Sep 21 '22 13:09

Lars Kotthoff