회사에서 신규 화면 구성을 위해 Chart.js를 사용하던 중 복장터지는 레이아웃 버그를 하나 만나게 되는데...
바로 이 툴팁의 위치가 미묘하게 왼쪽으로 틀어져버리는 버그였다. Chart.js 옵션 중 stack이라는 것을 활용하면 위처럼 하나의 bar 엘레먼트에 두 데이터를 쌓아서 표시할 수 있는데, 이 경우에 툴팁의 포지션이 틀어져버리는 것이었다.
왜그러는 것인가.. 소스 코드를 분석하던 중 툴팁 관련 로직이 모여있는 plugin.tooltip.js 파일을 발견. 이 파일 안에 있는 `positioners.average` 함수가 툴팁의 위치를 계산해주는 놈이었다.
const positioners = {
average(items) {
if (!items.length) {
return false;
}
let i, len;
let x = 0;
let y = 0;
let count = 0;
for (i = 0, len = items.length; i < len; ++i) {
const el = items[i].element;
if (el && el.hasValue()) {
const pos = el.tooltipPosition();
x += pos.x;
y += pos.y;
++count;
}
}
return {
x: x / count,
y: y / count
};
},
// ...
}
모든 아이템의 x 값을 다 더해서 평균을 내기 때문에 stack 기능을 사용하는 경우 stack이 생긴 요소의 x 값이 중복으로 더해지기 때문에 포지션이 쏠리는 현상이 발생하게 된다. 즉 중복된 x 포지션 값이 온다면 평균 계산에 포함시키지 않고 무시해줘야 하는 상황.
깔끔하게 Set으로 개선.
const positioners = {
average(items) {
if (!items.length) {
return false;
}
let i, len;
// x 값들을 다 더하지 않고 Set으로 변경
let xSet = new Set();
let y = 0;
let count = 0;
for (i = 0, len = items.length; i < len; ++i) {
const el = items[i].element;
if (el && el.hasValue()) {
const pos = el.tooltipPosition();
// 여기서 중복된 x 값이 들어오게 된다면 무시된다
xSet.add(pos.x);
y += pos.y;
++count;
}
}
const xAverage = [...xSet].reduce((a, b) => a + b) / xSet.size;
return {
x: xAverage,
y: y / count
};
},
// ...
}
코드 수정후 해당 변경에 대한 테스트 코드까지 작성해서 Pull Request 생성.
메인테이너 두 명의 승인 후 머지까지 일사천리로 진행되어 기분이 좋다. :)
'프로그래밍 > 웹' 카테고리의 다른 글
혜움 레포트 프론트 개선 - 2 (1) | 2024.01.08 |
---|---|
혜움 레포트 프론트 개선 - 1 (1) | 2024.01.05 |
타입스크립트가 싫다 (0) | 2021.04.15 |
웹 푸시 구현에 대한 고민 (0) | 2019.08.01 |
[번역글] 자바스크립트의 이벤트 처리 순서 (Event order in Javascript) (0) | 2018.02.19 |