d3js datagram20160505

74
어린이날 특집 데이터그램 라이브 스터디 20160505 HANNAH SONG D3 기초 따라잡기

Upload: young-sook-song

Post on 13-Feb-2017

167 views

Category:

Data & Analytics


6 download

TRANSCRIPT

Page 1: D3js datagram20160505

어린이날 특집 데이터그램 라이브 스터디

20160505 HANNAH SONG

D3 기초 따라잡기

Page 2: D3js datagram20160505

D3.js Basic DataGram

오늘 다룰 내용

1. D3 설치하기 + 웹서버 설정하기

2. D3 대략 살펴보기

2.1 D3의 기본 구성

2.2 SVG 속성 변경

3. D3 자세히 들여다보기

3.1 문서 요소의 선택과 추가 : selection

3.2 데이터 결합하기: data binding

3.3 데이터 들어가기와 나가기: enter()와 exit()

3.4 축과 척도 : axis와 scale

3.5 동적인 시각화를 위한 트랜지션 메서드 : transition()

4. D3 레이아웃 알아보기

5. 참고 도서

2

Page 3: D3js datagram20160505

D3.js Basic DataGram

D3 설치하기 + 웹서버 설정하기

1.

Page 4: D3js datagram20160505

DATAGRAM | D3.JS IN ACTION

1. D3.js : Data-Driven Documents

4

마이크 보스톡(Mike Bostock)

https://d3js.org/

https://bost.ocks.org/ http://bl.ocks.org/mbostock

Page 5: D3js datagram20160505

D3.js Basic DataGram

2. D3 설치하기(1) : 파일

5

프로젝트 폴더를 생성하고 D3.js파일을 같은 폴더 안에 넣는다. D3폴더를 따로 만들 경우 경로명을 적어주어야한다.

D3.zip'다운로드'

방법'1:''d3.js'파일'이용'

다운받은'D3.zip'파일의'압축을'풀어'보면,'d3.js와'd3.min.js'두'개의'파일이'있다.''(일반적으로'프로젝트를'진행할'때는'디버깅이'쉬운'일반'버전을'사용하고,'프로젝트가'완료된'후'로딩'시간을'줄이기'위해서'최소화'버전으로'변경한다.)'

Page 6: D3js datagram20160505

D3.js Basic DataGram

2. D3 설치하기(2) : 링크

6

방법'2':''링크로'연결'

!  항상'최신'버전을'사용하기'위해서는'HTML'파일'안에'아래의'태그를'삽입하여'사용한다.''''''''<script'src="//d3js.org/d3.v3.min.js"></script>'

Page 7: D3js datagram20160505

D3.js Basic DataGram

3. 웹 서버 설정하기

1.  웹 서버 설정하기 : 웹 브라우저는 보안상의 이유로 자바스크립트에서 로컬 파일을 불러오는 일을 금지하기

때문에 D3가 외부 데이터 파일(CSV나 JSON)을 불러오려고 시도하면 실패하게 된다.

이것은 D3의 문제가 아닌 브라우저의 보안기능 때문이므로 웹 서버를 설정한다.

2. 웹 서버 설정 방법(MAC)

(1) 터미널 창을 연다.

(2) 커맨드 라인에서 프로젝트 폴더로 이동한다.

cd ~/Desktop/project-folder

(3) 서버를 실행한다. (맨 끝의 숫자는 서버가 8888 포트에서 동작한다는 뜻이다.)

python –m SimpleHTTPServer 8888 &

(4) 브라우저로 돌아와서 http://localhost:8888/에 접속한다.

이제 브라우저는 로컬 컴퓨터를 사용해서 페이지를 요청한다.

※Localhost란 컴퓨터 내부 서버를 이용해 실제 인터넷 접속 조건과 동일하게 내부 컨텐츠를 보여주는 것.

7

Page 8: D3js datagram20160505

D3.js Basic DataGram

D3 대략 살펴보기

2.

Page 9: D3js datagram20160505

D3.js Basic DataGram

D3 의 기본 구성

2.1

Page 10: D3js datagram20160505

DATAGRAM | D3.JS IN ACTION

1. 파일 구조 : html, css, javascript + D3

10

html

css

javascript

d3 code

d3.js src

Page 11: D3js datagram20160505

D3.js Basic DataGram

2. html, css, js 코드를 연결하는 두 가지 방법

11

<html>

<head>

<style>

body {background-color:lightgrey}

h1 {color:blue}

</style>

</head>

<body>

<h1> hello </h1>

<p id = "demo" style="color:blue">

a paragraph </p>

</body>

<script>

function myFunction() {

document.getElementByID("demo").innerHTML

= "Paragraph changed";

}

</script>

<html>

index.html

방법 1. html 파일 내부에 모두 쓰기 방법 2. html 파일 외부에 css, js 파일을 분리하기

<html>

<head>

<link rel = “stylesheet” href = “myStylescss”>

</head>

<body>

<h1> hello </h1>

<p id=“demo”> test </p>

</body>

<script src = “myScript.js” type = “text/JavaScript”></script>

<html>

inline

tag

index.html

myStyle.css

myScript.js

external file

external file

tag

Page 12: D3js datagram20160505

D3.js Basic DataGram

3. HTML과 DOM

12

Model D O M

Object Document

“D3 allows you to bind arbitrary data to a Document Object Model (DOM), and then apply data-driven transformations to the document. For example, you can use D3 to generate an HTML table from an array of numbers. Or, use the same data to create an interactive SVG bar chart with smooth transitions and interaction.”

D3(Data-Driven Document) 소개 페이지의 첫 문장

DOM은 HTML과 XML 문서에 대하여, 문서의 구조적인 표현방법을 제공함으로써 스크립트를 이용하여 구조에 접근하는 방법을 정의한 API이다.

HTML 페이지를 트리(Tree) 형태의 모델로 저장하는데, DOM Tree에 존재하는 노드(node)는 요소(element), 속성(attribute), 텍스트(text), HTML문서 전체(document) 등으로 구성된다.

Page 13: D3js datagram20160505

DATAGRAM | D3.JS IN ACTION

4. D3의 동작 방식

13

D3는 다음 순서대로 동작한다.

