d3 - 部分数据加载

时间:2014-11-14 17:07:20

标签: asynchronous d3.js tooltip undefined

我的数据字符串返回'未定义'在我的工具提示中,虽然同一条数据确实影响了我的svg的颜色。

目标:我想显示一个地图,chloropleth样式,显示每个国家/地区的工具提示 a)国家名称,从.json对象加载(工作正常) b)对应于每个国家的一些值,从tsv加载(到目前为止部分工作)

文件结构: 主.js文件调用1个topojson文件(包含国家路径和名称)以及.tsv文件(包含每个国家/地区的特定区域数据)

使用的资源: 1- MBostock的氯中毒(见下面的注释) Justin Palmer的2- d3.tip

玩它

这是一个Plunker供人们使用它(由于世界的沉重感。我使用它,可能需要一段时间才能加载)。

---------------

相关代码位

  queue()
.defer(d3.json, "world.json")
.defer(d3.tsv, "winemap.tsv", function setMaptoTotal(d) { rate.set(d.name, +d.total); })
.await(ready);



 var tip = d3.tip()
      .attr('class', 'd3-tip')
       .html(function mylabel(d) { return d.properties.name  + "<table><tr><td><span style='color: #fcf772'> Total area cultivated:  " + d.total  +" ha</span></td></tr><tr><td> <span style='color:#bf2a2a'> Global rank: "+ d.rank + " </span></td></tr></table>";})
      .direction('sw')
      .offset([0, 2]);

var svg = d3.selectAll('body')
    .append('svg')
        .attr('width',width)
        .attr('height',height)
        .call(zoom)
        .call(tip);

// ACTION STARTS HERE // 
function ready(error, world) {
     svg.append("g")
      .attr("class", "counties")
    .selectAll("path")
      .data(topojson.feature(world, world.objects.countries).features)
    .enter().append("path")
 .attr("class", function (d) { return quantize(rate.get(d.properties.name)); })
      .attr("d", path)
      .call(tip)
      .on('mouseover', tip.show)
     .on('mouseout', tip.hide)
     ;

尝试了选项

1-移动.call(tip)之后 ready 函数,该函数通过queue()触发数据加载。 &GT;&GT;&GT;这仍然会在我的工具提示中返回 undefined

2-使用queue.defer(mylabel(d))。 &GT;&GT;&GT;屏幕上没有任何内容。

3-考虑到d3.tsv的异步性质,我经历了this question。如果我理解得很好,你必须在d3.tsv内部和之后引用你想要调用的函数(有或没有设置全局变量)。因此,我计划在d3.tsv内部和之后引用mylabel(d)函数。但是我注意到function (d) { return quantize(rate.get(d.properties.name)); })没有写在我的d3.tsv中,但它运行正常。

注意:抱歉,我无法在此阶段发布更多链接,例如到MBostick的chloropleth或d3.tip,但它需要更多的声誉:)

1 个答案:

答案 0 :(得分:1)

如果有人遇到同样的问题,我终于找到了答案。 有两个问题:

1-数据应首先与数组相关联。

首先,您需要在准备好的功能内配对 id 与每个数据条目配对

function ready (error, world, data)  {
 var Total= {};
 var Name= {};
 var Rank= {};

 data.forEach(function(d) {
        Total[d.id] = +d.total;
        Name[d.id] = d.name;
        Rank[d.id] = +d.rank;
 });

2-此方法仅适用于明确引用“id”

命令.data(topojson.feature(world, world.objects.countries).features)将搜索要应用转换的每个json对象的id属性。您的.tsv和.json之间的桥梁必须是id,包括.json和.tsv文件以及代码。

使用topoJSON时,无法用任何名称替换id的原因是它在topojson代码本身中保存了一个特定的函数(见下文)。

{var r={type:"Feature",id:t.id,properties:t.properties||{},geometry:u(n,t)};return null==t.id&&delete r.id,r}

我通过在.tsv文件中添加一个列,其中包含我的.json文件中所有id个对象的countries属性。我将此列命名为id,因此 1 - 中描述的配对可以正常运行。

小心,您希望代表.tsv上.json中的所有国家/地区,否则当您悬停在.tsv上未提及的国家/地区时,“undefined”将再次出现。

最后,工作代码 -

 function ready (error, world, data)  {
     var pairDataWithId= {};
     var pairNameWithId= {};
     var pairRankWithId= {};
    // “d” refers to that data parameter, which in this case is our .csv that (while not necessary) is also named “data.” 
     data.forEach(function(d) {
            pairDataWithId[d.id] = +d.total;
            pairNameWithId[d.id] = d.name;
            pairRankWithId[d.id] = +d.rank;
     });

 // Below my tooltip vars
 var tipin =  function(d) { d3.select(this).transition().duration(300).style('opacity', 1);
 div.transition().duration(300).style('opacity', 1);
 div.text(pairNameWithId[d.id] + " Total Area: "  + pairDataWithId[d.id]+ " Rank: "  + pairRankWithId[d.id])
    .style('left', (d3.event.pageX) + "px")
    .style('top', (d3.event.pageY -30) + "px");
    };
 var tipout =  function() {
     d3.select(this)
     .transition().duration(300).style('opacity', 0.8);
     div.transition().duration(300)
     .style('opacity', 0);
 };

 // Resume

function colorme(d) { return color (pairDataWithId[d.id]);
}

     svg.append('g')
     .attr('class', 'region')
     .selectAll('path')
     .data(topojson.feature(world,world.objects.countries).features)
     .enter()
     .append('path')
     .attr('d', path)
     .style('fill', colorme)
     .style('opacity', 0.8)
     .on ('mouseover', tipin)
     .on('mouseout', tipout);    
 };

注意:我已停止使用d3.tip获取上述完整代码的更简单版本。