2016-10-03 14 views
1

我試圖使用d3.js庫將點添加到地圖。 (我試過改編這個gist的腳本)。在現有元素之上附加SVG項目

問題是地圖被渲染在點的頂部。 我試圖使用另一個SO回答,其中提示這樣的事情: svg.append("g").attr("id", "map").attr("id", "points") ...但我一直無法使它的工作。我是一個很長時間的Python用戶... JavaScript對我來說是新的(所以請原諒那些天真的)。

現在用的是下面的CSS:

<style> 
    body { 
     background-color: white; 
    } 
    svg { 
     border: 1px solid black; 
     background-color: #a4bac7; 
    } 
     .land { 
      fill: #d7c7ad; 
      stroke: #8999ab; 
     } 
     .boundary { 
      fill: none; 
      stroke: #a5967f; 
     } 
    </style> 

身體:

<script type="text/javascript" src="d3/d3.js"></script> 
    <script src="http://d3js.org/topojson.v0.min.js"></script> 

    <script> 
     var width = 960; 
     var height = 480; 
     var dataURL = "https://gist.githubusercontent.com/abenrob/787723ca91772591b47e/raw/8a7f176072d508218e120773943b595c998991be/world-50m.json"; 

     var svg = d3.select("body").append("svg") 
      .attr("width", width) 
      .attr("height", height); 

針對this SO回答的答案,添加了這個:

 svg.append("g") 
       .attr("id", "map") 
       .attr("id", "points"); 

 var projection = d3.geoEquirectangular() 
      .scale(153) 
      .translate([width/2,height/2]) 

     var path = d3.geoPath() 
      .projection(projection); 

     d3.json(dataURL, function(error, world) { 
      svg.append("g") 
       .select("#map").selectAll(".map") 
       .attr("class", "land") 
       .selectAll("path") 
       .data([topojson.object(world, world.objects.land)]) 
       .enter().append("path") 
       .attr("d", path); 
      svg.append("g") 
       .select("#map").selectAll(".map") 
       .attr("class", "boundary") 
       .selectAll("boundary") 
       .data([topojson.object(world, world.objects.countries)]) 
       .enter().append("path") 
       .attr("d", path); 
      } 
     ); 

     var lngLatExtract = function(d, i){ 
      return projection([d['lng'], d['lat']])[i]; 
     }; 

     d3.csv("cities.csv", function(data){ 
       svg.append("g") 
         .select("#points").selectAll(".points") 
         .data(data) 
         .enter() 
          .append('circle') 
          .attr("cx", function(d){ 
           return lngLatExtract(d, 0); 
          }) 
          .attr('cy', function(d){ 
           return lngLatExtract(d, 1); 
          }) 
          .style("fill", "blue") 
          .style("opacity", 0.75) 
          .attr("r", function(d){ 
           return Math.sqrt(parseInt(d['population']) * 0.000001) 
          }); 
       } 
     ); 

    </script> 

cities.csv看起來是這樣的:

rank,place,population,lat,lng 
1,New York city,8175133,40.71455,-74.007124 
2,Los Angeles city,3792621,34.05349,-118.245323 

回答

2

兩個d3.jsond3.csv異步功能。它們的回調觸發順序不是給定的,事實上,因爲你的csv文件比較小,所以回調可能是先發射。這意味着您的csv回調中的svg.append("g")正在發生之前svg.append("g")在json回調中。您可以通過檢查DOM並查看首先附加的內容來確認。

也就是說,我會切換到使用d3.queue。這允許您觸發d3.jsond3.csv異步請求,然後觸發一個完成的回調。

另一種簡化的選項是將d3.csv代碼放在d3.json調用的回調中。