•  Loading : 브라우저 메모리로 데이터를 불러온다. •  Selecting – Binding : 필요한 HTML 문서요소를 새로 만들어서 데이터를 엮는다. •  Transform : 각 문서요소에 엮인 개별 데이터를 토대로 해당 문서요소를 변환시킨다. •  Transition : 사용자 입력에 반응하여 문서요소의 상태를 한 값에서 다른 값으로 전이시킨다.

Page 14: D3js datagram20160505

D3.js Basic DataGram

5. D3 코드의 기본 형태

d3.select(“body”).selectAll(“p”)

.data(dataset)

.enter()

.append(“p”)

. text( function(d) { return d; ));

14

// data() 메서드는 데이터 값이 몇 개인지 계산하고 파싱한다. Dataset변수에서 불러온 배열의 값이 5개이면, 다음 체인으로 연결된 모든 내용은 값마다 한번씩 모두 5번 실행된다.

// 가장 가까운 DOM 선택물에 데이터 집합의 값을 d로 할당하며, 메서드 체인으로 연결되어 있을 때 d를 받는 익명 함수를 만들 수 있다.

// 조건과 일치하는 첫번째 DOM 문서요소의 참조를 반환한다.

// DOM에서 body를 찾고, p 문서요소를 모두 선택한다.

// 그런데 p 문서요소는 아직 DOM에 존재하지 않기 때문에 빈 선택물을 반환한다.

// 관련 DOM 문서요소보다 데이터 값이 많으면 enter() 메서드는 플레이스 홀더 역할을 할 문서요소를 생성한다

// 전달인자로 받은 DOM 문서요소를 새로 생성해서, 앞 체인에서 선택한 문서요소의 끝(안쪽)에 추가한다.

// append() 메서드는 enter()가 생성한 빈 플레이스 홀더 선택물을 가져와서 DOM에 p 문서요소를 추가하고, 다음 메서드를 위해 생성된 문서요소의 참조값을 넘긴다.

Data 1

Data2

Data3

Data4

Data5

DOM element

<p>

<p>Data 1</p> <p>Data 2</p> <p>Data 3</p> <p>Data 4</p> <p>Data 5</p>

<p>

<p>

<p>

<p>

<p>

Page 15: D3js datagram20160505

D3.js Basic DataGram

SVG 속성 변경

2.2.

Page 16: D3js datagram20160505

D3.js Basic DataGram

1. SVG

16

SVG(Scalable Vector Graphics) (1) 웹상에서 2차원 그래픽을 다루기 위한 XML 형식의 사양. (2) HTML에 독립적이지만 HTML5에서는 SVG를 포함하므로 HTML 안에 SVG를 내장 콘텐츠로 표시할 수 있다. (3) SVG는 이름 그대로 벡터 형식의 확장 가능한 그래픽 요소를 이용하므로 확대 및 축소, 회전 등의 변형 시 이미지 품질이 떨어지지 않는다. (4) 또한 DOM과 똑같이 요소로서 취급하므로 웹에서 SVG 요소가 잘 표시되지 않을 때 디버그하기 쉽다는 장점도 있다.

SVG에서 이용할 수 있는 요소

속성 설명

도형 요소(shape element) circle(원), ellipse(타원), line(직선), polyline(연결선), rect(사각형)

패스 요소(path element) 곡선을 포함하는 복잡한 형태를 그림

텍스트 요소(text element) 텍스트를 삽입

콘테이너 요소(container element) 제어 및 그룹화하는 요소 – a(링크), g(그룹) 등

Page 17: D3js datagram20160505

D3.js Basic DataGram

1. SVG(1) : shape element

17

속성 설명

x 좌단 x좌표

y 상단 y좌표

with 사각형의 폭

height 사각형의 높이

rx 둥근 모서리의 x의 반지름

ry 둥근 모서리의 y의 반지름

rect

속성 설명

cx 원 중심의 x좌표

cy 원 중심의 y좌표

r 원의 반지름

circle

속성 설명

cx 원 중심의 x좌표

cy 원 중심의 y좌표

rx x축 반지름

ry Y축 반지름

ellipse

Page 18: D3js datagram20160505

D3.js Basic DataGram

1. SVG(1) : shape element

18

속성 설명

x1 선분 시작 위치의 x좌표

x2 선분 종료 위치의 x좌표

y1 선분 시작 위치의 y좌표

y2 선분 종료 위치의 y좌표

line

속성 설명

points 선분이 연결할 점의 위치를 “x좌표, y좌표”를 공백으로 구분하여 지정 (열린 선분으로 다각 선분을 작성)

예) Points = “0,0 10,0 10,10 20,10 20,20”

polyline

polygon

속성 설명

points 선분이 연결할 점의 위치를 “x좌표, y좌표”를 공백으로 구분하여 지정 (닫힌 선분으로 다각형을 작성)

예) Points = “0,0 10,0 10,10 20,10 20,20”

Page 19: D3js datagram20160505

D3.js Basic DataGram

1. SVG(2) : path element

19

속성 설명 비고

d

시작 위치에서 시작되어, 다음 점으로 가는 직선, 다음 점으로 가는 큐직 베지어 곡선, 다음 점으로 가는 쿼드라틱 베지어 곡선, 다음 점으로 가는 타원호 계열로 직선과 곡선을 그어가다가 종단처리(패스를 닫을지 말지 결정)로 끝난다.

꺾은선 그래프나 원 그래프를 그리는 데에 중요한 요소이다.

예)

<svg width=“100” height=“100”> <path d=“ M 10 25 L 10 75 L 60 75 L 10 25 fill=“none” stroke=“red” /> </svg>

path 요소

그래픽 요소가 각 속성을 지정하는 것만으로 각각의 도형을 그릴 수 있는 반면, path요소는 그 윤곽을 연결하는 점, 곡률 등을 개별적으로 지정하여 도형을 그릴 수 있다. 그런 의미에서 그래픽 요소는 개개의 형상을 그리기 위한 path 요소의 사례로 생각하면 된다.

M 10 25

L 10 75 L 60 75

L 10 75

Page 20: D3js datagram20160505

D3.js Basic DataGram

1. SVG(3) : g element

20

