D3.js 면 그래프(area chart) 만드는 방법
예제 프로그램
예제 코드
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>D3 Area Chart</title>
<script src="https://d3js.org/d3.v7.min.js"></script>
</head>
<body>
<script>
// 1. 데이터 준비
var dataset = [
[1, 15],
[5, 25],
[25, 30],
[85, 40],
[100, 42],
[220, 40],
[250, 50],
[330, 95],
[410, 30],
[475, 44],
[480, 50]
];
var width = 400; // 그래프 넓이
var height = 300; // 그래프 높이
var margin = { "top": 30, "bottom": 60, "right": 30, "left": 60 };
// 2. SVG 영역 설정
var svg = d3.select("body").append("svg").attr("width", width).attr("height", height);
// 3. 축 스케일(눈금) 설정
var xScale = d3.scaleLinear()
.domain([0, d3.max(dataset, function (d) { return d[0]; })])
.range([margin.left, width - margin.right]);
var yScale = d3.scaleLinear()
.domain([0, d3.max(dataset, function (d) { return d[1]; })])
.range([height - margin.bottom, margin.top]);
// 4. 축 표시
var axisx = d3.axisBottom(xScale).ticks(5);
var axisy = d3.axisLeft(yScale).ticks(5);
svg.append("g")
.attr("transform", "translate(" + 0 + "," + (height - margin.bottom) + ")")
.call(axisx)
.append("text")
.attr("fill", "black")
.attr("x", (width - margin.left - margin.right) / 2 + margin.left)
.attr("y", 35)
.attr("text-anchor", "middle")
.attr("font-size", "10pt")
.attr("font-weight", "bold")
.text("X Label");
svg.append("g")
.attr("transform", "translate(" + margin.left + "," + 0 + ")")
.call(axisy)
.append("text")
.attr("fill", "black")
.attr("text-anchor", "middle")
.attr("x", -(height - margin.top - margin.bottom) / 2 - margin.top)
.attr("y", -35)
.attr("transform", "rotate(-90)")
.attr("font-weight", "bold")
.attr("font-size", "10pt")
.text("Y Label");
// 5. 영역(area) 표시
svg.append("path")
.datum(dataset)
.attr("fill", "rgba(70, 130, 180, 0.3)")
.attr("d", d3.area()
.x(function (d) { return xScale(d[0]); })
.y1(function (d) { return yScale(d[1]); })
.y0(yScale(0))
);
svg.append("path")
.datum(dataset)
.attr("fill", "none")
.attr("stroke", "steelblue")
.attr("stroke-width", 1.5)
.attr("d", d3.line()
.x(function (d) { return xScale(d[0]); })
.y(function (d) { return yScale(d[1]); })
);
</script>
</body>
</html>
예제 코드 설명
여기에 산포도를 대상으로 그래프를 만드는 방법의 튜토리얼을, 여기에 꺾은 선 그래프를 만드는 방법을 올리고 있다. 면 그래프는 꺾은선형 차트에서 약간의 변경으로 만들 수 있다.
1. 데이터 준비
여백을 설정하기 위해 객체를 준비합니다.
var margin = { "top": 30, "bottom": 60, "right": 30, "left": 60 };
축을 표시하기 위해 하단과 왼쪽 마진을 크게 설정한다.
2. SVG 영역 설정
SVG의 표시 영역을 설정한다.
3. 축 스케일 설정
축 스케일을 설정한다.
d3.scaleLinear()
위 코드에서 domain
으로 설정한 범위를 range
로 설정한 범위로 변환하는 함수를 설정한다. 선 그래프의 좌표를 화면의 픽셀 값으로 변환하는 함수를 만든다.
4. 축 표시
D3의 함수 d3.axisBottom()
과 d3.axisLeft()
를 사용하여 축 요소를 설정한다. 인수를 축 스케일의 설정으로 설정한 함수로 하여, call
로 호출하는 것으로 SVG 요소가 자동적으로 추가된다.
var axisx = d3.axisBottom(xScale).ticks(5);
var axisy = d3.axisLeft(yScale).ticks(5);
svg.append("g")
.attr("transform", "translate(" + 0 + "," + (height - margin.bottom) + ")")
.call(axisx)
svg.append("g")
.attr("transform", "translate(" + margin.left + "," + 0 + ")")
.call(axisy)
.ticks()
는 축 메모리의 수를 제어하는 메소드입니다. 정수로 설정한다.
축을 호출하고, text
요소로 축 레이블을 추가한다.
.append("text")
.attr("fill", "black")
.attr("x", (width - margin.left - margin.right) / 2 + margin.left)
.attr("y", 35)
.attr("text-anchor", "middle")
.attr("font-size", "10pt")
.attr("font-weight", "bold")
.text("X Label");
.append("text")
.attr("fill", "black")
.attr("x", -(height - margin.top - margin.bottom) / 2 - margin.top)
.attr("y", -35)
.attr("transform", "rotate(-90)")
.attr("text-anchor", "middle")
.attr("font-weight", "bold")
.attr("font-size", "10pt")
.text("Y Label");
"text-anchor"
는 텍스트의 위치 맞춤을 위한 속성으로, "middle"
로 중앙 정렬을 설정하고 있다. 각각 축에 쓰이지 않도록 35px
씩 이동하고 있다.
5. 면 영역 표시
면 그래프를 "path"
요소로 표시한다. 여기가 선 그래프와 다른 부분이다.
svg.append("path")
.datum(dataset)
.attr("fill", "rgba(70, 130, 180, 0.3)")
.attr("d", d3.area()
.x(function(d) { return xScale(d[0]); })
.y1(function(d) { return yScale(d[1]); })
.y0(yScale(0))
);
svg.append("path")
.datum(dataset)
.attr("fill", "none")
.attr("stroke", "steelblue")
.attr("stroke-width", 1.5)
.attr("d", d3.line()
.x(function(d) { return xScale(d[0]); })
.y(function(d) { return yScale(d[1]); })
);
데이터 바인딩는 아래와 같이 datum
를 사용하고 있다.
.datum(dataset)
하나의 데이터를 바인드하는 data
와 달리 "path"
에 데이터 세트를 통째로 추가한다. 또, 색의 지정시에 "rgba(70, 130, 180, 0.3)"
를 이용하고 있다. R
, G
, B
값을 0~255
로, α
값(투명도)을 0~1
.0
으로 설정한다. "opacity"
속성에서도 투명도를 설정할 수 있지만, "fill"
속성과 "storke"
속성의 투명도를 따로따로 바꾸고 싶을 때에 rgba
를 사용한다. 여기서는 "storke"
속성을 설정하지 않으므로 어느 쪽이든 상관 없다.
면 영역을 그릴 때 path
의 "d"
속성을 다음 D3의 메소드를 사용하여 설정한다.
d3.area()
.x(function(d) { return xScale(d[0]); })
.y1(function(d) { return yScale(d[1]); })
.y0(yScale(0))
.x()
에 x
좌표를 지정하는 함수를, y0
에 하측 (이번은 y=0) 의 y 좌표를, y1 에 상측의 y 좌표를 설정한다.
두 번째 "path"
는 꺾은 선형 차트와 마찬가지로 경계선을 설정한다. 필요하지 않은 경우 제외한다.
d3.line()
.x(function(d) { return xScale(d[0]); })
.y(function(d) { return yScale(d[1]); })
위 코드는 경계용 "path"
의 "d"
속성을 만드는 함수이다.
마무리
막대 그래프와 산포도도 같은 알고리즘으로 만들 수 있다. 참조하길 바란다.