score:2

Accepted answer

You are not correctly binding your features' data when using

svg.append('path')
   .data(result.features)
   .style('stroke', 'green')
   .attr('d' , d3.geo.path().projection(projection))

This will append one path, bind the first element of result.features to this path and set the style and attribute accordingly.

To work the way you want it, you need to make use of the data joining mechanism of D3.

svg.selectAll('path.features')
   .data(result.features)
  .enter().append('path')
    .attr('class', 'feature')
    .style('stroke', 'green')
    .attr('d' , d3.geo.path().projection(projection))

This will compute a data join for the features in result.features putting the new elements in the enter selection which is accessible by calling enter() on the seletion. Using this enter selection you can now append paths for all your features.


A further side note not directly related to your issue: Depending on the number of features you want to append to your map, the .attr("d") setter might be called quite often. You could improve performance by reusing one instance of the path generator:

var geoPath = d3.geo.path().projection(projection);  // You need just one instance

svg.selectAll('path.features')
   .data(result.features)
  .enter().append('path')
    .attr('class', 'feature')
    .style('stroke', 'green')
    .attr('d' , geoPath)                             // Re-use the path generator

This is considered best practice, which should be generally applied.


Related Query