g 요소 : 그룹화를 하는 요소로서, 직접 도형을 그리는 요소는 아니지만 그래픽 요소와 텍스트 요소를 한꺼번에 다루기 위한 중요한 요소이다. 예를 들면, 노드를 circle로 작성하고 그 옆에 text 요소로 노드 이름을 기재할 때 <g><circle/><text>circle name</text></g> 와 같은 형식으로 이용하여 그룹화한다. 이처럼 g 요소를 이용하면 도형과 라벨의 이동과 회전, 확대 축소 같은 처리를 따로 하지 않고 모아서 할 수 있게 된다.

circle name

<g>

circle name

<g>

transform

축소 회전

Page 21: D3js datagram20160505

D3.js Basic DataGram

2. SVG 속성 변경(1) : 공통 그래픽 속성

21

자주 이용되는 그래픽 요소 공통 속성

속성 설명 비고

fill 칠할 색, 투명도를 지정한다. none을 지정하면 색을 칠하지 않는다.

stroke 선, 윤곽의 색, 투명도를 지정한다. none을 지정하면 색을 칠하지 않는다.

stroke-width 선, 윤곽의 두께를 지정한다. -

cursor 마우스가 왔을 때의 커서를 지정한다. CSS로도 지정할 수 있다.

opacity 투명도를 지정한다. CSS로도 지정할 수 있다.

transform 평행 이동, 회전, 확대, 축소를 지정한다. -

Page 22: D3js datagram20160505

D3.js Basic DataGram

2. SVG 속성 변경(2) : CSS 스타일 적용 방법

(1) Style을 사용하는 방법

.style(“height”, function(d) {

return d + “px”;

});

(2) Class를 사용하는 방법

CSS 스타일 규칙은 class를 지정하는 방법과 문서요소에 직접 style 속성으로 지정하는 방법 두가지가 있으며 D3에서는 두 가지 방법 다 사용가능하지만, 여러 곳에서 공유해서 사용할 수 있는 클래스 사용을 추천한다. Style 속성은 예외적인 경우에만 사용한다.

.classed(“bar”, true)

이 코드는 넘어온 선택물에 bar 클래스를 적용한다.

.classed(“bar”, false)

False를 지정하면 반대로 선택한 문서요소에서 bar 클래스를 제거한다.

1

Page 23: D3js datagram20160505

D3.js Basic DataGram

3. SVG 속성 변경(3) : attr 속성 지정 방법

(1) 속성을 지정하는 방법

bar 클래스를 적용하려면 다음과 같이 사용한다.

.attr(“class”, “bar)

도형의 배경색과 외곽선도 attr 메서드를 이용해서 해당 속성을 지정할 수 있다.

.attr(“fill”, “yellow”)

.attr(“stroke”, “orange”)

.attr(“stroke-width”, function(d) {

return d/2;

});

(2) 여러 값을 한번에 매핑하기

svg.select(“circle”)

.attr(“cx”, 0)

.attr(“cy”, 0)

.attr(“fill”, “red”)

1

svg.select(“circle”) .attr({

cx : 0;

cy : 0;

fill : red

});

// 이 코드가 훨씬 간단하다. // style같은 다른 메서드도 동일하게 동작한다.

Page 24: D3js datagram20160505

D3.js Basic DataGram

D3 자세히 들여다보기

3.

Page 25: D3js datagram20160505

D3.js Basic DataGram

문서 요소의 선택과 추가 : selection

3.1

Page 26: D3js datagram20160505

D3.js Basic DataGram

1. 선택영역selections (1)

26

선택영역이란 웹페이지의 문서 객체 모델(Document Object Model, 이하 DOM) 중에서 선택된 요소를 의미한다.'DOM은'계층적인'형태를'띄며,'모든'웹페이지의'형태를'만드는'데'쓰인'다.'브라우저가'웹페이지를'렌더링한다는'것은'DOM을'표현한다는'의미다.'하나의'<div>'태그,'문단'요소,'myClass'클래스,'SVG'원,'심지어'페이지'전체도'선택영역이'될'수'있다.''D3에서'd3.select()와'd3.selectAll()'두'가지'메서드를'사용하면'선택영역을'생성할'수'있다.'''

(1)'CSS'선택자로'선택영역'만들기' d3.select(“circle”) // html요소'선택 d3.select(“.className”) // 클래스'선택 d3.select(“#myID”) // 아이디'선택

'

(2)'기존'선택영역으로'새로운'선택영역'만들기' D3.select(“.footer”).select(“p”)

'

(3)'선택영역을'변수로'설정하기' Var myGraf = d3.select(“p”) myGraf.text()'

Page 27: D3js datagram20160505

D3.js Basic DataGram

1. 선택영역selections (2)

27

(4) 선택영역 속성 변경하기 : attr() var myCircle = d3.select(“circle”); myCircle.attr(“fill”, “red”) myCircle.attr(“r”, 5)

Page 28: D3js datagram20160505

D3.js Basic DataGram

2. 메서드 체인method chain (1)

28

D3는'선언형'프로그래밍(declaraLve'programming)이라고'불린다.'컴퓨터에게'자세한'절차를'설명해'줄'필요'없이'무엇을'수정하고'싶은지만'알려'주면'된다.'속성의'이름과'값을'aMr()에서'지정해주면'나머지는'D3가'알아서'처리할'것이다.'D3의'선언적'특징은'메서드를'연속적으로'연결시킬'수'있게'해준다''

왼쪽의 3가지 코드는 모두 동일한 내용이다. 연속적으로 메서드를 연결시킨다는 의미는 코드 앞에 있는 선택영역에 그 뒤에 있는 모든 attr()를 적용시키는 것이 다. 세미콜론(;)은 연속적으로 연결된 메서드의 끝을 나타내므로, 마지막 줄에만 추가한다.

Page 29: D3js datagram20160505

D3.js Basic DataGram

2. 메서드 체인method chain (2)

29

(1)'메서드'연결하기':'D3에서'다음과'같이'메서드를'연속적으로'연결시킬'수'있다.'''

(2)'메서드'연결'도중에'새로운'선택영역'생성하기':'새로운'선택영역을'생성하면'그'이후에'연결되는'메서드는'기존의'선택영역'대신에'새로운'선택영역에'적용된다.''

Page 30: D3js datagram20160505

D3.js Basic DataGram

2. 메서드 체인method chain (3)

30

