Heisenberg
Heisenberg

Reputation: 8806

d3 - Elements being obscured despite being drawn last

I'm drawing the choropleth map in the d3 book, and I don't understand the order in which elements get drawn.

The correct code is as follows:

d3.csv("us-productivity.csv", function(data) {

  d3.json("us-states.json", function(json) {
    // Merge producivity data and geojson data
    // Then plot the paths, using the level of productivity for "fill"
  });

  d3.csv("us-cities-size.csv", function(data) {
    // Plot cities as dots of different sizes
  })
});

However, when I move d3.csv("us-cities-size.csv") outside of and after d3.csv("us-productivity.csv"), then the cities dot lie underneath the choropleth map. Why is that the case when the code for us-cities-size is after and should be drawn on top?

Upvotes: 0

Views: 32

Answers (1)

James Stewart
James Stewart

Reputation: 378

This is probably a timing issue. The d3.csv function makes an AJAX request, which runs asynchronously. The function that you pass runs when the response is received, but code below the d3.csv call will run while waiting for the server response. By moving the d3.csv("us-cities-size.csv") call out of the callback, the two calls will run at the same time. This turns into a race to see which call will return first and execute the callback. Since the d3.csv("us-productivity.csv") call makes another d3.csv call inside, it is practically guaranteed that the us-cities-size will return first, meaning it will draw first.

Actually a better way than relying on these callbacks for document order would be to append a group for each of these layers before making the csv calls. Then you can append into the groups, with the layering order guaranteed. Like so:

var statesGroup = svg.append("g");
var citiesGroup = svg.append("g");    
d3.csv("us-productivity.csv", function(data) {

  d3.json("us-states.json", function(json) {
    // Merge producivity data and geojson data
    // Then plot the paths, using the level of productivity for "fill"
    // Append everything to statesGroup
  });

  d3.csv("us-cities-size.csv", function(data) {
    // Plot cities as dots of different sizes
    // Append everything to citiesGroup
  })
});

Upvotes: 2

Related Questions