2016-01-06 97 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');