(3)'연결된'메서드를'변수로'지정해'주기'':'생성된'선택'영역에'메서드를'연속적으로'연결시킨'것을'변수로'지정할'수'있다.'''

'

'

'

'

'

:'만약'연결된'메서드'중간에'새로운'선택영역이'추가되면'마지막'메서드가'적용된'선택영역이'변수로'지정된다''

Page 31: D3js datagram20160505

D3.js Basic DataGram

3. 새로운 요소 추가하기 : append()

31

D3에서는 remove()와 append()를 사용해서 새로운 요소를 생성하고 삭제할 수 있다. (1) 요소 제거하기 : remove() : 만약 첫 번째 <div>를 제거하고 싶다면 d3.select(“div”).remove()를 입력한다. (2) 요소 추가하기 : append() : append()를 사용하면 선택영역에 상관없이 자식 요소를 추가할 수 있다. •  append()에 주어지는 인자는 추가하려는 요소 태그를 따옴표로 감싸서 표기해야 한다. •  append()는 항상 새롭게 생성된 요소를 맨 뒤에 추가시킨다(그렇기 때문에 ‘덧붙이다'라는 의미가 있는 append를 메서드 이름으로 사용한다).

•  append()는 선택영역을 반환(return)한다. 다시 말해서 연속적으로 연결된 메서드에 새로운 선택영역을 추가시키는 것이다.

Page 32: D3js datagram20160505

D3.js Basic DataGram

4. 여러 요소 선택하기 : selectAll()

32

d3.selectAll()은 한 번에 많은 요소를 선택영역으로 생성한다. d3.select(“p”)는 페이지에서 첫 번째 문단을 선택영역으로 생성하지만 d3.selectAll(“p”)는 모든 문단 요소를 선택영역으로 생성한다. d3.selectAll()로 생성된 선택영역에도 동일 하게 attr()와 text()를 사용할 수 었다. 이렇게 적용하면 선택된 모든 요소에 수정사항이 반영된다.

Page 33: D3js datagram20160505

D3.js Basic DataGram

데이터 결합하기 : data binding

3.2

Page 34: D3js datagram20160505

D3.js Basic DataGram

1. 데이터 결합 data binding (1)

34

데이터'결합은'말'그대로'데이터를'무언가와'합치는'것을'의미한다.'그'무언가는'<rect>,'<circle>,'<div>'등'웹페이지'요소'하나가'될'수도'있고,'여러'개의'요소가'될'수도'있다.''더'정확하게는,'그'요소들의'D3'선택영역과'데이터를'결합하는'것이다.''시각화는'근본적으로는'아래의'세'가지'중'하나의'동작을'하게'된다.'''

•'웹페이지로''들어간다(enter)'''''':'데이터'시각화는'데이터'또는'시각적'요소가'하나라도'없으면'만들'수'없다.'''''''따라서'도형이'웹페이지에'나타날'수'있어야'한다.''

•''업데이트(update)'된다'''''':'버튼을'클릭하거나'슬라이더를'조종하면'도형이'변형되면서''''''''새로운'데이터를'표현하도록'바뀐다.''

•'웹페이지에서'‘나간다(exit)'''''':'특정'데이터가'더'이상'유효하지'않게'되면,'''''''그것을'표현하던'도형도'화면에서'사라질'수'있다.'''

Page 35: D3js datagram20160505

D3.js Basic DataGram

1. 데이터 결합 data binding (2)

35

인터랙티브'시각화는'일종의'연극'무대와'같다고'할'수'있다.'연극을'하면'배우들이'무대에'들어가고'연기를'한'후'퇴장을'하듯이,'인터랙티브'시각화에서도'도형(또는'각종'시각적'요소)이'웹'페이지에'등장하고'다양한'형태로'업데이트된'후'나간다.'''

D3에서'이런'역할을'담당하는'것이'데이터'결합이다.'데이터'결합을'이용하면'시각적'요소가'웹페이지에'들어가고,'업데이트되고,'나갈'수'있다.''

들어온다 enter

업데이트된다 update

나간다 exit

Page 36: D3js datagram20160505

D3.js Basic DataGram

2. 데이터를 결합하는 방법(1)

36

(1) 존재하지 않는 요소를 선택하기 : d3.selectAll()을 이용하여 페이지에 존재하지 않는 요소를 선택할 수 있다.

빈 선택영역 그림

Page 37: D3js datagram20160505

D3.js Basic DataGram

2. 데이터를 결합하는 방법(2)

37

(2) 데이터 포인트에 새로운 객체를 생성하기 : 선택된'영역에'두'개의'메서드'data()와'enter()를'추가하면,'모든'데이터'포인트에'대해'새로운'객체를'생성한다.'D3에게'데이터의'크기가'얼마인지'알려주지'않아도'되며,'비어'있는'선택영역을'지정하고,'데이터를'결합해주면'알맞은'수의'객체를'생성해준다''

Page 38: D3js datagram20160505

D3.js Basic DataGram

2. 데이터를 결합하는 방법(3)

38

(3) 객체에 문서 요소 추가하기 : 이'객체들은'아직'비어'있다.'객체에'문서'요소를'실제로'추가해'주기'위해서는'append()를'이용해서'각'객체에'추가할'요소를'덧붙이면'된다.'그러나'아직'웹페이지에'문서'요소가'있기는'하지만'데이터가'없으므로'아무것도'보이지'않는다.''

(4)'문서'요소와'데이터를'결합하기''data()'메서드를'사용하면'데이터가'웹페이지의'각'요소와'엮이게'된다.'D3는'데이터를'쉽게'엮을'수'있게'해준다.'''

Page 39: D3js datagram20160505

D3.js Basic DataGram

3. 익명함수로 엮인 데이터에 접근하기(1)

39

익명함수는'이름이'없는,'즉'식별자(idenLfier)가'없는'함수이다.''여러'프로그래밍'언어에서'사용되며,'D3에서는'데이터를'엮기'위해'익명함수를'사용한다.''''

'

'

아주 짤막한 함수이기 때문에 한 줄로 적어도 된다.

이름이 있는 함수

같은 기능인 익명함수

익명함수는 일반함수와 같이 인자를 받을 수 있다.

Page 40: D3js datagram20160505

D3.js Basic DataGram

3. 익명함수로 엮인 데이터에 접근하기(2)

40

D3에는'익명함수로'데이터를'엮는'다양한'관례가'존재한다.'관례가'어떤'것인지'외워두면'D3를'사용할'수'있다.'''

