D3_js

[D3.js] SVG를 이용한 Chart와 Circle

vhxpffltm 2019. 7. 19. 23:32

이번에는 SVG를 이용해서 시각화를 진행해보자.

 

SVG는 벡터로 이미지를 표현한 것이며 백터(vector) 이미지를 표현하기 위한 포맷으로 w3c에서 만든 백터 이미지 표준이다.

 

특징은 이미지를 확대하든 변형하든 깨짐이 없는것이 특징이다.

 

먼저 산점도부터 보자

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
var w = 500, h = 200;
        var data3 = [510203050];
 
        var svg = d3.select('body').append('svg')
        .attr('width', w).attr('height', h);
            //SVG객체를 참조하기 위함
 
        var circle = svg.selectAll('circle').data(data3)
        .enter().append('circle');
        //selectAll은 아직 존재하지 않는 circle에 대해 빈 참조를 반환
        //data로 데이터 묶음, enter로 신규 문서요소 참조 반환, append가 DOM에 circle추가
        //나중에 circle을 참조하기 쉽도록 변수를 만든것.
 
        circle.attr("cx"function (d, i) {
                return (i * 100+ 25// 원의 x좌표 값이 커짐 -> 오른쪽으로 이동
                })
            .attr("cy", h/2)
            .attr("r"function (d) {
                return d; //d는 data3의 집합이므로 반지름이 커지는 원을 그림.
                })
            .attr("fill""green")
            .attr("stroke""gray")
            .attr("stroke-width",function(d){
                return d/2;   //svg 명령어를 통해 색상을 설정
            });
        
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter
 

 

 

d3에서 SVG객체를 가리키는 참조를 위해 아래와 같이 작성한다.

 

var svg = d3.select('body').append('svg')

        .attr('width', w).attr('height', h);

 

이제 변수 svg를 어디서든 사용하여 크기가 w,h인 상단과 높이를 지정하여 SVG객체를 만들 준비가 되었다.

 

 var circle = svg.selectAll('circle').data(data3)

        .enter().append('circle');

 

원을 시각화할 준비를 한다. 변수 circle을 사용하여 언제든 circle을 참조할 수 있게 한다.

 

.attr은 속성을 주는 것이다. 'cx' , 'cy', 'r' 은 각각 원의 x좌표, y좌표, 반지름을 나타낸다. 표준 SVG와 똑같다. 각 코드를 보면 x값은 익명함수를 통해 값을 받는데 i가 있다. 여기서 i는 해당 문서요소의 색인값을 뜻한다. 즉, 인덱스 번호라고 생각하면 좋다. 

 

이후의 fill, stroke, stroke-width 역시 SVG문법과 같으며, 각각 색을 채우고, 선을 그리고, 선의 두께를 의미한다. 값을 고쳐 확인하면 바로 이해할 수 있다. 한번 실행해보자.

 

위와 같은 결과를 볼 수 있을것이다. 데이터 값은 막대 그래프를 모두 진행하고 확인해보자.

 

이번에는 SVG로 막대 그래프를 그릴 것이다. 이전에는 CSS스타일을 사용하여 시각화하였다. 아래에 예시코드가 있다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
var w2 = 700, h2 = 300, padding = 10;
        var dataset = [5101319212522181513,
                        11121520181716182325];
        var svg2 = d3.select('body').append('svg')
                    .attr('width', w2)
                    .attr('height', h2);
        //append에 svg를 써야 svg를 body안에 사용할것을 의미, attr은 svg객체의 가로 세로 크기를 뜻함
 
        //attr메서드의 속성들을 객체로 묶어서 할것ㅇ임, 간결하다(오류생김 나중에 수정할것!!)
        svg2.selectAll('rect').data(dataset)
            .enter().append('rect')
            .attr("x"function (d, i) {
                return i * (w2 / dataset.length);
            }) // 차트를 만들기위한 x좌표 이동
            .attr("y"function (d) {
                return h2 - (d*4); //높이에서 데이터를 빼야 SVG하단에 막대의 하단이 놓임, d값을 변형했으면 변형한 만큼 
            }).attr("width", w2 / dataset.length - padding) // 각 막대사이의 간격
            .attr("height"function (d) {
                return d*4//짧기때문에 4를 곱함
            })
            .attr('fill',function(d){
                return 'rgb(10,100,'+(d*10+')' //값이 클수록 밝은색상이 나오도록 조정
            });
   
        //라벨
        svg2.selectAll('text').data(dataset)
            .enter().append('text')
            .text(function (d) {
                return d;
            })
            .attr("text-anchor",'middle'// 할당된 x값에 가로로 중앙 정렬을 하는 속성
            .attr('x'function (d, i) {
                return i * (w2 / dataset.length+ (w/dataset.length-padding)/2//텍스트 정렬을 위함
            })
            .attr('y'function (d) {
                return h2 - (d * 4+ 14;
            })
            .attr('font-family''scans-serif')
            .attr('font-size''11px')
            .attr('fill''white');    // 텍스트 속성을 추가, 크기,색상,폰트
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter
 

 

단계별로 해보자.

 

처음에는 SVG 영역의 크기를 위해 w,h 변수의 값을 초기화해준다.

이후, SVG문서요소 생성을 한다. 변수 svg2처럼 만들면 이 변수로 언제든 참조할 수 있다.

지금은 모두 코드가 답으로 만들어져 있지만, 여기는 조금 살펴보고 가자.

 

svg2.selectAll('rect').data(dataset)

            .enter().append('rect')

            .attr("x"function (d, i) {

                return i * (w2 / dataset.length);

            }) // 차트를 만들기위한 x좌표 이동

            .attr("y"function (d) {

                return h2 - (d*4); //높이에서 데이터를 빼야 SVG하단에 막대의 하단이 놓임, d값을 변형했으면 변형한 만큼 

            }).attr("width", w2 / dataset.length - padding) // 각 막대사이의 간격

            .attr("height"function (d) {

                return d*4//짧기때문에 4를 곱함

            })

            .attr('fill',function(d){

                return 'rgb(10,100,'+(d*10+')' //값이 클수록 밝은색상이 나오도록 조정

            });

 

주석으로 있지만, attr('x',0)으로 한다면 어떻게 될까? 막대가 하나로 모두 겹쳐 나올 것이다. 이를 방지하기 위해 위와 같이 처리한다. 

attr('width',...) 는 데이터의 개수에 비례하도록 지정한 것이다. 데이터가 늘어나면 간격이 조밀해지고 데이터수가 줄어들면 간격이 넓어진다. 이해를 위해 x는 막대(사각형)에 대한 x값이고 width는 막대사이의 간격을 위한 속성이라고 생각하면 된다. 이 값을 변경하면 각 막대의 너비가 조절될 것이다. 이 너비를 일정하게 맞춘다. 이해가 안된다면 width속성값을 바꾸고 테스트하면 좋을것 같다.

 

이제 height를 보자. height역시 막대의 높이를 결정한다고 생각하면 된다. 다음으로 y값인데...

이것은 중요하기 때문에 예제 코드를 변경하여 결과를 한번 보자.

아래의 결과는 .attr('y',0) 으로 한 결과이다.

 

 

 왜 위와 같은 결과가 나올까... SVG 사각형을 그릴때, 왼쪽 상단 모서리를 기준으로 x,y 좌표를 잡기 때문이다. 이 사각형은 모두 원점과 참조 좌표는 좌측 상단이 기준이기 때문이다. 우리는 좌측 하단을 기준으로 잡아야 한다.

즉, 막대높이를 상단에서부터 늘려야한다. 막대의 상단은 SVG의 높이, 막대의 데이터 값과 연결지어 위의코드처럼 동적으로 변경할 수 있다. 

 

색상은 fill 속성을 사용하여 바꿀수 있다. 위 코드처럼 값에따라 rgb의 한값을 조정하여 다양한 스타일을 만들 수 있다. 

 

마지막으로, 라벨을 간단하게 보자. 

 

svg2.selectAll('text').data(dataset)

            .enter().append('text')

            .text(function (d) {

                return d;

            })

 

'text' 를 선택하고 data를 가지고 왔다 function 익명함수를 통해 텍스트에 데이터의 값을 바로 가져온다.

 

.attr('x'function (d, i) {

                return i * (w2 / dataset.length+ (w/dataset.length-padding)/2//텍스트 정렬을 위함

            })

            .attr('y'function (d) {

                return h2 - (d * 4+ 14;

            })

            .attr('font-family''scans-serif')

            .attr('font-size''11px')

            .attr('fill''white'); 

 

'x', 'y' 를보고 우린는 텍스트의 위치를 조절한다는 것을 알 수 있다. return 값에 다음과 같이 한 이유는 높이를 막대 그래프의 위쪽 상단에 맞추고 가로를 각 막대의 가운데에 위치시키기 위해 다음과 같이 하였다. 값을 조절해서 원하는 값으로 언제든 변환할 수 있다.

 

아래의 attr은 텍스트의 속성을 나타낸다. text 크기, 폰트, 색상을 조절하여 원하는대로 스타일링 하면 된다.

 

결과를 한번 보자.

 

 

다음과 같은 시각화를 얻을 수 있다. 개발자 도구를 통해 데이터 값을 구하고 elements의 값을 항상 체크하여 어떻게 시각화가 이루어지는지 확인하자.

 

'D3_js' 카테고리의 다른 글

[D3.js] 척도  (0) 2019.08.03
[D3.js] Scatter_산포도  (0) 2019.07.25
[D3.js] chart 그리기  (0) 2019.07.17
[D3.js] DOM 문서요소 선택하기  (0) 2019.07.15
[D3.js] Data_driven_Document  (0) 2019.07.10