D3.js 면 그래프(area chart) 만드는 방법

D3에서 기본 차트의 면 그래프를 만드는 방법을 소개한다.

예제 프로그램

코드 확인

예제 코드

<!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" 속성을 만드는 함수이다.

마무리

막대 그래프산포도도 같은 알고리즘으로 만들 수 있다. 참조하길 바란다.




최종 수정 : 2024-01-18