•  익명함수는'd라는'이름의'특별한'인자를'받는다.'d는'선택된'영역'내'각'요소의'데이터'포인트를'지칭한다.'익명함수에게'd의'값을'반환하도록'하여'데이터를'설정할'수'있다.''

'

•  D3는'각'요소에'엮인'데이터'포인트의'값뿐'아니'라'배열의'인덱스도'알'수'있게'해준다.'인덱스에'접근하기'위해서는'익명함수에'i라는'새로운'인자를'전달해주면'된다.'D3는'for문을'사용해'반복문을'만들'필요없이'간단하게'인덱스에'접근할'수'있도록'해준다.'Y값을'인덱스'i와'barSpacing상수를'곱한'값으로'바꾸는'예시는'다음과'같다.''

•  주의할'점은'd는'반드시'인자로'전달해야하며,'i는'사용하지'않을'거라면'인자에'포함시키지'않아도'된다.'하지만'i를'사용할'거라면'익명함수에'인자로'전달되었는지'확인해야한다.'

Page 41: D3js datagram20160505

D3.js Basic DataGram

데이터 들어가기와 나가기: enter()와 exit()

3.3

Page 42: D3js datagram20160505

D3.js Basic DataGram

1. 들어가기 enter() : (1)

42

웹페이지의'문서'요소가'이미'데이터포인트와'대응되어있을'때,'새로운'데이터를'반영하기'위해'‘업데이트’를'할'수'있다.''enter()'메서드를'시용했을'때는'아직'엮여'있지'않은'각'데이터'포인트에'대해'새로운'요소를'생성했다.'하지만'‘업데이트'를'하는'경우에는'이미'페이지'요소가'존재하기'때문에'그럴'필요가'없다.'이미'존재하는'페이지'요소들을'선텍헤서,'새로운'데이터'를'기반으로'어떻게'해야'할지'알려'주기만'하면'된다.'''

Page 43: D3js datagram20160505

D3.js Basic DataGram

1. 들어가기 enter() : (2)

43

D3의'enter()'메서드는'다섯'개'요소를'모두'다시'생성하는'대신,'요소가'없는'데이터'포인트의'요소만'다시'생성한다.''

Page 44: D3js datagram20160505

D3.js Basic DataGram

1. 들어가기 enter() : (3)

44

이제'요소가'다'있으니'텍스트'요소를'추가할'수'있고,'다시'데이터와'웹페이지는'서로'제대로'엮이게'된다'''

Page 45: D3js datagram20160505

D3.js Basic DataGram

2. 나가기 exit() : (1)

45

데이터의'수가'요소의'개수보다'적을'경우,'데이터가'엮인'요소는'단순히'업데이트되지만'데이터가'엮이지'않은'요소는'나가기를'해야한다.'이'작업에는'exit()'메서드가'사용된다.''

Page 46: D3js datagram20160505

D3.js Basic DataGram

2. 나가기 exit() : (2)

46

일반적으로는'데이터'결합을'하고'나서'exit()을'사용해'데이터가'엮이지'않은'요소를'선택할'수'있다.'그'다옴에는'remove()라는'메서드를'이용해'요소를'완전히'제거할'수'있다.''

Page 47: D3js datagram20160505

D3.js Basic DataGram

2. 나가기 exit() : (3)

47

요약하면,'데이터'결합의'기본'철학은'아주'간단하다.'''

데이터'포인트가'요소보다'많은'경우:'들어가기(enter)'단계가'작동한다.''데이터'포인트와'요소의'수가'같은'경우:'업데이트(update)'단계가'작동한다.''데이터'포인트가'요소보다'적은'경우:'나가기(exit)'단계가'작동한다.'''

하지만'D3를'사용할'때'세'가지'모두를'사용해야하는'것은'아니다.''예를'들어,'D3를'이용헤'정지된'시각화를'만둘'때는'enter()만'사용해도'되고,'인터랙티브한'시각화를'만든다면'업데이트할'때마다'데이터'포인트의'개수가'동일하게'유지되면'exit()가'필요없을'수도'있다.''

Page 48: D3js datagram20160505

D3.js Basic DataGram

축과 척도 : axis와 scale

3.4

Page 49: D3js datagram20160505

D3.js Basic DataGram

1. 척도 : 정의역과 치역 (1)

49

척도를'사용하면'그래프의'축을'간편하게'만들'수'있다.'''

•  정의역(domain)':''입력되는'데이터를'의미한다.'•  치역(range)':'출력되는'데이터(페이지에서'보여'주고'싶은'데이터)를'의미한다.'

선형 척도가 작동하는 방법

Page 50: D3js datagram20160505

D3.js Basic DataGram

1. 척도 : 정의역과 치역 (2)

50

정의역은'주어진'데이터를'갖고'있어야'하고'치역은'그래프가'그려지는'공간에'대한'정보를'갖고'있어야'한다.'''

['예제':''정의역과'치역의'하한과'상한을'설정하기]'(1) 치역':'치역에'대한'배열의'하한과'상한을'정의해'줘야'한다.'하한은'0이며(너비가'가장'작은'막대의'너비가'0이기'때문이다)'상한은'그래프가'출력될'화면의'너비(가장'큰'막대가'화면의'너비'전체를'차지하기'위해서)를'나타내야'한다.'

(2) 정의역':'만약'데이터'값이'0이면'너비가'0인'막대를'출력해주기'위해서'하한은'0이'되야'한다.'상한은'데이터에서'가장'큰'값으로'설정한다.'데이터에서'가장'큰'값을'직접'찾기보다'd3.max()라는'메서드를'사용해서'D3가'알아서'찾게'만들'수'있다.''

Page 51: D3js datagram20160505

D3.js Basic DataGram

2. 선형척도에 축 추가하기(1)

51

정량적인(quanLtaLve)'정보를'담는'선형척도(linear'scale)에'축을'추가한다.'''

