Reputation: 5832
I'm trying to add a tooltip to my donut's slices on moues over as follow:
var tooltip = select("g.arc--first")
//.append("div") // if I add this div here it stops working
.append("text")
firstSlice.append('path')
.attr('d', coolArc(firstRadius, thickness))
.attr('class', d => `fill_${weightScale(d.data.weight)}`)
.on('mouseover', (d) => {
tooltip.style("visibility", "visible")
.text(this.nodeByName.get(d.data.name)["Short Description"])
.style("fill", "red")
.style("position", "absolute")
.style("text-align", "center")
.style("width", "60px")
.style("height", "28px")
.style("padding", "2px")
.style("background", "lightsteelblue")
.style("border", "10px")
})
My goal is to have a tooltip similar to http://bl.ocks.org/d3noob/a22c42db65eb00d4e369 , but right now it only shows a red text at the middle of the page. I think I need to have a new div
but when I try to add append("div")
it stops working and doesn't show the text anymore. How should I fix it?
Upvotes: 1
Views: 646
Reputation: 8509
The tooltip from the example that you mentioned works pretty simply. It is appended as a child element for body
(you try to append it as a child for g
element, but you cannot append html elements into svg). So you should change you code:
var tooltip = select('body')
.append('div')
.attr('class', 'tooltip');
I also recommend you style this tooltip in your css (add appropriate class name and rules in your css file) you can avoid chaining many .style
methods in this case. You should set position: absolute;
rule - you can update top
and left
styles and position the tooltip where you need. Also set visibility: hidden
rule - your tooltip should be hidden by default.
In mouseover
event handler you need to change:
visibility
style to show the tooltip
left
and top
styles to position the tooltip
text
to update text on the tooltip
.on('mouseover', (d) => {
tooltip
.style('visibility', 'visible')
.style('left', d3.event.pageX + 'px')
.style('top', d3.event.pageY + 'px')
.text(d);
})
In mouseout
event handler you should just hide the tooltip:
.on('mouseout', (d) => {
tooltip
.style('visibility', 'hidden')
});
See simplified demo in the hidden snippet below:
var tooltip = d3.select("body")
.append("div")
.attr('class', 'tooltip');
d3.selectAll('circle')
.data(['one', 'two', 'three'])
.on('mouseover', (d) => {
tooltip
.style('visibility', 'visible')
.style('left', d3.event.pageX + 'px')
.style('top', d3.event.pageY + 'px')
.text(d);
})
.on('mouseout', (d) => {
tooltip
.style('visibility', 'hidden')
})
.tooltip {
background-color: lightblue;
font-weight: bold;
padding: 5px;
border-radius: 9px;
position: absolute;
display: inline-block;
margin-top: -50px;
visibility: hidden;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.js"></script>
<svg width="720" height="120">
<circle cx="20" cy="60" r="10"></circle>
<circle cx="180" cy="60" r="10"></circle>
<circle cx="340" cy="60" r="10"></circle>
</svg>
Upvotes: 2