[D3.js] Pie Chart 응용
[D3.js] Pie Chart 응용
- 참조 : [D3.js] pie() 함수
오늘은 D3.js 갤러리에 있는 차트 중 Pie Chart를 응용한 이미지가 있어서 한번 비슷하게 구현해보는 시간을 가져 봤습니다. 어떤 차트인지 한번 살펴 보고 실험을 해볼까요.
1. D3.js 갤러리에 있던 이미지
- 출처 : Aster Plot in D3 - http://bl.ocks.org/bbest/2de0e25d4840c68f2db1
Ben Best’s Block 2de0e25d4840c68f2db1
Updated October 4, 2017
위 출처에 가시면 대충 이런 이미지가 있습니다. 이런 차트는 갤러리 예제를 보면 몇가지 종류로 만들어서 오픈 소스로 공개 되어 있는데 우선 이미지만 보고 연상을 해보고 비슷하게 구현해 보도록 하겠습니다.
출처에 가시면 위 이미지처럼 차트가 만들어지는데 pie Chart가 어떻게 하면 위처럼 보여질까요. 아주 간단합니다.
기존의 Pie Chart의 경우는 다음과 같습니다.
이 형태는 기본적으로 다음과 같은 코딩이 이루어집니다.
var arc = d3.arc()
.innerRadius(100)
.outerRadius(240)
이 형태로 해서 각 데이터가 안쪽원 100과 바깥쪽원 240으로 해서 각 데이터별 파이가 그려집니다. 여기서, 어떤 부분을 수정할까요. outerRadius()함수 안에 240 값을 데이터별로 크기를 조절하면 바로 갤러리에서 찾은 오늘 실험할 pie Chart를 표현할 수 있게 됩니다.
자, 그럼 실험을 해볼까요.
2. 실험
- 참조 : [D3.js] pie() 함수
예전에 실험함 pie() 함수 post에 있던 소스를 복습 차원으로 그대로 사용합니다.
[기본소스]
<body>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script>
var data = [10, 20, 30, 40, 50];
var arcs = d3.pie()(data);
var width = 500;
var height = 500
var arc = d3.arc()
.innerRadius(100)
.outerRadius(240)
.cornerRadius(10)
var svg = d3.select("body").append("svg")
.attr("width",width)
.attr("height",height)
.style("background-color","yellow");
g = svg.append("g")
.attr("transform", "translate(" + width / 2 + "," + height/ 2 +")")
var pie = g.selectAll("path")
.data(arcs)
.enter()
.append("path")
.style("fill", function(d,i){
return d3.color("hsl(100, 100%, " + d.value + "%)");
})
.attr("d", arc)
</script>
</body>
[결과]
여기서, outerRadius(240) 함수가 핵심이라고 했죠.
var arc = d3.arc()
.innerRadius(100)
.outerRadius(240)
위 코딩부분만 수정하면 됩니다.
.innerRadius(50)
.outerRadius(?)
데이터는 그대로 사용하면
var data = [10, 20, 30, 40, 50];
5개의 데이터를 바깥원 원의 스케일로 맞출려고 합니다. scaleLinear()함수로 자동으로 스케일을 맞췄습니다.
var scale_outerRadius = d3.scaleLinear().domain([0, d3.max(data)]) //y = mx + b
.range([50, 200])
범위는 안쪽원 50으로 우선 잡았으니깐 바깥쪽원의 최대 크기를 200으로 잡아 range범위를 우선 정했고 입력 데이터의 domain은 0에서 d3.max()함수로 데이터의 가장큰수로 해서 범위를 지정했네요. 즉, 0~50사이의 입력 데이터 값을 50~200사이의 출력데이터로 나오도록 outerRadius 스케일값으로 만들어 놓았습니다.
var arc = d3.arc()
.innerRadius(50)
.outerRadius(function (d) {return scale_outerRadius(d.value);})
위와 같이 outerRadious()함수 내부의 데이터 별 스케일을 지정하면 끝납니다.
[수정소스]
<body>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script>
var data = [10, 20, 30, 40, 50];
var arcs = d3.pie()(data);
var width = 500;
var height = 500
var scale_outerRadius = d3.scaleLinear().domain([0, d3.max(data)]) //y = mx + b
.range([50, 200])
var arc = d3.arc()
.innerRadius(50)
.outerRadius(function (d) { return scale_outerRadius(d.value);})
var svg = d3.select("body").append("svg")
.attr("width",width)
.attr("height",height)
.style("background-color","yellow");
g = svg.append("g")
.attr("transform", "translate(" + width / 2 + "," + height/ 2 +")")
var pie = g.selectAll("path")
.data(arcs)
.enter()
.append("path")
.style("fill", function(d,i){
return d3.color("hsl(100, 100%, " + d.value + "%)");
})
.attr("d", arc)
</script>
</body>
[결과]
마무리
어렵지 않게 표현이 되죠. outerRadius()함수 안에 데이터 별 크기값만 지정해주면 이렇게 멋진 차트가 만들어지네요. 만들어 놓고 한번 실험을 한 원본 소스는 어떻게 되어 있는지 봤는데 전 스케일 함수를 이용하여 크기를 지정했는데 원본 소스는 자체적으로 일일히 캔버스 크기와 내부원과 다 감안해서 계산하여 크기를 만들어 내더군요. 아무튼 재밌는 차트 하나를 실험해 보았습니다.
짱짱맨 호출에 응답하여 보팅하였습니다. 짱짱맨의 보팅현황은 보팅 자동화 서비스 스티머를 통해서 투명하게 공개됩니다.
짱짱맨 방문에 감사 합니다.
전 일차적인 눈으로먼 보이네요 ㅡ ㅡ
점점 차트가 화려 해진다.
그림쟝이의 한계일까요? 에공
화려하게 차트를 만들고 싶지만 아직 기초적인 거라서 갈길이 머네요.