如何使用d3更新/覆盖地图和图例内容

时间:2015-03-05 10:00:09

标签: javascript svg d3.js gis

我使用d3拼凑了一个等值线图,由Mike Bostock编写的例子帮助。我是d3(以及HTML,JavaScript,CSS)的新手。

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

上查看地图和源代码

Glasgow Index of Deprivation 2012

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

我已经尝试过遵循Stephen Spann in this answer给出的建议,以及他在工作小提琴中提供的代码。但无济于事。

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

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

然后在更新时选择它......

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();

2 个答案:

答案 0 :(得分:1)

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

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

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

答案 1 :(得分:0)

感谢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上看到完整的工作更新代码。