Asynchronous d3-数据部分加载

Asynchronous d3-数据部分加载,asynchronous,d3.js,tooltip,undefined,Asynchronous,D3.js,Tooltip,Undefined,我的工具提示中返回“undefined”的数据字符串有一个问题,而同一段数据确实会影响svg的颜色 目标:我想显示一个地图,chloroleth样式,显示每个国家的工具提示 a) 国家名称,从.json对象加载(工作正常) b) 从tsv加载的对应于每个国家/地区的一些值(到目前为止部分有效) 文件结构: main.js文件调用1个topojson文件(带有国家路径和名称)以及一个.tsv文件(带有每个国家的特定区域数据) 使用的资源: 1-MBostock的氯胺(见以下注释) 2-d3.贾斯汀

我的工具提示中返回“undefined”的数据字符串有一个问题,而同一段数据确实会影响svg的颜色

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

文件结构: main.js文件调用1个topojson文件(带有国家路径和名称)以及一个.tsv文件(带有每个国家的特定区域数据)

使用的资源: 1-MBostock的氯胺(见以下注释) 2-d3.贾斯汀·帕尔默的提示

玩它 下面是一个供人们使用的示例(由于我使用的world.json很重,加载它可能需要一些时间)

--------------- 相关代码位

  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)
     ;
queue()
.defer(d3.json,“world.json”)
.defer(d3.tsv,“winemap.tsv”,函数setmaptotottal(d){rate.set(d.name,+d.total);})
.等待(准备好);
var tip=d3.tip()
.attr('class','d3 tip')
.html(函数mylabel(d){return d.properties.name+“耕地总面积:”+d.Total+“ha全局排名:”+d.rank+”;})
.方向(“sw”)
.偏移量([0,2]);
var svg=d3.selectAll('body')
.append('svg')
.attr('width',width)
.attr('height',height)
.呼叫(缩放)
.打电话(小费);
//行动从这里开始
功能就绪(错误,世界){
svg.append(“g”)
.attr(“类”、“县”)
.selectAll(“路径”)
.data(topojson.feature(world,world.objects.countries.features)
.enter().append(“路径”)
.attr(“类”,函数(d){返回量化(rate.get(d.properties.name));})
.attr(“d”,路径)
.电话(提示)
.on('mouseover',tip.show)
.on('mouseout',tip.hide)
;
已尝试选项

1-在通过queue()触发数据加载的ready函数之后或内部移动.call(提示)。>>>这仍然会在我的工具提示中返回未定义的

2-使用
queue.defer(mylabel(d))
>屏幕上不显示任何内容

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


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

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

1-数据应首先与数组关联。 首先,您需要在ready函数中,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
属性。在.json和.tsv文件以及代码中,.tsv和.json之间的桥梁必须是
id

在使用topoJSON时,不能仅用任何名称替换
id
,原因是它在topoJSON代码本身中具有特定的功能(请参见下文)

我在.tsv文件中添加了一列,其中包含.json文件中所有
国家
对象的
id
属性。我将该列命名为
id
,以便1-中描述的配对可以正常工作

请小心,您希望在.tsv上表示.json中的所有国家,否则当您悬停在.tsv上不会提及的国家时,“未定义”将再次出现

最终工作守则-

 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以获得上面完整代码的更简单版本。

您似乎没有使用包含您要使用的信息的CSV数据。它不会自动合并,您需要根据各自国家的名称在其中查找信息。
 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);    
 };