D3没有更新标签

时间:2016-01-06 16:01:50

标签: javascript d3.js

我的网站上有一张地图和一个匹配的图例。当用户从选择列表中选择不同的值时,将更新地图,并且在同一功能中,应使用新值更新图例。由于地图实现正常工作,即使在控制台中图例的值保持不变,如果我记录变量,也会记录正确的值。

这是绘制图例的功能:

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

2 个答案:

答案 0 :(得分: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")
  ...

这里有一些really great教程;并且它让人感到困惑,但它是d3的基础。

答案 1 :(得分: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');
相关问题