2017-05-26 117 views
1

我是新來的d3.js。我想從頭開始創建這個地區分佈圖:使用d3.js的Choropleth地圖

enter image description here

我的劇本沒有顯示任何錯誤,並在元素標籤,我可以看到數據,但沒有顯示在屏幕上。我已閱讀多份文件,但仍不知道我錯過了什麼。

的jsfiddle: https://jsfiddle.net/jx3hjfgw

var width = 960, 
    height = 1160; 

// SVG element as a JavaScript object that we can manipulate later 
var svg = d3.select("#map").append("svg") 
     .attr("width", width) 
     .attr("height", height); 

var center = [24.679341, 46.680381]; 

// Instantiate the projection object 
var projection = d3.geo.conicConformal() 
     .center(center) 
     .clipAngle(180) 
      // Size of the map itself, you may want to play around with this in 
      // relation to your canvas size 
     .scale(10000) 
      // Center the map in the middle of the canvas 
     .translate([width/2, height/2]) 
     .precision(.1); 

// Assign the projection to a path 
var path = d3.geo.path().projection(projection); 

d3.json("https://code.highcharts.com/mapdata/countries/sa/sa-all.geo.json", function(err, data) { 
    $.each(data.features, function(i, feature) { 
    svg.append("path") 
     .datum(feature.geometry) 
     .attr("class", "border") 
     .attr("stroke", "black") 
     .attr("fill", "blue"); 
    }); 
}); 
+0

你的路徑沒有'd'屬性,所以它們實際上並沒有繪製任何東西,你需要使用d3-geo來轉換json的座標數據到svg路徑 –

回答

2

您的地圖有幾個問題。

主要問題是您的投影不是WGS84,也就是說它不包含經度/緯度對。在以GeoJSON的投影在你的GeoJSON的本身規定:

"crs":{"type":"name","properties":{"name":"urn:ogc:def:crs:EPSG:32638"}} 

CRS代表空間參照系統

此投影(EPSG:32638)是UTM系統。 D3使用未投影的數據(或「投影」到WGS84的數據),三維橢球體上的點,還沒有在平面網格上投影的點(如UTM)。如果以GeoJSON並沒有說明使用何種投影,你仍然可以告訴它不是WGS84,或經度緯度對,因爲座標是無效的經度/緯度:

...[1348,4717],[1501,4754],[1572,4753]... 

你有兩個選擇,一個是使用未投影的數據(或WGS84中的數據)並圍繞d3投影構建地圖。另一種是使用geo.transform來顯示你的數據。

解決方案1 ​​

正如其他答案提到的,你需要使用path功能實際顯示的數據,你也應該不需要的每個循環中D3附加功能

對於這種解決方案的工作,它可能是最直接的,你需要重新投影/取消投影你有的geojson(使用d3以外的工具),或者,你也可以將必須找到一個新的數據源(這可能不是太困難),空間數據表示爲長/雙對。

另請注意,在geojson和d3中的座標爲[long,lat],因此您的中心座標爲[24.679341, 46.680381]指向北46.7度,東經24.7度 - 此點不在沙特阿拉伯,而是在羅馬尼亞。

看一看適用於沙特阿拉伯here的示例預測(使用基本幾何 - 只是一個國家大綱)(在d3v4中 - 與v3略有不同)。

在一起,那將會給你的東西喜歡

var projection = d3.geo.mercator() 
     .center([46.680381,24.679341]) 
     .scale(1000) 
     .translate([width/2, height/2]) 
     .precision(.1); 

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

d3.json("source.json", function(err, data) { 
    svg.selectAll("path") 
     .data(data.features) 
     .enter() 
     .append('path') 
     .attr("class", "border") 
     .attr("stroke", "black") 
     .attr("fill", "blue") 
     .attr("d", path); 
    }); 

請注意,如果你真的想保持圓錐投影(d3.geo.conicConformal()),看看上定心型投影here,它的對於阿爾伯斯投影,但是這種方法與它們都是相同類型的圓錐投影相同。

溶液2

另一種選擇是使用一個geo.transfrom這將轉化和擴展數據(因爲它已經在這種情況下爲平面)以匹配所需的圖。這種方法的缺點是你不能使用經緯度來表示任何東西 - 地圖單位將是投影單位,地圖單位不是經度或緯度。

目標是平移/縮放/換擋座標諸如這些:

...[1348,4717],[1501,4754],[1572,4753]... 

到是你的SVG界限內的[X,Y]的像素值。 (比如我用this bl.ock中的數據演示,(使用d3v4,它具有稍微不同的方法名稱,但對於這種類型的操作是相同的),這是更復雜的, ,或者使用一個自動函數來確定你需要使用的合適變換。

1

您的最後一個函數改成這樣

svg.append("path") 
     .data(feature.geometry) 
     .attr("d", path) 
     .attr("class", "border") 
     .attr("stroke", "black") 
     .attr("fill", "blue"); 
1

我覺得有什麼不對的,你geojson文件

我把它上傳到github,這會自動檢測geojson內容並將其顯示爲地圖。你可以看到,只有一行顯示

前面已經指出的那樣,你不會有path

定義d財產我已經更新您的fiddle匹配Github的結果的更多信息:

var width = 960, 
 
    height = 1160; 
 

 
// SVG element as a JavaScript object that we can manipulate later 
 
var svg = d3.select("#map").append("svg") 
 
     .attr("width", width) 
 
     .attr("height", height); 
 

 
var center = [24.679341, 46.680381]; 
 

 
// Instantiate the projection object 
 
var projection = d3.geo.mercator() 
 
     .center(center) 
 
     .clipAngle(180) 
 
      // Size of the map itself, you may want to play around with this in 
 
      // relation to your canvas size 
 
     .scale(1000) 
 
      // Center the map in the middle of the canvas 
 
     .translate([width/2, height/2]) 
 
     .precision(.1); 
 

 
// Assign the projection to a path 
 
var path = d3.geo.path().projection(projection); 
 

 
d3.json("https://raw.githubusercontent.com/bumbeishvili/Assets/master/Other/junk/sa-all.geo.json", function(err, data) { 
 
debugger; 
 
    
 
    svg.selectAll('path') 
 
     .data(data.features) 
 
     .enter() 
 
     .append("path") 
 
     .attr("d", path) 
 
     .attr("class", "border") 
 
     .attr("stroke", "black") 
 
     .attr("fill", "blue"); 
 
     
 
});
<script src="//d3js.org/d3.v3.min.js" charset="utf-8"></script> 
 
<script src="//d3js.org/topojson.v1.min.js"></script> 
 

 
<div id="map"></div>