D3.js selection을 알아보자

sun202x·2022년 9월 30일
0

D3.js

목록 보기
2/4
post-thumbnail

D3.js를 사용하기 위한 예제를 작성하면서 아무래도 selection의 기본적인 개념을 정리해보는게 좋을 것 같다는 생각이 들었다. D3.js는 기본적으로 함수형 프로그래밍 기반으로 만들어졌으며, 이러한 특징들은 selection을 통해서도 나타나는 것을 확인할 수 있다.

d3.select('body')
  .append('div')
  .html('Hello world!');

앞선 게시글에서 해당 코드를 통해 body 태그에 div 태그를 추가할 수 있었다. 각 함수들의 인터페이스를 살펴보면 현재 내가 하고자 하는 일에만 집중할 수 있는 것을 알 수 있다. select 함수 내부에서 어떤 일이 벌어지든 사용자는 선택하고자 하는 body만 명시하면 된다. 이러한 점은 함수형 프로그래밍의 특징으로 볼 수 있다.

선택(selection)

D3.js는 선택을 통해 시각화 작업을 시작할 수 있다. 표준 W3C CSS 선택자jQuery에 익숙하다면 D3.js의 선택을 이용하는데 큰 불편함은 없을 것이다. 표준 W3C CSS 선택자 API는 선택이 아닌 선택자를 제공하기 때문에 다중 요소를 처리함에 있어서 번거로움이 있을 수 있다. 그러나 D3.js에서는 선택 API를 제공하기 때문에 다중 요소에 대한 처리도 간단하게 처리할 수 있다.

// 표준 W3C CSS 선택자
const i = document.querySelectorAll('p').iterator();
let e;

while(e = i.next()) {
  // 선택된 각 요소 처리를 한다.
  console.log(e);
}

// D3.js
d3.selectAll('p')
  .each(function (d, i) {
    // 선택된 각 요소 처리를 한다.
  	console.log(this)
  });

단일 요소 선택

아래 코드는 CSS 선택자를 통해 단일 요소를 선택하고 'hello world'를 출력한다.

<p id="target"></p>
d3.select('p#target')
  .text('hello world');

위 코드 처럼 select 함수는 D3.js에서 단일 요소를 선택하기 위해 사용된다. 해당 함수는 HTML을 조작하는 수정자 함수를 연결할 수 있는 D3 선택 객체를 반환한다.

📝 D3 선택 객체는 몇가지 수정자 함수를 제공하는데 기본적인 것들을 살펴보자

  • selection.attr: 주어진 속성을 조작할 수 있게 하는 함수
  • selection.classed: CSS 클래스 요소를 조작할 수 있는 함수
  • seection.style: CSS 스타일을 조작할 수 있는 함수
  • selection.text: 텍스트 내용을 조작할 수 있는 함수
  • selection.html: 내부 HTML을 조작할 수 있는 함수

이러한 수정자 함수들은 단일 선택 요소, 다중 선택 요소 모두 적용 가능하다.

다중 요소 선택

여러 요소를 처리 하기 위해서는 단일 요소 선택만으로는 부족할 때가 있다. D3.js는 다중 요소를 처리하기 위한 함수도 제공한다.

<div>1</div>
<div>2</div>
<div>3</div>
d3.selectAll('div')
  .attr('class', 'red box');

selectAll 함수를 사용하여 위와 같이 간단하게 다중 요소에 class를 적용할 수 있다.

선택 반복

선택한 다중 요소들을 순회하면서 필요한 요소들을 처리해야 하는 상황들이 종종 있다. D3.js는 선택 반복 API를 제공하여 개별 요소를 처리할 수 있게 해준다.

d3.selectAll('div')
  .attr('class', 'red box');
  .each(function(d, i) {
    // select 함수는 단일 선택 요소를 반환한다.
    d3.select(this).append('h1');
  });

부분 선택 수행

작업을 처리할 때 전체 범위를 처리하기 보다 특정 범위를 지정하여 선택하는 것이 편할 때가 있다. CSS 선택자를 사용한 부분 선택과 D3.jsselect 함수를 사용한 부분 선택을 확인해보자.

// CSS 선택자 사용
d3.select('#section1 > div')
  .attr('class', 'blue box');
// select 함수의 이중 사용
d3.select('#section1')
  .select('div')
  .attr('class', 'blue box');

위 두 가지 코드 모두 동일하게 동작한다. 차이점은 select 함수를 이중으로 사용하게 되면 선택 요소에 좀 더 유연한 처리를 할 수 있다. 아래 코드는 #section1 요소에 class를 적용한 코드이다.

// select 함수의 이중 사용
d3.select('#section1')
    .attr('class', 'red border')
  .select('div')
    .attr('class', 'blue box');

CSS 선택자를 사용하면 중간 요소의 처리가 어렵지만, select 함수를 사용하면 중간 요소의 처리도 쉽게 할 수 있는 것을 확인할 수 있다.

원시 DOM 요소 선택

개발 과정에서 D3 선택 요소를 제외한 원시 DOM 요소에 접근할 일이 생길 때가 있다. 아래 코드를 통해서 원시 DOM 요소에 접근하기 위한 방법을 확인 할 수 있다.

const rows = d3.selectAll('tr');
const headerElement = rows[0][0];

d3.select(headerElement).attr('class', 'table-header');

d3.select(rows[0][1]).attr('class', 'table-row-odd');
d3.select(rows[0][2]).attr('class', 'table-row-even');
d3.select(rows[0][3]).attr('class', 'table-row-odd');

위 코드는 효율적이지 못하지만 원시 DOM 요소에 접근하기 위한 예제로 작성되었다. 해당 코드는 each 함수로 작성되는 것이 더 효율적이다. D3.js를 사용하면서 원시 DOM 요소를 접근할 일이 거의 없지만 필요한 경우에는 이런 식으로 접근이 가능하다.

정리

D3.js를 사용하여 시각화 작업을 처리하기 위한 첫번째 단계로 selection이 사용되는데, 해당 내용을 통해 기본적인 selection의 내용을 정리해 보았다.

📝 해당 게시글의 내용은 다양한 레시피로 보는 D3.js 쿡북 책을 참조하여 정리했습니다. 보다 디테일하고 정확한 내용을 참조하고 싶다면 해당 책을 읽어보시기 바랍니다.

Reference

다양한 레시피로 보는 D3.js 쿡북

profile
긍정적으로 살고 싶은 개발자

0개의 댓글