레슨 3 / 8·20분
도형과 트랜지션
SVG 기본 도형
D3는 SVG 요소를 직접 조작하므로 SVG의 기본 도형을 이해하는 것이 중요합니다. rect(사각형), circle(원), line(직선), path(경로) 등을 데이터 바인딩과 함께 사용합니다.
javascript
const svg = d3.select('#chart')
.append('svg')
.attr('width', 500)
.attr('height', 300);
// 사각형 (rect)
svg.append('rect')
.attr('x', 10).attr('y', 10)
.attr('width', 100).attr('height', 60)
.attr('fill', '#3b82f6')
.attr('rx', 8); // 둥근 모서리
// 원 (circle)
svg.append('circle')
.attr('cx', 200).attr('cy', 40)
.attr('r', 30)
.attr('fill', '#ef4444');
// 직선 (line)
svg.append('line')
.attr('x1', 280).attr('y1', 10)
.attr('x2', 400).attr('y2', 70)
.attr('stroke', '#10b981')
.attr('stroke-width', 3);선 생성기(Line Generator)로 꺾은선 그래프 만들기
javascript
const data = [
{ date: '01/01', value: 30 },
{ date: '01/02', value: 50 },
{ date: '01/03', value: 45 },
{ date: '01/04', value: 70 },
{ date: '01/05', value: 60 },
];
const x = d3.scalePoint()
.domain(data.map(d => d.date))
.range([50, 450]);
const y = d3.scaleLinear()
.domain([0, d3.max(data, d => d.value)])
.range([250, 20]);
// d3.line()으로 path의 d 속성 문자열 생성
const lineGenerator = d3.line()
.x(d => x(d.date))
.y(d => y(d.value))
.curve(d3.curveMonotoneX); // 부드러운 곡선
svg.append('path')
.datum(data)
.attr('d', lineGenerator)
.attr('fill', 'none')
.attr('stroke', '#6366f1')
.attr('stroke-width', 2.5);트랜지션(Transition)
D3의 트랜지션은 속성 값의 변화를 부드러운 애니메이션으로 보간합니다. .transition()을 체인에 추가하면 이후의 .attr()이나 .style() 변경이 점진적으로 적용됩니다.
javascript
// 막대가 아래에서 올라오는 애니메이션
svg.selectAll('rect')
.data(data)
.join('rect')
.attr('x', (d, i) => xScale(d.label))
.attr('width', xScale.bandwidth())
.attr('y', innerHeight) // 시작: 바닥
.attr('height', 0) // 시작: 높이 0
.attr('fill', '#6366f1')
.transition()
.duration(800) // 800ms 동안
.delay((d, i) => i * 100) // 각 막대 100ms씩 지연
.ease(d3.easeBackOut) // 이징 함수
.attr('y', d => yScale(d.value)) // 끝: 데이터 위치
.attr('height', d => innerHeight - yScale(d.value)); // 끝: 데이터 높이외부 데이터 로드
javascript
// CSV 파일 로드 (자동으로 파싱)
const csvData = await d3.csv('/data/sales.csv', (d) => ({
month: d.month,
revenue: +d.revenue, // 문자열 → 숫자 변환
}));
// JSON 파일 로드
const jsonData = await d3.json('/data/countries.json');
// 로드한 데이터로 시각화
console.log(csvData); // [{month: "1월", revenue: 150}, ...]- •.transition() — 이후 속성 변경을 애니메이션으로 처리
- •.duration(ms) — 애니메이션 지속 시간
- •.delay(ms | fn) — 시작 전 지연 시간 (함수로 각 요소별 지연 가능)
- •.ease(fn) — d3.easeLinear, d3.easeBounce, d3.easeBackOut 등
- •d3.csv(url, row) — CSV 로드 및 행 변환 함수 적용
- •d3.json(url) — JSON 데이터 비동기 로드
💡
D3의 .join() 메서드(v5.8+)는 enter/update/exit 패턴을 간결하게 처리합니다. .data(newData).join("rect")만으로 추가/갱신/제거가 자동 처리됩니다.