D3.js 파이 차트(Pie Chart) 만들기
예제 프로그램
예제 코드
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>D3 Pie Chart</title>
<script src="https://d3js.org/d3.v7.min.js"></script>
</head>
<body>
<script>
// 1. 데이터 준비
var dataset = [
{ "name": "A", "value": 5 },
{ "name": "B", "value": 6 },
{ "name": "C", "value": 8 },
{ "name": "D", "value": 1 },
{ "name": "E", "value": 2 },
{ "name": "F", "value": 6 },
{ "name": "G", "value": 8 },
{ "name": "H", "value": 6 },
{ "name": "I", "value": 10 },
{ "name": "J", "value": 9 }
]
var width = 400; // 그래프 넓이
var height = 300; // 그래프 높이
var radius = Math.min(width, height) / 2 - 10;
// 2. SVG 영역 설정
var svg = d3.select("body").append("svg").attr("width", width).attr("height", height);
var g = svg.append("g").attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
// 3. 컬러 설정
var color = d3.scaleOrdinal()
.range(["#DC3912", "#3366CC", "#109618", "#FF9900", "#990099"]);
// 4. pie 차트 dateset에 대한 함수 설정
var pie = d3.pie()
.value(function(d) { return d.value; })
.sort(null);
// 5. pie 차트 SVG 요소 설정
var pieGroup = g.selectAll(".pie")
.data(pie(dataset))
.enter()
.append("g")
.attr("class", "pie");
arc = d3.arc()
.outerRadius(radius)
.innerRadius(0);
pieGroup.append("path")
.attr("d", arc)
.attr("fill", function(d) { return color(d.index) })
.attr("opacity", 0.75)
.attr("stroke", "white");
// 6. pie 차트 텍스트 SVG 요소 설정
var text = d3.arc()
.outerRadius(radius - 30)
.innerRadius(radius - 30);
pieGroup.append("text")
.attr("fill", "black")
.attr("transform", function(d) { return "translate(" + text.centroid(d) + ")"; })
.attr("dy", "5px")
.attr("font", "10px")
.attr("text-anchor", "middle")
.text(function(d) { return d.data.name; });
</script>
</body>
</html>
예제 코드 설명
1. 데이터 준비
원형 차트 그리기를 위한 데이터를 준비한다. javascript의 표준 함수 Math.min을 사용하여 원형 차트의 반경을 설정한다.
var radius = Math.min(width, height) / 2 - 10;
2. SVG 영역 설정
원형 차트를 표시할 SVG 표시 영역을 설정한다. 원형 차트는 기본적으로 원점이 0,0 점으로 그려지므로 화면 중앙으로 이동한다.
var g = svg.append("g").attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
<g> 요소를 설정하고 그 안에 원형 차트의 SVG 요소를 설정한다.
3. 컬러 설정
원형 차트를 그리는 색상 스케일을 D3 메서드 d3.scaleOrdinal을 사용하여 설정한다.
var color = d3.scaleOrdinal()
.range(["#DC3912", "#3366CC", "#109618", "#FF9900", "#990099"]);
d3.scaleOrdinal은 range로 설정된 배열을 반복적으로 호출하는 함수를 설정한다. 이번에는 5가지 색의 색을 호출하는 함수를 color로 설정하여 사용한다.
4. pie 차트 dateset에 대한 함수 설정
제공된 데이터 dataset을 pie 차트의 데이터로 변환하는 함수를 D3의 메소드 d3.pie를 사용하여 설정한다.
var pie = d3.pie()
.value(function(d) { return d.value; })
.sort(null);
데이터 세트를 설정한 함수에 대입하면(pie(dataset)), 변환된 데이터가 출력된다.
.value로 각 원형 차트의 크기를 결정하는 값을 설정한다. .sort(null)로 순서를 재정렬하지 않는 설정을 하고 있다. .sort()는 선택 사항이며 생략하면 값이 큰 순서로 정렬된다.
변환 후의 데이터는 다음의 값이 설정된 객체의 배열이 된다.
| 값 | 설명 |
|---|---|
data |
원본 데이터에 대한 참조 |
value |
원형 차트 요소의 값 |
index |
원형 차트 요소의 인덱스(※ 정렬 후 정렬할 수 없음) |
startAngle |
호의 시작 각도 |
endAngle |
호의 끝 각도 |
padAngle |
요소 사이의 틈새 각도 |
5. pie 차트 SVG 요소 설정
설정한 함수 pie를 사용하여 데이터를 설정한다.
var pieGroup = g.selectAll(".pie")
.data(pie(dataset))
.enter()
.append("g")
.attr("class", "pie");
시작하기 전에 "g"요소를 설정하고, 그 안에 원형 차트의 팬("path" 요소)과 문자열("text" 요소)을 설정한다.
원형 차트의 팬 "path" 요소의 "d"속성을 설정하는 함수를 D3의 메소드 d3.arc()를 사용하여 설정한다.
arc = d3.arc()
.outerRadius(radius)
.innerRadius(0);
pieGroup.append("path")
.attr("d", arc)
.attr("fill", function(d) { return color(d.index) })
.attr("opacity", 0.75)
.attr("stroke", "white");
d3.arc()는 .outerRadius(..)에서 외부 반경을 .innerRadius(..)에서 내부 반경을 설정한다. 예를 들어 .innerRadius(..)에 0이 아닌 값을 설정한다.
arc = d3.arc()
.outerRadius(radius)
.innerRadius(85);
그러면, 아래와 같이 도넛 차트를 만들 수 있다.
6. pie 차트 텍스트 SVG 요소 설정
라벨의 텍스트를 설정한다.
var text = d3.arc()
.outerRadius(radius - 30)
.innerRadius(radius - 30);
pieGroup.append("text")
.attr("fill", "black")
.attr("transform", function(d) { return "translate(" + text.centroid(d) + ")"; })
.attr("dy", "5px")
.attr("font", "10px")
.attr("text-anchor", "middle")
.text(function(d) { return d.data.name; });
텍스트 배치를 위해 d3.arc()를 다시 호출하여 text에 메소드를 설정한다.
.centroid(..) 메서드에 pie 차트에 대해 변환된 데이터를 삽입하면 파이 차트의 반경 방향 중앙 위치에 텍스트를 설정할 수 있다.
부채의 .innerRadius(..)를 0으로 설정했기 때문에, 텍스트를 중앙보다 조금 바깥쪽에 표시하고 싶어 새롭게 메소드를 호출하고 있다.
앞에서 전의 도넛 차트의 경우는 중앙 위치에 텍스트를 배치하는 편이 보기 좋기 때문에, 텍스트를 표시하기 위해 d3.arc를 호출할 필요는 없고, text.centroid(d)의 부분을 arc.centroid(d)으로 하면 이전 예제과 같이 중앙에 배치할 수 있다.