2014-02-06 32 views
2

我想用topjson載入一張D3貼圖,並加入一個單獨的CSV文件,其中包含我想用來爲貼圖着色的數據。我可以在多個圖層之間切換,但不能每次都重新繪製地圖。我在董事會上搜尋了一些關於如何做到這一點的線索,但我似乎無法弄清楚。任何人都可以提供幫助嗎?用D3製作多層貼圖

如果我們想要動態編輯CSV,我希望將CSV和JSON數據分開。我想一次將相關課程添加到每個國家,或者在用戶在三個按鈕之間切換時添加和刪除課程。要麼爲我工作,我似乎無法弄清楚如何去做。

var width = 945 

var height = 550 

var svg = d3.select('#content').append('svg').attr('width', width).attr('height', height); 

var projection = d3.geo.mercator().scale(175); 

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

var all_data = {}; 

var tierById = d3.map(); 

var quantize = d3.scale.quantize() 
    .domain([0, 1]) 
    .range(d3.range(2).map(function(i) { return "tier" + i; })); 

queue() 
    .defer(d3.json, "data/world.json") 
    .defer(d3.csv, "data/wod.csv") 
    .await(setUpChoropleth); 

function setUpChoropleth(error, json) { 

    svg.append("g") 
    .attr("class", "countries") 
    .selectAll("path") 
    .data(topojson.feature(json, json.objects.countries).features) 
    .enter().append("svg:path") 
    .attr("d", path); 

} 

function drawTierI() { 
    queue() 
     .defer(d3.json, "data/world.json") 
     .defer(d3.csv, "data/wod.csv", function(d) { tierById.set(d.id, +d.tier_i); }) 
     .await(ready); 

    function ready(error, json) { 
    svg.append("g") 
     .attr("class", "countries") 
     .selectAll("path") 
     .data(topojson.feature(json, json.objects.countries).features) 
     .enter().append("path") 
     .attr("class", function(d) { return quantize(tierById.get(d.id)); }) 
     .attr("d", path); 

    } 
} 

function drawTierII() { 
    queue() 
     .defer(d3.json, "data/world.json") 
     .defer(d3.csv, "data/wod.csv", function(d) { tierById.set(d.id, +d.tier_ii); }) 
     .await(ready); 

    function ready(error, json) { 
    svg.append("g") 
     .attr("class", "countries") 
     .selectAll("path") 
     .data(topojson.feature(json, json.objects.countries).features) 
     .enter().append("path") 
     .attr("class", function(d) { return quantize(tierById.get(d.id)); }) 
     .attr("d", path); 

    } 
} 

function drawTierIIPlus() { 
    queue() 
     .defer(d3.json, "data/world.json") 
     .defer(d3.csv, "data/wod.csv", function(d) { tierById.set(d.id, +d.tier_ii_plus); }) 
     .await(ready); 

    function ready(error, json) { 
    svg.append("g") 
     .attr("class", "countries") 
     .selectAll("path") 
     .data(topojson.feature(json, json.objects.countries).features) 
     .enter().append("path") 
     .attr("class", function(d) { return quantize(tierById.get(d.id)); }) 
     .attr("d", path); 

    } 
} 

$('button#tier_i').click(function (e) { 
    $("svg").empty(); 
    drawTierI(); 
}); 

$('button#tier_ii').click(function (e) { 
    $("svg").empty(); 
    drawTierII(); 
}); 

$('button#tier_ii_plus').click(function (e) { 
    $("svg").empty(); 
    drawTierIIPlus(); 
}); 

這裏是我的代碼jfiddle:http://jsfiddle.net/2H7Pm/我似乎不過是具有與JSON有一些語法問題。

的例子地圖將會在我的github但是工作:http://newamericafoundation.github.io/worldofdrones/

感謝您的幫助!

回答

1

您只需要選擇現有路徑,而不是在初始設置等值線後添加新路徑,例如,

function drawTierI() { 
    csv.forEach(function(d) { tierById.set(d.id, +d.tier_i); }); 

    function ready(error, json) { 
    svg.selectAll("path") 
     .attr("class", function(d) { return quantize(tierById.get(d.id)); }) 
     .attr("d", path); 

    } 
} 

和類似的其他功能。你不需要重新加載在每一步無論是JSON和CSV - 上面的代碼假設你的CSV數據被存儲在變量csv,你會正是如此填充:

var csv; 
function setUpChoropleth(error, json, _csv) { 
    csv = _csv; 
    // rest of setup 
} 

那麼你可以簡單做

$('button#tier_i').click(function (e) { 
    drawTierI(); 
}); 

更改顯示的變量,而不需要先清空SVG。

+0

謝謝!這就說得通了。有關如何糾正切換圖層時發生滯後的任何建議?看起來我不需要每次點擊都加載CSV和JSON,但這是我能夠從CSV中調用多個列的唯一方法。 –

+0

啊,是的,我沒有注意到。將更新答案。 –

+0

謝謝,這個作品完全符合你的描述!感謝你,肯定會學到關於D3和JS的新知識。 –