我的数据字符串返回'未定义'在我的工具提示中,虽然同一条数据确实影响了我的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,但它需要更多的声誉:)
答案 0 :(得分: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;
});
命令.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获取上述完整代码的更简单版本。