2016-01-06 101 views
2

我在我的網站上有一張地圖和一個匹配的圖例。當用戶從選擇列表中選擇不同的值時,地圖被更新,並且在相同的功能中,圖例應該用新值更新。由於地圖實現工作正常,因此即使在控制檯中記錄了正確的值(如果我記錄變量),圖例的值也保持不變。D3沒有更新標籤

這是繪製圖例中的功能:他們與舊的閾值彩色

color_domain = [wert1, wert2, wert3, wert4, wert5]; 
ext_color_domain = [0, wert1, wert2, wert3, wert4, wert5]; 
console.log(ext_color_domain); 
legend_labels = ["< "+wert1, ""+wert1, ""+wert2, ""+wert3, ""+wert4, "> "+wert5]; 
color = d3.scale.threshold() 
.domain(color_domain) 
.range(["#85db46", "#ffe800", "#ffba00", "#ff7d73", "#ff4e40", "#ff1300"]); 

var legend = svg.selectAll("g.legend") 
    .data(ext_color_domain) 
    .enter().append("g") 
    .attr("class", "legend"); 

    var ls_w = 20, ls_h = 20; 

    legend.append("rect") 
    .attr("x", 20) 
    .attr("y", function(d, i){ return height - (i*ls_h) - 2*ls_h;}) 
    .attr("width", ls_w) 
    .attr("height", ls_h) 
    .style("fill", function(d, i) { return color(d); }) 
    .style("opacity", 0.7); 

    legend.append("text") 
    .attr("x", 50) 
    .attr("y", function(d, i){ return height - (i*ls_h) - ls_h - 4;}) 
    .text(function(d, i){ return legend_labels[i]; }); 
    console.log(legend_labels); //gives the right legend_labels but doesn't display them correctly 

}; 

可悲的是,甚至在地圖上與新顏色更新。這是地圖的被染色方式:

svg.append("g") 
.attr("class", "id") 
    .selectAll("path") 
    .data(topojson.feature(map, map.objects.immoscout).features) 
    .enter().append("path") 
    .attr("d", path) 
    .style("fill", function(d) { 
    return color(rateById[d.id]); 
    }) 

screenshot

回答

1

這是很難回答沒有一個完整的,工作代碼示例,但...

你是不是處理輸入,更新,正確退出模式。你永遠不會真的更新現有的元素,你只是重新綁定數據並輸入新的元素。

說你叫你的傳奇功能已經一次,現在你有新的數據和你做:

var legend = svg.selectAll("g.legend") 
    .data(ext_color_domain) 
    .enter().append("g") 
    .attr("class", "legend"); 

這重新綁定數據並計算出enter選擇。它說,嗨D3,什麼數據元素是新的?對於那些新的,你可以追加一個g。進一步:

legend.append("rect") 
    .attr("x", 20) 
    .attr("y", function(d, i){ return height - (i*ls_h) - 2*ls_h;}) 
    .attr("width", ls_w) 
    .attr("height", ls_h) 
    .style("fill", function(d, i) { return color(d); }) 
    .style("opacity", 0.7); 

再次,這是在這些新輸入元件操作。頁面上已存在的內容完全沒有觸及。

未經測試的代碼,但希望它指向你在正確的方向:

// selection of all enter, update, exit 
var legend = svg.selectAll("g.legend") 
    .data(ext_color_domain); //<-- a key function would be awesome here 

legend.exit().remove(); //<-- did the data go away? remove the g bound to it 

// ok, what data is coming in? create new elements; 
var legendEnter = legend.enter().append("g") 
    .attr("class", "legend"); 
legendEnter.append("rect"); 
legendEnter.append("text"); 

// ok, now handle our updates... 
legend.selectAll("rect") 
    .attr("x", 20) 
    .attr("y", function(d, i){ return height - (i*ls_h) - 2*ls_h;}) 
    .attr("width", ls_w) 
    .attr("height", ls_h) 
    .style("fill", function(d, i) { return color(d); }) 
    .style("opacity", 0.7); 

legend.selectall("text") 
    ... 

有一些這方面的reallygreat教程;它會讓人迷惑,但它是d3的基礎。

+0

謝謝您的回答。我測試了你的代碼,它只畫出了圖例的一個方面。你有什麼想法,爲什麼這是? – maidi

+0

@maidi,如果你創建了一個工作jsFiddle或PLunkr,我會看看。 – Mark

+0

缺少'.merge(legend)'工作。這就是訣竅。 –

0

一個例子,可以幫助您開始使用更新D3(D3,V4):

const line = svg.selectAll('line').data(d3Data); // binds things 
line.exit().remove(); // removes old data 

line.enter() 
    .append('line') // add new lines for new items on enter 
    .merge(line) // <--- this will make the updates to the lines 
    .attr('fill', 'none') 
    .attr('stroke', 'red');