I have a problem with a data string returning 'undefined' in my tooltip, while that same piece of data does affect the colors of my svg.
Objective: I want to display a map, chloropleth style, that displays a tooltip for each country with a) country names, loaded from a .json object (works fine) b) some values corresponding to each country, loaded from a tsv (works partially so far)
File structure : The main .js file calls 1 topojson file (with country paths and names) as well as a .tsv file (with specific area data for each country)
Resources used: 1- MBostock's chloropleth (see note below) 2- d3.tip by Justin Palmer
Play with it
Here is a Plunker for people to play with it (due to the heaviness of the world.json I use, it may take a while to load).
---------------
Relevant code bit :
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)
;
Options tried:
1- Moving .call(tip) after or inside the ready function which triggers data load via queue(). >>> This still returns undefined in my tooltip.
2- Use queue.defer(mylabel(d))
. >>> Nothing appears on screen.
3- Taking into account the asynchronous nature of d3.tsv, I went through this question. If I understand well, you have to refer to the function you want to call both inside and after d3.tsv (with or without setting a global variable). I thus planned to refer to the mylabel(d)
function both inside and after d3.tsv. However I noticed that function (d) { return quantize(rate.get(d.properties.name)); })
is not written in my d3.tsv
yet it works fine.
Note: sorry I could not post more links at this stage, e.g. to MBostick's chloropleth or d3.tip, but it requires more reputation :)