nacyot's blog

D3.js로 인터랙티브 세계 지도 만들기 (Markdown)

2025-12-30

D3.js는 지리 데이터 시각화에도 뛰어난 도구입니다. 이 튜토리얼에서는 GeoJSON 데이터를 사용하여 세계 지도를 단계별로 발전시켜 나갑니다.

Step 1: 기본 지도

가장 기본적인 세계 지도입니다. TopoJSON 데이터를 불러와 SVG로 렌더링합니다.

// 기본 투영법과 경로 생성기
const projection = d3.geoNaturalEarth1()
  .scale(width / 5.5)
  .translate([width / 2, height / 2]);

const path = d3.geoPath().projection(projection);

// 국가 경로 그리기
svg.selectAll("path")
  .data(geojson.features)
  .join("path")
  .attr("d", path);

Step 2: 스타일링

색상과 테두리를 추가하여 지도를 더 보기 좋게 만듭니다. 격자선(graticule)도 추가합니다.

// 격자선 추가
const graticule = d3.geoGraticule();
g.append("path")
  .datum(graticule())
  .attr("d", path)
  .attr("fill", "none")
  .attr("stroke", "#ccc");

// 국가 스타일링
g.selectAll("path.country")
  .attr("fill", "#69b3a2")
  .attr("stroke", "#fff")
  .attr("stroke-width", 0.5);

Step 3: 호버 인터랙션

마우스를 국가 위에 올리면 하이라이트되고 툴팁이 표시됩니다.

// 호버 이벤트
.on("mouseover", function(event, d) {
  d3.select(this).attr("fill", "#3d8b6e");
  tooltip.style("opacity", 1)
    .html(d.properties.name);
})
.on("mouseout", function() {
  d3.select(this).attr("fill", "#69b3a2");
  tooltip.style("opacity", 0);
});

Step 4: 줌 & 팬

마우스 휠로 줌, 드래그로 팬이 가능합니다. 특정 지역을 자세히 살펴볼 수 있습니다.

// 줌 동작 설정
const zoom = d3.zoom()
  .scaleExtent([1, 8])  // 1x ~ 8x 줌
  .on("zoom", (event) => {
    g.attr("transform", event.transform);
  });

svg.call(zoom);

Step 5: Choropleth (단계구분도)

데이터에 따라 국가별로 다른 색상을 적용합니다. 여기서는 임의의 값을 사용합니다.

// 색상 스케일
const colorScale = d3.scaleSequential()
  .domain([0, 100])
  .interpolator(d3.interpolateBlues);

// 데이터 기반 색상 적용
.attr("fill", d => {
  const value = getData(d.id);  // 실제 데이터에서 가져옴
  return colorScale(value);
});

정리

이 튜토리얼에서 다룬 내용:

  1. 기본 지도: TopoJSON 로드, 투영법, 경로 생성
  2. 스타일링: 색상, 테두리, 격자선
  3. 인터랙션: 호버 효과, 툴팁
  4. 줌 & 팬: d3.zoom() 활용
  5. Choropleth: 데이터 기반 색상 매핑

다음 단계로는 실제 데이터(인구, GDP 등)를 연결하거나, 마커/포인트를 추가하거나, 애니메이션을 적용할 수 있습니다.