D3의 Tutorial 중 가장 기본적인 BarChart 그리기를 정리한 것.
Tutorials
1. Bar차트 그리기
1. 요소 선택하기
- selector를 쿼리하여 element를 선택할 수 있음.(ex.
d3.select('div')
ord3.selectAll("section")
) .append()
,html()
등의 메소드를 이용하여 간단하게 element 편집 가능.
2. 메소드 체이닝
select()
를 통해 가져온 element를 method chaining을 이용하여 보다 편하게 여러 메소드를 걸 수 있음.d3.select("body") .style("color", "black") .style("background-color", "white");
- 체이닝은 document 계층에서 자식에게만 적용됨. 즉, 다른 자식을 생성했다면, 더 이상 해당 element에 체이닝 불가. -> 변수를 이용하여 원하는 reference를 관리.
3. 차트 그리기
class가 chart
인 div태그가 있다고 가정하자.
해당 요소 안에 d3를 이용하여 차트를 그리는 방법은 다음과 같다.
d3.select(".chart")
.selectAll("div")
.data(data)
.enter().append("div")
.style("width", function(d) { return d * 10 + "px"; })
.text(function(d) { return d; });
위의 코드를 순서대로 한 줄씩 풀어보면..
- selector를 이용하여 차트를 그릴 영역을 선택
var chart = d3.select(".chart");
- data join을 위한 selection을 정의
- div.chart 안에는 data가 담긴 div가 있을수도 없을수도 있음.
- d3에서 정의된 selection 객체를 반환하는데, 이 객체를 통해 데이터를 바인드하고, 데이터에 대응하는 객체를 다룰 수 있는 기능을 제공함.
var bar = chart.selectAll("div");
- Data join을 위해 정의한 영역에 data를 bind
- Data Join은 데이터의 변경에 따라 element를 만들고, 갱신하고, 삭제하는데에 있어서 많이 사용되는 패턴이다.
- 이러한 패턴을 따라 개발함으로써, 거의 동일한 코드를 가지고 각기 다른 데이터를 시각화할 수 있기 한다.
var barUpdate = bar.data(data);
- (현재) selection이 비어있기 때문에
update
나exit
메소드의 리턴(selection)도 비어있다. 그러므로 현재 비어있는 데이터를 다루는enter
메소드의 리턴인 selection들에 새로운 데이터를 넣기만 하면 된다.var barEnter = barUpdate.enter().append('div');
- 새로 생긴 div들의 selection인
barEnter
에 너비를 준다.barEnter.style("width", function(d){ return d*10 + "px"; });
- 위 과정을 통해 생성된 element들은(div) Data Join 을 통해 생성되었기 때문에 각각의 div들은 모두 data가 묶여있음.
- 이후에 각 div에 data 수치를 text로 넣어준다.
barEnter.text(function(d){ return d; });
4. 규모에 맞게 확장하기
위 코드의 한 가지 약점은 코드에 직접 들어간 숫자인 10이다.(4번의 return d*10
부분) 이렇게 되면, 10이라는 숫자에 의존적인 차트가 나오게 됨.
이것을 linear scale을 이용하여 의존성을 분리시킬 수 있음. D3의 스케일은 범위를 보여주기 위해 data space(domain)으로부터 정해진다.
var x = d3.scale.linear()
.domain([0, d3.max(data)])
.range([0,420]);
x를 분리하여 차트를 생성하는 그래프와, 스케일을 지정하는 코드를 분리하였다. 위 코드를 기존 코드에 적용시킨다면
d3.select(".chart")
.selectAll("div")
.data(data)
.enter().append("div")
.style("width", function(d) { return x(d) + "px"; })
.text(function(d) { return d; });
2. Bar Chart 그리기 II
1. SVG란?
Scalable Vector Graphics의 약자로 곡선이나 기울기, 꺾인선, 면 등을 표현할 수 있게한다.
2. 데이터 불러오기
tsv파일을 통해 데이터를 불러오려고 한다 가정해보자. 이 과정을 위해서는 파일을 웹 서버에서 다운받고, 파싱하여 JS의 object 형태로 바꾸는 과정이 필요하다.
d3.tsv
메소드를 이용하면 이러한 과정을 한 번에 수행 가능하다.
Data를 불러오는 과정은 다운로드의 비동기적 특성때문에 복잡해질 수 있다. d3.tsv
를 이용한다면, 백그라운드에서 파일을 즉시 다운로드하여 다운로드가 끝난 후 callback이 동작하는 형태로 작동된다.
// 1. 다운로드 전에 동작하는 코드
d3.tsv("data.tsv", function(error, data){
// 3. 다운로드가 된 후 동작할 코드
});
// 2. 다운로드 중에 동작할 코드
차트를 개발하는데에 있어서 두 단계로 나누어 개발하는 것이 좋다. 첫 번째 단계는, page가 로드되면서 데이터가 준비되기 전에 할 수 있는만큼 차트를 그릴 준비를 해야한다. 차트의 사이즈를 정한다거나, 변수를 초기화하는 작업 등을 미리 하여 차트를 그리기 전에 차트에 필요한 준비를 끝내는 것이다. 두 번째 단계는 데이터가 로드된 이후 callback 함수 안에 차트를 그리는 코드를 작성한다.
var width = 420,
barHeight = 20;
var x = d3.scale.linear()
.range([0, width]);
var chart = d3.select(".chart")
.attr("width", width);
d3.tsv("data.tsv", type, function(error, data) {
x.domain([0, d3.max(data, function(d) { return d.value; })]);
chart.attr("height", barHeight * data.length);
var bar = chart.selectAll("g")
.data(data)
.enter().append("g")
.attr("transform", function(d, i) { return "translate(0," + i * barHeight + ")"; });
bar.append("rect")
.attr("width", function(d) { return x(d.value); })
.attr("height", barHeight - 1);
bar.append("text")
.attr("x", function(d) { return x(d.value) - 3; })
.attr("y", barHeight / 2)
.attr("dy", ".35em")
.text(function(d) { return d.value; });
});
function type(d) {
d.value = +d.value; // coerce to number
return d;
}