如何 update/overwrite 使用 d3 映射和图例内容

How to update/overwrite map and legend content using d3

在 Mike Bostock 编写的示例的帮助下,我使用 d3 制作了一张等值线图。我是 d3 的新手(老实说 HTML、JavaScript、CSS)。

我已经创建了地图和图例,并且能够在不同的数据集之间切换。可以在 bl.ocks.org

上查看地图和源代码

Glasgow Index of Deprivation 2012

我现在遇到的问题是如何在不同数据集之间切换时替换地图和图例内容。正如您目前所见,selected 不同的数据集时,内容只是添加到现有内容之上。

我尝试遵循 Stephen Spann in this answer 的建议以及他在工作 fiddle 中提供的代码。但是没有用。

据我了解,我应该像这样在开头将 g 附加到 svg 变量...

var svg = d3.select("body")
    .append("svg")
    .attr("width", width)
    .attr("height", height)
    .append("g");

然后select这样更新的时候...

var appending = svg.selectAll("g")
    .attr("class", "S12000046_geo")
    .data(topojson.feature(glasgowdep, glasgowdep.objects.S12000046_geo).features);

     // add new elements
     appending.enter().append("path");

     // update existing elements
     appending.style("fill",
     function (d) {
         return color(choro[d.id]);
     })
     .style("stroke", "#cfcfcf")
     .attr("d", path)

     // rollover functionality to display tool tips
     .on("mouseover", function (d) {
         tip.show(d)
         d3.select(this)
             .transition().duration(200)
             .style("fill", "red");
     })
     .on("mouseout", function () {
         tip.hide()
         d3.select(this)
             .transition().duration(200)
             .style("fill",
             function (d) {
                 return color(choro[d.id]);
             });
     })

     // build the map legend
     var legend = d3.select('#legend')
         .append('ul')
         .attr('class', 'list-inline');

     var keys = legend.selectAll('li.key')
         .data(color.range());

     var legend_items = ["Low", "", "", "", "", "", "", "", "High"];

     keys.enter().append('li')
         .attr('class', 'key')
         .style('border-top-color', String)
         .text(function (d, i) {
             return legend_items[i];
         });

     // remove old elements
     appending.exit().remove();

解决方案如下:在 http://bl.ocks.org/niallmackenzie/8a763afd14e195154e63 中的代码中尝试在构建地图图例之前添加以下行(index.html 中的第 220 行):

d3.select('#legend').selectAll('ul').remove();

每次更新数据时,都会先清空#legend。

感谢Lars的指点和nipro提出的解决方案,完成了以下工作。通过在构建图例的部分上方添加以下代码,图例在更新之前先被清空:

d3.select('#legend')
   .selectAll('ul')
   .remove();

// build the map legend
var legend = d3.select('#legend')
...

通过对主地图做同样的事情,我们可以先清空地图再更新它:

d3.select("g")
  .selectAll("path")
  .remove();

// build the choropleth map
var appending = svg.selectAll("g")
...

可以在 bl.ocks.org here.

上看到完整的工作更新代码