새발블로그
D3로 값 범위(Orders-of-Magnitude)가 큰 시계열을 정확하게 시각화하는 방법 본문
1. 문제 배경
시계열 데이터에서 값의 크기 차이가 수십~수천 배 이상 벌어지는 경우(예: 0.1 ~ 100000), 선형 스케일(linear)만으로는 다음 문제가 발생
- 작은 값들이 바닥에 평평하게 깔려 보임 → 정보 손실
- 이상치(outlier) 때문에 전체 분포가 왜곡됨
- 추세·분포·이상치를 한 번에 보기 어려움
이때 필요한 것이 스케일 보정(Scaling) 이며, D3.js는 이를 정확하고 유연하게 처리할 수 있는 도구를 제공합니다.
2. D3 스케일은 정확히 무엇인가?
D3의 scale() 함수는 도메인(domain) 값을 픽셀(range) 값으로 변환하는 함수입니다.
value (domain) ---> scale ---> pixel (range)
예시:
const y = d3.scaleLinear()
.domain([0, 100]) // 실제 데이터 범위
.range([300, 0]); // 화면 y축 픽셀
스케일은 그 자체로 수학적 함수이며:
- scale(value) → 데이터 → 픽셀
- scale.invert(px) → 픽셀 → 데이터
을 수행
D3의 스케일은 단순 선형뿐 아니라 로그/시간/밴드/파워/퀀타일 등 다양한 공간 변환을 지원합니다.
3. 선형 스케일 vs 로그 스케일
Linear (d3.scaleLinear)
- 값의 차이가 덧셈적일 때 적합
- 큰 값 하나 때문에 작은 값이 눌려보이는 문제 발생
Log (d3.scaleLog)
- 값의 차이가 곱셈적(비율적)일 때 적합
- 수십~수천 배 차이도 자연스럽게 표현
주의사항:
- 0 이하 값 불가능 (log 특성)
- 최소값은 반드시 0보다 큰 값으로 보정해야 함
예:
const y = d3.scaleLog()
.clamp(true)
.domain([
Math.max(0.1, d3.min(data, d => d.y)),
d3.max(data, d => d.y)
])
.range([h, 0]);
4. 축(Axis)과 라인(Line) 생성
const x = d3.scaleLinear()
.domain(d3.extent(data, d => d.x))
.range([0, w]);
const y = scaleType === 'log'
? d3.scaleLog().domain([yMin, yMax]).range([h, 0])
: d3.scaleLinear().domain([yMin, yMax]).range([h, 0]);
const line = d3.line()
.x(d => x(d.x))
.y(d => y(d.y))
.curve(d3.curveMonotoneX);
5. 비교이미지


위 두 장의 차트에서 보이는 것처럼 Linear 스케일에서는 작은 값이 바닥에 깔려 보이지만, Log 스케일에서는 값의 비율(orders-of-magnitude)을 기반으로 눈금을 배치하기 때문에 작은 값의 패턴과 변동성까지 모두 드러난다.
'Client > Vue.js' 카테고리의 다른 글
| SPA 환경에서 이탈률(Exit/Bounce)·체류시간(Dwell)을 정확히 측정하는 방법 (0) | 2025.11.10 |
|---|---|
| [Vue.js] Pinia로 Vue 상태 관리하기 (0) | 2025.05.04 |
| [Vue.js] Vue 3에서 API 호출은 언제 하는 게 맞을까? (0) | 2025.05.04 |
| [Vue.js] Vue 생명주기 (0) | 2025.05.04 |
| [Vue.js] Composition API (0) | 2025.05.04 |