d3 + react tooltip 만들기

마우스를 호버했을 때 뜨는 툴팁을 만들기 위한 두 가지 방법이 있다.

overlay를 사용하기

첫 번째 방법은 svg 내부에 많은 요소들이 있어서 요소를 어디에 등록할지 애매할 경우에 유용하다.

필수적인 조건은 요소들이 Scale로 위치를 계산하여 svg 내부에 위치해야 한다.

첫 번째 방법은 요소 최상단에 보이지 않는 얇은 층을 쌓는 것이다.

나는 임의로 overlay라고 이름지었다..!

opacity를 0으로 주어 보이지 않지만 분명히 존재한다.

1
2
3
4
5
6
7
const overlay = svg
.selectAll(".overlay")
.attr("opacity", 0)
.attr("width", width - marginLeft)
.attr("height", height - marginBottom)
.attr("fill", overlayColor)
.style("pointer-events", "all");

이제 이 overlay에 이벤트를 등록하면 된다.

1
2
3
4
5
6
7
8
9
10
11
overlay
.on("mouseover", focus.style("display", null))
.on("mouseout", focus.style("display", "none"));
.on("mousemove", function(e){
const focus = select(".focus");
const bisectDate = bisector((data) => data.date).left;
const curPosition = xScale.invert(pointer(e, e.target)[0]);
// 현재 포인터를 기반으로 xScale 내부에서의 위치정보를 구한다.
const i = bisectDate(data, curPosition, 1);
// 현재 마우스 위치를 기반으로 데이터 배열에서 해당 위치의 index를 구한다.
})

마우스 위치에 가까운 요소에 직접 접근할 수 있다.

요소에 직접 이벤트 등록하기

body에 relative속성을 주고 focus에 position:absolute를 주어 left와 right로 위치를 정해주는 방법이다.

어떤 요소를 기준으로 하냐에 따라 eventX를 사용할지 offsetX를 사용할지가 달라진다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var tooltip = d3
.select("#my_dataviz")
.append("div")
.style("position", "absolute")
.style("visibility", "hidden")
.text("I'm a circle!");

d3.select("#circleBasicTooltip")
.on("mouseover", function () {
return tooltip.style("visibility", "visible");
})
.on("mousemove", function (event) {
return tooltip
.style("top", event.pageY - 800 + "px")
.style("left", event.pageX - 800 + "px");
})
.on("mouseout", function () {
return tooltip.style("visibility", "hidden");
});

댓글