D3.js 막대 그래프(bar chart)
예제 프로그램
간단한 막대 그래프를 만든다.
예제 코드
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>D3 bar chart basic</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 padding = 30; // 스케일 표시용 여백
// 2. SVG 영역 설정
var svg = d3.select("body").append("svg").attr("width", width).attr("height", height);
// 3. 축 스케일(눈금) 설정
var xScale = d3.scaleBand()
.rangeRound([padding, width - padding])
.padding(0.1)
.domain(dataset.map(function (d) { return d.name; }));
var yScale = d3.scaleLinear()
.domain([0, d3.max(dataset, function (d) { return d.value; })])
.range([height - padding, padding]);
// 4. 축 표시
svg.append("g")
.attr("transform", "translate(" + 0 + "," + (height - padding) + ")")
.call(d3.axisBottom(xScale));
svg.append("g")
.attr("transform", "translate(" + padding + "," + 0 + ")")
.call(d3.axisLeft(yScale));
// 5. 막대 표시
svg.append("g")
.selectAll("rect")
.data(dataset)
.enter()
.append("rect")
.attr("x", function (d) { return xScale(d.name); })
.attr("y", function (d) { return yScale(d.value); })
.attr("width", xScale.bandwidth())
.attr("height", function (d) { return height - padding - yScale(d.value); })
.attr("fill", "steelblue");
</script>
</body>
</html>
코드 설정
1. 데이터 준비
축을 표시하는 폭을 확보하기 위해 padding
을 변수로 생성한다. 상하좌우에 padding
으로 설정한 폭의 여백을 설정한다.
2. SVG 영역 설정
body
안에 svg
태그를 설정하여 그릴 영역을 준비한다.
3. 축 스케일(눈금) 설정
축의 너비를 화면의 너비에 맞추는 스케일 변환과 축 표시를 위한 함수를 준비한다.
x
축은 D3의 함수 d3.scaleBand()
를 사용하여 설정한다.
var xScale = d3.scaleBand()
.rangeRound([padding, width - padding])
.padding(0.1)
.domain(dataset.map(function(d) { return d.name; }));
먼저, .rangeRound(..)
함수로 스케일 표시 범위를 반올림으로 설정한다.
.rangeRound([padding, width - padding])
여기서는 그래프 양 끝에 padding
만큼의 간격을 두기 때문에 x
축을 padding
~ width-padding
의 범위로 설정한다.
.padding(..)
에서 막대 그래프의 막대와 막대 사이의 간격을 0.0 ~ 1.0의 비율로 설정합니다.
.padding(0.1)
.domain(..)
의 부분에서 가로축의 레이블(name
)과 수를 설정한다.
.domain(dataset.map(function(d) { return d.name; }));
인수를 ma
p으로 변환하여 설정한다. 여기에 설정된 레이블의 문자열은 x
축에 표시된다.
y축은 D3의 함수 d3.scaleLinear()
를 사용하여 설정한다.
var yScale = d3.scaleLinear()
.domain([0, d3.max(dataset, function(d) { return d.value; })])
.range([height - padding, padding]);
d3.scaleLinear()
는 domain(..)
으로 설정한 스케일을 range
로 설정한 스케일로 등배로 변환하는 함수이다. domain
에 그래프 내 좌표값으로 0부터 숫자(value
)의 최대값(d3.max(...)
로 가져옴)를 설정하고, range
에 표시상의 거리를 고려하여 범위를 한다. padding
을 고려한 범위를 설정한다. y
축은 화면 아래로 갈수록 값이 커지므로, y=0
에 화면 하측의 큰 값(height - padding
)을 설정한다.
4. 축 표시
x
, y
축을 설정한다.
svg.append("g")
.attr("transform", "translate(" + 0 + "," + (height - padding) + ")")
.call(d3.axisBottom(xScale));
svg.append("g")
.attr("transform", "translate(" + padding + "," + 0 + ")")
.call(d3.axisLeft(yScale));
x
축은 그래프의 높이만큼, y
축은 x
축의 표시 여백만큼 띄워서 설정한다.
d3.axisBottom(xScale)
d3.axisLeft(yScale)
위에 함수는 축의 svg
요소 표시용의 함수로, call(..)
로 호출하면 svg
요소의 line
등을 사용해 축의 각도를 표시한다.
5. 막대 표시
svg.append("g")
.selectAll("rect")
.data(dataset)
.enter()
.append("rect")
.attr("x", function(d) { return xScale(d.name); })
.attr("y", function(d) { return yScale(d.value); })
.attr("width", xScale.bandwidth())
.attr("height", function(d) { return height - padding - yScale(d.value); })
.attr("fill", "steelblue");
막대를 표시한다. xScale
에는 d3.scaleBand()
로 호출한 함수가 설정되어 있지만, map
한 축 라벨(d.name
)을 인수로 하면 각 좌표를 호출할 수 있게 되어 있다. 그리고, .bandwidth()
로 설정한 padding()
을 고려한 폭을 가져온다. "rect"
는 위에서 오른쪽 아래로 사각형을 표시하므로 "y"
속성이 막대의 위쪽 좌표가 된다.