Reputation: 6005
I'm creating a proof of concept in v4 of D3JS. One of the things I'm trying to do is have a tooltip display when hovering over a data point. I found a good example of this here.
What I now need to do is add a link (or any clickable element) to the tooltip. I created a plunkr based on the example above and added a link to the tooltip. I can't click on the link and the tooltip appears to be below the line-chart as far as z-index goes.
I've tried setting the z-index on the chart and the tooltip to no avail. Can anyone point me in the right direction to sort this?
<!DOCTYPE html>
<meta charset="utf-8">
<style> /* set the CSS */
.line {
fill: none;
stroke: steelblue;
stroke-width: 2px;
}
div.tooltip {
position: absolute;
text-align: center;
width: 150px;
height: 100px;
padding: 2px;
font: 12px sans-serif;
background: lightsteelblue;
border: 0px;
border-radius: 8px;
pointer-events: none;
}
</style>
<body>
<!-- load the d3.js library -->
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
// set the dimensions and margins of the graph
var margin = {top: 20, right: 20, bottom: 30, left: 50},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
// parse the date / time
var parseTime = d3.timeParse("%d-%b-%y");
var formatTime = d3.timeFormat("%e %B");
// set the ranges
var x = d3.scaleTime().range([0, width]);
var y = d3.scaleLinear().range([height, 0]);
// define the line
var valueline = d3.line()
.x(function(d) { return x(d.date); })
.y(function(d) { return y(d.close); });
// append the svg obgect to the body of the page
// appends a 'group' element to 'svg'
// moves the 'group' element to the top left margin
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")");
var div = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
// Get the data
d3.csv("data.csv", function(error, data) {
if (error) throw error;
// format the data
data.forEach(function(d) {
d.date = parseTime(d.date);
d.close = +d.close;
});
// scale the range of the data
x.domain(d3.extent(data, function(d) { return d.date; }));
y.domain([0, d3.max(data, function(d) { return d.close; })]);
// add the valueline path.
svg.append("path")
.data([data])
.attr("class", "line")
.attr("d", valueline);
// add the dots with tooltips
svg.selectAll("dot")
.data(data)
.enter().append("circle")
.attr("r", 5)
.attr("cx", function(d) { return x(d.date); })
.attr("cy", function(d) { return y(d.close); })
.on("mouseover", function(d) {
div.transition()
.duration(200)
.style("opacity", .9);
div.html(formatTime(d.date) + "<br/>" + d.close + "<br/><a href='www.google.com'>Test it</a>")
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 28) + "px");
});
// add the X Axis
svg.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));
// add the Y Axis
svg.append("g")
.call(d3.axisLeft(y));
});
</script>
</body>
Upvotes: 3
Views: 1848
Reputation: 102194
When creating your tooltip based on the example in the link, you copied its CSS:
div.tooltip {
pointer-events: none;
...
}
The reason we generally set pointer-events
to none
in a <div>
tooltip, as the linked example did, is that we want to get the mouseout
event on the element that fired the mouseover
(normally to set the tooltip's opacity to zero), and if the tooltip is positioned to close from the element (sometimes even directly over it) the pointer can hover over the div and ruin the mouseout
. Besides that, another important reason to set pointer-events
to none
is that it allows other elements behind the tooltip to get mouseover
events, just like if the tooltip was not there.
However, because in your code there is no mouseout
, the easier solution here is simply eliminating the pointer-events: none
in the CSS. That way the <div>
get the click
event.
This is the updated plunker: https://plnkr.co/edit/xfa8cjQd3tHYNu0dUla4?p=preview
Upvotes: 4