목표
before mouse hover
when hovering mouse
위 이미지(출처)와 같이,
여러 dataset을 하나의 line chart에서 보여주고,
label에 mouse hover했을 때 해당 dataset만 강조하려고 한다.
이미지는 이해를 돕기 위한 예시이다.
위 예시는 amchart 라이브러리를 사용하여 구현되었으며,
나는 chart.js로 위 기능을 구현하고자 한다.
1차 Solution
- chart option > legend에
onHover
,onLeave
이벤트 핸들러 추가
1차 Result
아래 이미지와 같이 매우 잘 동작하는 것을 확인할 수 있다. 깔끔!
before mouse hoverwhen hovering mouse3
문제 상황 1
chart와 legend 사이의 간격을 조절하고 싶어졌다.
chart.js 기본 legend를 사용하면, legend와 chart 사이 간격을 조절할 수 없다.
legend가 canvas 내부에 같이 그려지기 때문이다.
chart option > legend > padding 을 부여하여 gap을 띄울 수 있는데,
legend item 기준 상하좌우 모두로 padding이 먹어버려
legend item간 간격도 벌어지고 legend 위로도 여백이 생겨 보기 좋지 않다.
(paddingLeft 등으로 상하좌우 구분하여 먹일 수 없다 ㅜ)
출처 : https://stackoverflow.com/questions/42585861/chart-js-increase-spacing-between-legend-and-chart
나만 이런 생각을 한 것은 당연히 아닐테니,, reference를 찾아보았다.
Chart.js 공식 github에 다음과 같은 issue가 있었다.
내 생각과 연관된 chart.js github issue
아쉽지만 결론은, chart.js의 내장 legend 말고 HTML Legend를 사용하라! 였다.
2차 Solution : HTML Legend
chart.js 공식 문서를 바탕으로, HTML legend를 구현해 보았다.
기존 onHover
, onLeave
이벤트 핸들러도 부착했다.
문제 상황 2
기본 기능들은 잘 동작한다.
다만 마우스를 빠르게 이동하여 legend를 스쳐지나갈 때,
hover는 catch하고 leave는 catch하지 못하여
마우스가 chart 바깥에 있음에도 dataset 하나를 계속 강조하고 있게 되는 현상이 발생했다.
hover 후 빠르게 chart에서 마우스 leave 했을 때 강조가 남아있는 현상
원인
정상적인 이벤트 발생 순서는 아래와 같다.
- hover, leave 이벤트 핸들러 부착
- legend mouse hover
- highlight 로직 실행
- highlight 완료 후 chart update 실행
- 이벤트 핸들러 초기화 및 차트 색상 업데이트
- 초기화된 요소에 hover, leave 이벤트 핸들러 재부착
- legend mouse leave
- reset 로직 실행
- reset 완료 후 chart update 실행
- 이벤트 핸들러 초기화 및 차트 색상 업데이트
마우스를 매우 빠르게 이동시켰을 경우,
5번 과정 완료 후 6번 과정이 수행되기 전에 마우스가 이미 요소 바깥에 위치하게 되어
leave 이벤트 핸들러가 이를 catch하지 못하는 것이다.
highlight, reset 로직 내에서 chart.update()
를 수행하기 때문에 발생하는 필연적인 결과였다.
(색상 변경 후 chart.update()
를 반드시 수행해야만 차트에 반영된다.)
이를 해결하기 위해 이것저것 시도해 보았으나, 실패였다.
chart.js 의 plugin을 직접 구현한 것이기 때문에,
Chart Plugin Life Cycle을 제대로 이해하고 적절한 시기에 이벤트 핸들러를 지정해주면 될 것 같다고는 생각되나,
그 정확한 시점을 찾을 수 없었다.
일단 이 정도로만 마무리하고, 더 고민해본 다음 해결해 봐야겠다..