I'm experimenting with a D3 world map and use this example to build upon: http://techslides.com/demos/d3/worldmap-template.html
Now I would like to achieve a tooltip similar to the one in place for the countries (ie highlight and show name) for the cities plotted onto the map.
So far I have pasted and slightly altered the code for the country-tooltip and tried to connect it to the city date from the csv. This is the later part of the code with original comments and my copy-pasting:
//function to add points and text to the map (used in plotting capitals)
function addpoint(lat,lon,text) {
var gpoint = g.append("g").attr("class", "gpoint");
var x = projection([lat,lon])[0];
var y = projection([lat,lon])[1];
gpoint.append("svg:circle")
.attr("cx", x)
.attr("cy", y)
.attr("class","point")
.attr("r", 1.5);
//conditional in case a point has no associated text
if(text.length>0){
gpoint.append("text")
.attr("x", x+2)
.attr("y", y+2)
.attr("class","text")
.text(text);
}
gpoint
.on("mousemove", function(d,i) {
var mouses = d3.mouse(svg.node())
.map( function(d) { return parseInt(d); } );
tooltip.classed("hidden", false)
.attr("style", "left:"+(mouses[0])+"px;top:"+(mouses[1])+"px")
.html(d.CapitalName);
})
.on("mouseout", function(d,i) {
tooltip.classed("hidden", true);
});
When I now hover over one of the capitals it gives me `Cannot read property 'CapitalName' of undefined.
Can anyone help me?
As I said in my comment,
Have you bound any data to gpoint? It doesn't look like it, so d3 isn't going to pass a datum (the d in your mousemove function). Hence the error: Cannot read property 'CapitalName' of undefined
This is becuase you aren't using d3
data-binding. If I'm reading your code correctly, you are doing something like this:
var myDat = [{lat: 34, lon: 39, CapitalName: "akdjf"}, etc...]
for (var i = 0; i < myDat.length; i++){
addpoint(myDat[i].lat,myDat[i].lon,myDat[i].CapitalName);
}
d3
though, wants your data bound and then it loops internally. Something like this (totally untested but hope you can get the idea):
d3.csv("data/country-capitals.csv", function(err, capitals) {
var gpoint = g.selectAll('.gpoint')
.data(capitals) //<-- bind your data
.enter() //<-- enter selection
.append("g")
.attr("class", "gpoint");
gpoint.append("circle")
.attr("cx", function(d, i){
return projection([d.lat,d.lon])[0]; //<-- bound data and d is passed in...
}).attr("cy", function(d, i){
return projection([d.lat,d.lon])[1];
});
gpoint.on("mousemove", function(d,i) {
var coors = d3.mouse(this);
tooltip.classed("hidden", false)
.attr("style", "left:"+(coors.x)+"px;top:"+(coors.y)+"px") //<- use d3.mosue to get position
.html(d.CapitalName); //<-- bound data d is passed...
});
}
EDIT FOR COMMENT
Yes, you'll need to convert to numbers. d3
provides a handy callback for it:
d3.csv("data/country-capitals.csv", function(d) {
return {
CapitalLongitude = +d.CapitalLongitude,
CapitalLatitude = +d.CapitalLatitude,
CapitalName = d.CapitalName
};
}, function(error, capitals) {
// rest of code here
});
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.