I have been trying to solve a tooltip problem for quite some time now. I have searched through Stackoverflow and I think my problem is that I am not yet knowledgable enough to piece together a solution from existing posts. I am working on a d3 chart which you can view here, in all its broken glory:
Link to broken chart.
The default "Global" view works. When the "US" button is pressed, the data update correctly; but the tooltips do not. There are more data points in the US dataset than the default Global dataset. The difference in data points is the exact number of tooltips I am missing. I am struggling to use the Update Selection to gain access to the entering tooltips, I can't seem to get at them.
Below please find the d3 code I am using to generate the default view (this is working for me so far):
d3.tsv("data/global.tsv", function(error, data) {
data.forEach(function(d){
d.change = +d.change;
d.score = +d.score;
});
//Create circles
svg.selectAll("circle")
.data(data)
.enter()
.append("circle")
.attr("cx", function(d) {
return xScale(d.change);
})
.attr("cy", function(d){
return yScale(d.score);
})
.attr("r", 7)
.attr("class","chart")
.style("opacity",.8)
.style("fill", function(d) {
return d.code;
})
.on("mouseover", function(d) {
var xPosition = parseFloat(d3.select(this).attr("cx"));
var yPosition = parseFloat(d3.select(this).attr("cy"));
//Update the tooltip position and value
d3.select("#tooltip")
.style("left", xPosition + "px")
.style("top", yPosition + "px")
.select("#brand")
.style("color", d3.select(this).style("fill"))
.text(d.brand);
d3.select("#tooltip")
.select("#change")
.text(d.change);
d3.select("#tooltip")
.select("#score")
.text(d.score);
//Show the tooltip
d3.select("#tooltip").classed("hidden", false); //quickly apply or remove classes from an element
})
.on("mouseout", function() {
//Hide the tooltip
d3.select("#tooltip").classed("hidden", true); //quickly apply or remove classes from an element
})
}); //this ends the code on the selected svg element
The block of code below correctly updates my scatterplot when a user clicks on the "US" button:
d3.selectAll("#us_data").on("click", function() {
d3.tsv("data/us.tsv", function(error, data) {
data.forEach(function(d) {
d.change = +d.change;
d.score = +d.score;
});
var circles = svg.selectAll("circle")
.data(data);
circles.enter()
.append("circle")
.attr("cx", function(d) { return xScale(d.change); })
.attr("cy", function(d){ return yScale(d.score); })
.attr("r", 7)
.attr("class","chart")
.style("opacity",.8)
.style("fill", function(d) { return d.code; });
circles.transition()
.duration(500)
.attr("cx", function(d) { return xScale(d.change); })
.attr("cy", function(d){ return yScale(d.score); })
.attr("r", 7)
.attr("class","chart")
.style("opacity",.8)
.style("fill", function(d) { return d.code; });
But when I try to use the same format to update my tooltips for the US selection, nothing happens. I do not yet understand enough JavaScript (or d3) to stray far from existing conventions... so I am sure this is where I fall down.
var labels = d3.selectAll("#tooltip")
.data(data);
labels.enter()
.append("#tooltip")
.select("#brand")
.style("color", d3.select(this).style("fill"))
.text(d.brand);
labels.transition()
.duration(500)
.select("#brand")
.style("color", d3.select(this).style("fill"))
.text(d.brand);
labels.enter()
.append("#tooltip")
.select("#change")
.text(d.change);
labels.transition()
.duration(500)
.select("#change")
.text(d.change);
labels.enter()
.append("#tooltip")
.select("#score")
.text(d.score);
I am using this code to create the tooltips on my html page:
<div id="tooltip" class="hidden">
<p>Brand: <strong><span id="brand">name</span></strong></p>
<p>Change: <span id="change">100</span></p>
<p>Score: <span id="score">100</span></p>
</div>
Any advice is greatly appreciated.
Best, Gail Z