(1)'축'생성자'만들기'''''':'축의'스케일이'X,'즉'선형척도임을'명시하기'위해'scale()에'변수'x를'추가한다.''

'

'

(2)'만들어놓은'축'생성자'호출하기'''''':'SVG에'새로운'그룹(g)을'추가하고,'xAxis를'호출하는'콜백함수'call()'메서드를'추가한다.''

'

'

(3)'축의'스타일'바꾸기'''''':''축'그룹에'axis'클래스를'추가하여'CSS'스타일을'정의한다.''

Page 52: D3js datagram20160505

D3.js Basic DataGram

2. 선형척도에 축 추가하기(2)

52

D3에서'축에'세부'요소를'설정할'수'있는'메서드는'다음과'같다.''

Page 53: D3js datagram20160505

D3.js Basic DataGram

3. 순서 척도에 축 추가하기 (1)

53

정성적인(qualitaLve)'정보를'담고'있는'순서'척도(ordinal'scale)에'축을'추가한다.'''

(1)'순서'척도를'생성한다.''''''':'D3에서는'스케일을'설정할'때'치역을'명시하는'대신'‘치역'구간(range'band)’을'전달해''''''''쉽게'계산할'수'있다.'치역'구간은'범위를'명시하는'두'개의'입력'받아'치역을'계산한다.''

Page 54: D3js datagram20160505

D3.js Basic DataGram

3. 순서 척도에 축 추가하기 (2)

54

D3에서는'전달받은'범위에'따라'자동적으로'범위를'분할한다.''치역'구간을'설정하면'각'구간의'크기를'반환하도록'요청할'수'있다.''

Page 55: D3js datagram20160505

D3.js Basic DataGram

동적인 시각화를 위한 트랜지션 메서드 : transition()

3.5

Page 56: D3js datagram20160505

D3.js Basic DataGram

1. 갱신(Update)

56

갱신(update)과 트랜지션(transition) 실제 데이터는 시간에 따라 변화하며, D3에서는 이런 변화를 갱신(update)라고 부른다. 시각적으로 인지할 수 있도록 모션을 통한 트랜지션을 사용하면 갱신을 좀더 멋지게 만들 수 있다.

Page 57: D3js datagram20160505

D3.js Basic DataGram

1. 갱신(Update)

57

