Javascript 用D3制作多层地图

Javascript 用D3制作多层地图,javascript,csv,d3.js,topojson,Javascript,Csv,D3.js,Topojson,我正在尝试加载一个带有topjson的D3地图,并与之连接一个单独的CSV文件,其中包含我想用来给地图上色的数据。我可以在多个图层之间切换,但每次都要重新绘制地图。我在黑板上搜寻了一些关于如何做这件事的线索,但我似乎没有弄明白。有人能提供帮助吗 我希望将CSV和JSON数据分开,以防我们需要动态编辑CSV。我想一次性将相关类添加到每个国家,或者在用户在三个按钮之间切换时添加和删除这些类。这两种方法对我都有效,我只是不知道怎么做 var width = 945 var height = 550

我正在尝试加载一个带有topjson的D3地图,并与之连接一个单独的CSV文件,其中包含我想用来给地图上色的数据。我可以在多个图层之间切换,但每次都要重新绘制地图。我在黑板上搜寻了一些关于如何做这件事的线索,但我似乎没有弄明白。有人能提供帮助吗

我希望将CSV和JSON数据分开,以防我们需要动态编辑CSV。我想一次性将相关类添加到每个国家,或者在用户在三个按钮之间切换时添加和删除这些类。这两种方法对我都有效,我只是不知道怎么做

var width = 945

var height = 550

var svg = d3.select('#content').append('svg').attr('width', width).attr('height', height);

var projection = d3.geo.mercator().scale(175);

var path = d3.geo.path().projection(projection);

var all_data = {};

var tierById = d3.map();

var quantize = d3.scale.quantize()
    .domain([0, 1])
    .range(d3.range(2).map(function(i) { return "tier" + i; }));

queue()
  .defer(d3.json, "data/world.json")
  .defer(d3.csv, "data/wod.csv")
  .await(setUpChoropleth);

function setUpChoropleth(error, json) {

  svg.append("g")
     .attr("class", "countries")
  .selectAll("path")
    .data(topojson.feature(json, json.objects.countries).features)
  .enter().append("svg:path")
    .attr("d", path);

} 

function drawTierI() {
  queue()
      .defer(d3.json, "data/world.json")
      .defer(d3.csv, "data/wod.csv", function(d) { tierById.set(d.id, +d.tier_i); })
      .await(ready);

  function ready(error, json) {
    svg.append("g")
        .attr("class", "countries")
      .selectAll("path")
        .data(topojson.feature(json, json.objects.countries).features)
      .enter().append("path")
        .attr("class", function(d) { return quantize(tierById.get(d.id)); })
        .attr("d", path);

  }
}

function drawTierII() {
  queue()
      .defer(d3.json, "data/world.json")
      .defer(d3.csv, "data/wod.csv", function(d) { tierById.set(d.id, +d.tier_ii); })
      .await(ready);

  function ready(error, json) {
    svg.append("g")
        .attr("class", "countries")
      .selectAll("path")
        .data(topojson.feature(json, json.objects.countries).features)
      .enter().append("path")
        .attr("class", function(d) { return quantize(tierById.get(d.id)); })
        .attr("d", path);

  }
}

function drawTierIIPlus() {
  queue()
      .defer(d3.json, "data/world.json")
      .defer(d3.csv, "data/wod.csv", function(d) { tierById.set(d.id, +d.tier_ii_plus); })
      .await(ready);

  function ready(error, json) {
    svg.append("g")
        .attr("class", "countries")
      .selectAll("path")
        .data(topojson.feature(json, json.objects.countries).features)
      .enter().append("path")
        .attr("class", function(d) { return quantize(tierById.get(d.id)); })
        .attr("d", path);

  }
}

$('button#tier_i').click(function (e) {
  $( "svg" ).empty();
  drawTierI();
});

$('button#tier_ii').click(function (e) {
  $( "svg" ).empty();
  drawTierII();
});

$('button#tier_ii_plus').click(function (e) {
  $( "svg" ).empty();
  drawTierIIPlus();
});
下面是我的一堆代码:不过,我似乎在JSON中遇到了一些语法问题

示例地图在my github上确实有效,但是:


谢谢你的帮助

您只需要选择现有路径,而不是在初始设置choropleth后追加新路径,例如

function drawTierI() {
  csv.forEach(function(d) { tierById.set(d.id, +d.tier_i); });

  function ready(error, json) {
    svg.selectAll("path")
        .attr("class", function(d) { return quantize(tierById.get(d.id)); })
        .attr("d", path);

  }
}
对于其他函数也是如此。您也不需要在每一步都重新加载JSON和CSV—上面的代码假设您的CSV数据存储在变量CSV中,您将填充该变量:

var csv;
function setUpChoropleth(error, json, _csv) {
  csv = _csv;
  // rest of setup
}
然后你可以简单地做

$('button#tier_i').click(function (e) {
  drawTierI();
});

无需先清空SVG即可更改显示的变量。

谢谢!这是有道理的。关于如何纠正切换层时出现的延迟,有什么建议吗?似乎我不应该每次点击都加载CSV和JSON,但这是我能够从CSV调用多个列的唯一方法。啊,是的,我没有注意到这一点。将更新答案。谢谢,这完全符合您的描述!多亏了你,我确实学到了一些关于D3和JS的新东西。