Reputation: 5813
I have a d3 line chart with a tooltip, I am facing a problem with a tooltip.
I have functionality, on click of points/circle I am appending rect
to g, which is adding on top of the existing rect
which has the tooltip functionality.
My tooltip is not coming at selected(rect) Graph Point.
g.append("rect")
.attr("class", "overlay")
.attr("id", "firstLayer")
.attr("width", width)
.attr("height", height)
.on("mouseover", function(d) {
focus.style("display", null);
div
.transition()
.duration(200)
.style("opacity", 0.9);
})
.on("click", function(d, index) {
let newXScale = newX ? newX : xScale;
if (rect) rect.remove();
rect = g
.append("rect")
.attr("x", newXScale(d.startTime) - 12.5)
.attr("y", 0)
.attr("width", 24)
.attr("height", height + 5)
.attr("data", d.startTime)
.style("fill", "steelblue")
.style("opacity", 0.5);
if (clickLine) clickLine.remove();
clickLine = g
.append("line")
.attr("x1", newXScale(d.startTime))
.attr("y1", yScale(yDomain[0]))
.attr("x2", newXScale(d.startTime))
.attr("y2", yScale(yDomain[1]))
.attr("class", "focusLine")
.style("opacity", 0.5);
})
rect
element is coming on top of the gm on hover of that tooltip is not coming, any suggestions on how to fix it ?
At selected Graph Point -
CodeSandbox link below - https://codesandbox.io/s/damp-dawn-82hxc
Please guide me what can be changed.
Upvotes: 0
Views: 555
Reputation: 111
on click of the circle
you are appending another rectangle to g, which is adding on top of the existing rect
which has the tool tip
functionality
Note: d3 js adds layer/shape on top of another which basically overrides the existing layer/shape functionality with the new layer/shape if they are in the same position
To avoid that we have to draw the layers depends on their intended purpose and position.
Solution for the above problem
append background rects
for circle
you want to create with opacity: 0
g.selectAll(".faaa")
.data(data)
.enter()
.append("rect")
.attr("class", "faaa")
.attr("id", d => "rect_" + d.id)
.attr("x", d => xScale(d.startTime) - 12.5)
.attr("y", 0)
.attr("width", 24)
.attr("height", height + 5)
.attr("data", d => d)
.style("fill", "steelblue")
.style("opacity", 0);
append firstLayer
rect
which has the tooltip functionality so the background rect
won't break the tooltip
functionality
g.append("rect")
.attr("class", "overlay")
.attr("id", "firstLayer")
.attr("width", width)
.attr("height", height)
.on("mouseover", function(d) {
focus.style("display", null);
div
.transition()
.duration(200)
.style("opacity", 0.9);
})
.on("mouseout", function() {
focus.style("display", "none");
div
.transition()
.duration(300)
.style("opacity", 0);
})
.on("mousemove", function() {
var mouse = d3.mouse(this);
var mouseDate = xScale.invert(mouse[0]);
var i = bisectDate(data, mouseDate); // returns the index to the current data item
var d0 = data[i - 1];
var d1 = data[i];
let d;
// work out which date value is closest to the mouse
if (typeof d1 !== "undefined") {
d = mouseDate - d0.startTime > d1.startTime - mouseDate ? d1 : d0;
} else {
d = d0;
}
div
.html(
`<span>${parseDate(d.startTime)}</span>
<span> Changes : ${d.magnitude} % </span>`
)
.style("left", d3.event.pageX + "px")
.style("top", d3.event.pageY - 28 + "px");
var x = xScale(d.startTime);
var y = yScale(d.magnitude);
focus
.select("#focusCircle")
.attr("cx", x)
.attr("cy", y);
focus
.select("#focusLineX")
.attr("x1", x)
.attr("y1", yScale(yDomain[0]))
.attr("x2", x)
.attr("y2", yScale(yDomain[1]));
focus
.select("#focusLineY")
.attr("x1", xScale(xDomain[0]))
.attr("y1", y)
.attr("x2", xScale(xDomain[1]))
.attr("y2", y);
});
append circle
and add click
functionality then change the opacity
to highlight the background rect
g.selectAll(".foo")
.data(data)
.enter()
.append("circle")
.attr("id", d => d.id)
.attr("class", "foo")
.attr("data", d => d)
.attr("cx", function(d) {
return xScale(d.startTime);
})
.attr("cy", function(d) {
return yScale(d.magnitude);
})
.attr("r", function(d) {
return 6;
})
.on("click", function(d) {
// change the opacity here
d3.select("#rect_" + d.id).style("opacity", 0.5);
})
.attr("class", "circle");
Hope this solves the above problem...
Upvotes: 4