[데이터 갱신 방법] D3코드가 페이지에 데이터를 가져오는 과정은 너무 빠르게 일어나므로 일어난 변화를 알아차리게 하려면, 갱신 관련 코드를 다른 코드와 분리하고 갱신을 하기 위한 시발점(예: 마우스 클릭)이 필요하다. (1)  1단계 - 이벤트 리스너에 반응하기 : 이벤트 리스너(event listener)란 어떤 문서요소(들)에서 일어나는 특정 이벤트 발생을 알기 위한 익명 함수다. D3에는 이벤트 리스너 추가를 돕는 메서드로 selection.on()이 있다. on()은 이벤트 타입(“click”)과 이를 위한 리스너(익명 함수) 두 개의 전달인자를 받는다. d3.select(“p”) .on(“click”, function() { // 클릭할 때 하는 일. });

(2) 2단계 - 데이터 변경하기 : 새로운 데이터를 반영한다. svg.selectAll(“rect”) .data(dataSet);

(3) 3단계 - 시각화 갱신하기 : 시각화를 담당하는 문서요소의 속성을 갱신한다. 필요하다면 x, y 좌표값이나 높이, 넓이 등의 속성을 변경한다.

Page 58: D3js datagram20160505

D3.js Basic DataGram

2. 트랜지션(Transition)

58

트랜지션(transition) 트랜지션 애니메이션은 .transition() 메서드를 추가하여 구현한다. 메서드 체인을 사용해서 선택물을 만드는 코드와 속성을 변경하는 코드 사이에 이 코드를 명시적으로 추가한다. 단지 한줄만 추가하면 D3가 추가 작업을 해서 데이터 변화 과정을 애니메이션으로 만들어 준다. Transition()이 없으면 D3가 모든 attr()구분을 한번에 분석하기 때문에 속성이 즉시 변한다. 그런데 transition()을 추가하면, D3는 새로운 값을 즉시 반영하지 않고 시간 개념을 도입한다. 즉, 시작 값과 끝 값을 정규화하고 중간 상태의 모든 값을 계산한다. 이때 D3는 형태가 다른 속성값의 차이를 알아서 바꾼다.

Page 59: D3js datagram20160505

D3.js Basic DataGram

2. 트랜지션(Transition)

59

duration() : 트랜지션의 지속 시간. 밀리초 단위로 지정한다. 즉 duration(1000)은 1초이다.

ease() : 모션의 변동 비율이 일정하지 않고 가변적으로 변하도록 한다. 이처럼 트랜지션에 사용되는 모션의 특성을 이징(easing)이라고 한다. D3에서는 ease() 메서드를 사용해서 여러 종류의 이징을 지정할 수 있다. 이징의 기본값은 cubic-in-out이며 점진적으로 가속되었다가 감속된다. D3에 내장된 이징 함수는 몇 가지가 더 있다. ease(“linear”)는 일정한 속도로 이동하다가 갑자기 멈추고, ease(“circle”)은 끝까지 가속하는 점진적인 이징이며, ease(“elastic”)은 한번 튕겨주는 이징이며, ease(“bound”)는 공처럼 튀기다 멈추는 이징이다

Page 60: D3js datagram20160505

D3.js Basic DataGram

2. 트랜지션(Transition)

60

delay() : 트랜지션의 시작 지점을 지정한다. 밀리초로 정적인 값을 줄 수 있다. 특별히 지켜야 하는 순서가 있는 건 아니지만 duration() 전에 사용하는 게 좋다. 먼저 지연시키고 트랜지션을 실행할 수 있기 때문이다. 정적인 지연 값도 유용하지만 동적으로 계산한 지연 값을 사용하여 시차 지연을 둘 수 있다. 이렇게 동작하려면 delay() 함수에 정적인 값 대신에 함수를 넘겨준다.

… Transition() .delay(function(d, i){

return i * 100; }) .duration(500) …

… .transition()

.delay(1000) .duration(2000) …

Page 61: D3js datagram20160505

D3.js Basic DataGram

2. 트랜지션(Transition)

61

each() : 트랜지션이 시작하거나 끝나는 시점에 무언가 동작시켜야할 때, each()를 사용하면 선택물의 원소별로 임의의 코드를 실행할 수 있다. each()는 두 개의 전달인자가 필요하다. (1) start 혹은 end 중 하나의 값 (2) 트랜지션의 시작이나 종료 시 실행할 익명함수

… .each(“start”, function() { // 트랜지션 시작 시 실행할 함수 }) … .each(“end”, function() { // 트랜지션 종료 시 실행할 함수 }) …

[주의] 문서요소에서 트랜지션은 한 번에 하나만 동작하기 때문에, 새로운 트랜지션을 적용하면 이전 트랜지션을 덮어버린다. 이것은 사용자가 여러 버튼을 연속해서 누를 때 먼저 선택한 트랜지션이 아닌 마지막으로 선택한 트랜지션으로 동작하도록 만들기 위한 설계이다. 트랜지션의 이런 특징 때문에 each(“start”, …)는 트랜지션이 없는 단순 트랜스폼(transform0) 작업을 위해서만 사용해야한다. 하지만 each(“end”, …)는 트랜지션 사용이 가능한데, each()가 호출되는 시점은 주요 트랜지션이 이미 종료된 상태이기 때문에 새로운 트랜지션이 생성되어도 문제를 일으키지 않는다. 여러 트랜지션을 나열할 때는 메서드 체인을 사용하고, each()는 트랜지션의 시작과 끝에서 일어나야 하는(트랜지션이 아닌) 즉각적인 변화에만 사용하는 것이 좋다.

Page 62: D3js datagram20160505

D3.js Basic DataGram

2. 트랜지션(Transition)

62

interpolate() : 보간자(interpolator)는 트랜지션 전의 초기 상태와 트랜지션 후의 종료 상태 사이의 속성값 변화를 계산하기 위해 사용된다. 내부적으로는 축척도 이와 같은 보간자에 기초를 두고 있다. D3의 내장 보간자는 거의 모든 타입에 대해 값을 보간할 수 있다. d3.interpolate(a, b)라고 쓰면 D3가 알아서 적절한 보간자를 선정한다. Interpolation함수는 b의 타입에 맞게 선정된다. (1)  b가 숫자라면 a는 강제로 숫자로 간주한다. 이 경우에 0을 보간의 시작값이나 종료값으로 쓰면 안된다. 트랜지션하는 속성의 값은 최종적으로는 문자열로 변환되는데, 아주 작은 값은 공학 표기법을 따르는 문자열로 변환되기 때문이다. CSS와 HTML은 0.0000001을 제대로 이해하지 못한다. 따라서 안전하게 쓸 수 있는 가장 작은 값은 0.000001이다.

(2)  b가 문자열이면 D3는 그 값이 CSS 색상 문자열인지 확인하여 적절한 색상으로 변환한다. a도 마찬가지로 색상으로 변환되고 D3는 interpolateRgb() 함수 또는 색상 공간에 맞는 다른 색상 관련 보간자가 사용된다.

… Function interpolateNumber(a, b) {

return function(t) { return a + t * (b – a); };

} …

Page 63: D3js datagram20160505

D3.js Basic DataGram

D3 레이아웃 알아보기

4.

Page 64: D3js datagram20160505

D3.js Basic DataGram

레이아웃(layout)이란

D3의 레이아웃은 이름과 달리 화면에 무언가를 보여주지는 않는다. 레이아웃 관련 메서드는 직접적으로 시각적인 결과물을 내는 메서드가 아니다. 여러분이 매핑하거나 변환한 데이터를 D3의 레이아웃이 가져다가 특정 형태의 시각화에 걸맞은 새로운 데이터를 생성한다. D3 레이아웃은 서로 다른 기능을 수행하고 자기만의 독특한 특징을 가지고 있다. 자세한 내용은 공식 API의 레이아웃 문서(https://github.com/mbostock/d3/wiki/Layouts) 를 참고한다.

64

Bundle Chord Cluster Force

Hierarchy Histogram Pack Partition

Pie Stack Tree Treemap

Page 65: D3js datagram20160505

D3.js Basic DataGram

예시 : 포스 레이아웃(force-layout)

화면의 요소를 처리하는 데 물리 역학(physical force)을 사용하기 때문에 포스 레이아웃(force-directed layout)이라고 부른다.

포스 레이아웃은 일반적으로 관계(network) 데이터에 사용된다. 컴퓨터 공학에서는 이런 데이터 집합을 그래프(graph)라고 부르는데, 간단한 그래프는 노드(node)와 연결(edge)들로 구성된다. 노드는 데이터 집합의 엔터티이고, 연결이란 노드 간의 연결을 말한다. 그러나 모든 노드가 항상 연결되어 있는 것은 아니다. 노드는 보통 원으로 표시하고 연결은 선으로 표시한다.

65

* 물리 역학이란 다른 원소들과 스프링으로 연결되어 서로 밀치는 입자계를 말한다. 여기서 반발력은 서로 항상 밀쳐 내면서 입자들이 시각적으로 겹치는 현상을 방지한다. 그리고 스프링은 입자들을 잡아 두어서 정해진 영역 밖으로 날아가 버리는 일을 방지한다. 결과적으로 모든 입자를 항상 한 화면에서 볼 수 있게 된다.

| image source : http://mathinsight.org/network_introduction | http://www.cprogramming.com/tutorial/computersciencetheory/graphtheory.html

Page 66: D3js datagram20160505

D3.js Basic DataGram

1. SVG 영역 크기 설정

66

<!DOCTYPE html> <html lang="en">

<head> <meta charset="utf-8"> <title>D3: Force layout</title> <script type="text/javascript" src="http://d3js.org/d3.v3.min.js"></script>z <style type="text/css"> /* No style rules here yet */ </style> </head> <body> <script type="text/javascript">

//넓이와 폭 설정 var w = 500; var h = 300;

//이'부분에'포스'레이아웃'코드를'추가한다.

</script> </body>

</html>

포스'레이아웃이'그려질'영역의'크기를'설정한다.''

Page 67: D3js datagram20160505

D3.js Basic DataGram

2. 데이터셋 설정

67

//원본 데이터셋 설정 var dataset = { nodes: [ { name: "Adam" }, { name: "Bob" }, { name: "Carrie" }, { name: "Donovan" }, { name: "Edward" }, { name: "Felicity" }, { name: "George" }, { name: "Hannah" }, { name: "Iris" }, { name: "Jerry" } ], edges: [ { source: 0, target: 1 }, { source: 0, target: 2 }, { source: 0, target: 3 }, { source: 0, target: 4 }, { source: 1, target: 5 }, { source: 2, target: 5 }, { source: 2, target: 5 }, { source: 3, target: 4 }, { source: 5, target: 8 }, { source: 5, target: 9 }, { source: 6, target: 7 }, { source: 7, target: 8 }, { source: 8, target: 9 } ] };

nodes와'edges라는'원소'두'개를'가진'객체'dataset을'만든다.'두'개의'원소는'객체를'원소로'갖는'배열이다.''

nodes'배열에'노드'정보를'입력한다.'''

edges'배열에'링크'정보를'입력한다.'연결선은'시작점과'목적지'ID'두'개의'값을'가지며,'ID는'노드에'대응된다.'예)'ID가'3이면'‘Donovan’이고,'3이'4로'연결된다면'‘Donovan’과'‘Edward’가'연결된다.'''

source':'접속된'곳의'노드'번호'target':'접속할'곳의'노드'번호''

Page 68: D3js datagram20160505

D3.js Basic DataGram

3. 포스 레이아웃 초기화

68

//데이터셋에 있는 노드와 에지를 사용하여 기본 포스 레이아웃을 초기화 var force = d3.layout.force() .nodes(dataset.nodes) .links(dataset.edges) .size([w, h]) .start();

포스'레이아웃을'초기화한다.'''

가장'기본적인'요소만을'갖춘'최소한의'형태는'사용할'노드(nodes)와'연결선(links),'레이아웃의'크기(size)를'지정하고,'준비가'끝나면'start()'메서드를'호출하는'형태이다'

Page 69: D3js datagram20160505

D3.js Basic DataGram

3. 포스 레이아웃 사용자 정의

69

//데이터셋에 있는 노드와 에지를 사용하여 기본 포스 레이아웃을 초기화 var force = d3.layout.force() .nodes(dataset.nodes) .links(dataset.edges) .size([w, h]) .linkDistance([50]) .charge([-100]) .start();

var colors = d3.scale.category10();

색상'값을'설정한다.'

초기화한'포스'레이아웃에'필요한'옵션을'더해서'원하는'형태로'옵션을'추가한다.'''

linkDistance'옵션으로'노드'사이의'연결선'길이를'조금'늘려주고,'노드'사이에'반발력이'커지도록'charge'옵션을'음수로'지정하여'노드'간의'간격을'더'벌려주었다.''

Page 70: D3js datagram20160505

D3.js Basic DataGram

4. SVG 요소로 에지와 노드 생성

70

//SVG 요소를 생성 var svg = d3.select("body") .append("svg") .attr("width", w) .attr("height", h);

//line을 이용하여 에지를 생성 var edges = svg.selectAll("line") .data(dataset.edges) .enter() .append("line") .style("stroke", "#ccc") .style("stroke-width", 1); //circle을 이용하여 노드를 생성 var nodes = svg.selectAll("circle") .data(dataset.nodes) .enter() .append("circle") .attr("r", 10) .style("fill", function(d, i) { return colors(i); }) .call(force.drag);

에지와'노드를'생성할'SVG'요소를'선택한다.'

SVG'line을'이용하여'에지를'생성한다.'

SVG'circle을'이용하여'노드를'생성한다.'노드'색상으로'd3.scale.category10을'적용한다.'

상호작용이'가능하도록'드래그'앤'드롭을'호출한다.'(이'줄이'없으면'노드를'움직일'수'없다.)'

Page 71: D3js datagram20160505

D3.js Basic DataGram

5. 다시 그리기를 위한 tick이벤트

71

////다시'그릴'때(tick이벤트가'발생할'때)마다'함수를'호출하여'새로운'좌표'값으로'노드와'에지를'그림 force.on("tick", function() {

edges.attr("x1", function(d) { return d.source.x; }) .attr("y1", function(d) { return d.source.y; }) .attr("x2", function(d) { return d.target.x; }) .attr("y2", function(d) { return d.target.y; }); nodes.attr("cx", function(d) { return d.x; }) .attr("cy", function(d) { return d.y; }); });

포스 레이아웃에서는 자동으로 애니메이션 처리가 수행되지만, 이때 노드와 노드를 연결하는 선을 다시 그리는 처리가 필요해진다. 다시 그리기가 필요해지면 포스 레이아웃에서 tick 이벤트가 발생한다. on() 메서드를 사용하여 tick이벤트를 포착한 다음 이벤트가 발생할 때 처리를 수행할 함수를 지정한다. 이 함수 안에 좌표 값의 재설정을 수행하는 처리를 작성한다. 이때 좌표 값의 계산은 d3.js가 자동으로 수행하므로 표시할 노드와 선의 좌표 값을 설정하기만 하면 된다.

* 포스 레이아웃의 tick은 축(axis)를 만들 때 사용하는 구분용 눈금(tick)을 뜻하는 것이 아니다. 물리 역학에서 말하는 tick은 시계의 초침처럼 일정량의 시간 경과라는 의미로 사용한다. 이를 통해서 실시간으로 갱신되는 계산된 모션을 보게 된다. 그러나 모든 프로그램의 tick이 실제 시간과 동일하게 동작하는 것은 아니며, 데이터에 따라 실제 시간보다 빠르게 흐르거나 느리게 흐르는 tick을 프로그래밍할 필요가 있다.

매순간(Lck)마다'line과'circle의'x,'y'값을'갱신한다.''

Page 72: D3js datagram20160505

D3.js Basic DataGram

참고 도서

5.

Page 73: D3js datagram20160505

D3.js Basic DataGram

참고 도서

73

D3.js':'쉽고'빠른''인터랙티브'데이터'시각화''|'도서출판'인사이트'

D3.js'입문':'웹을'매력적으로'만드는'그래프와'차트'만들기''|'프리렉'

D3를'이용한'시각적'스토리텔링'|'인사이트'

D3'in'AcLon'

|'Manning'

Page 74: D3js datagram20160505

e-mail to Hannah : [email protected]

수고하셨어요!'

5월 19일에 다시 만나요~!