일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 유효재고
- flash에러
- chart flash
- 로트관리
- rmate chart flash
- SQL0104
- 생산SCM
- 시큐어코딩
- mms.cfg
- adobe flash 보안정책
- SEcure coding
- D3.js
- rmate chart
- D3차트
- Token ) was not valid
- Today
- Total
티스토리 뷰
일반적인 차트에서 흔히 보는 척도를 구현하려고 한다.
이러한 기능을 구현하기 위해서 앞의 '01 간단한 차트 만들기'
마지막 소스 중에서 다음과 같이 수정해 준다.
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 41 42 43 44 45 46 47 48 49 50 51 52 | <!DOCTYPE html> <meta charset="utf-8"> <style> svg { border: 1px solid; } .bar { fill: orange; } .bar:hover { fill: tomato; cursor: pointer; } .text { fill: white; font-weight: bold; } </style> <svg width="500" height="300"></svg> <script src="https://d3js.org/d3.v4.min.js"></script> <script> var dataset = [ {x : 'A', y : 9} , {x : 'B', y : 19} , {x : 'C', y : 29} , {x : 'D', y : 39} , {x : 'E', y : 29} , {x : 'F', y : 19} , {x : 'G', y : 9} ]; var svg = d3.select("svg"); svg.selectAll("rect") .data(dataset) .enter() .append("rect") .attr("class","bar") .attr("height", function(d, i) {return (d.y * 5)}) .attr("width", 40) .attr("x", function(d, i) {return (50 * i)}) .attr("y", function(d, i) {return (250 - d.y * 5)}); svg.selectAll("text") .data(dataset) .enter() .append("text") .text(function(d) {return d.y}) .attr("class", "text") .attr("x", function(d, i) {return 50 * i + 10}) .attr("y", function(d, i) {return 250 - d.y * 5 + 15}); </script> | cs |
차트의 가로 축(X) 데이터와 세로 축(Y) 데이터의 값이 출력되는 것이
표면적으로 봐도 편하고 보기에도 좋다.
기본적으로 차트에서 일반적으로 제공되는 기능이기도 하다.
따라서, 이전에는 데이터를 세로 축(Y)의 값만 배열로 작성했지만
가로 축(X)에도 값을 출력하기 위해 임의의 값 dataset을 Json데이터의 배열로 작성했다. [line 22~28]
X축의 값과 Y축의 값이
같이 하나의 쌍으로 구성된다.
이러한 데이터의 구조 변화에 따라서
사용법에 조금 변화가 있다. [line 38, 41, 47, 50]
바의 높이와 위치를 계산할 때
변수 d로 받아서 사용하던 데이터 사용법을 d.y의 형태로 바꿔준다.
기존에 각각 function에서 넘어오는 값은 각 배열의 원소(d)가 넘어와서
이 배열 원소는 그냥 값이니 그대로 사용했다.
즉, d * 5와 같이 바로 사용했었다.
하지만 Json배열은 각 원소는 Json이 되고
Json은 x, y로 지정되어 있기 때문에
return에 d,y * 5와 같은 방식으로 사용되게 된다.
그리고 CSS를 이용하여 SVG의 border를 변경해본다. [line 4]
다음에는 SVG 크기에 맞춰서
X축부터 출력해본다.
기능을 구현하기 전에 D3에서 제공하는 scale에 대해서 알아야 한다.
[참조URL]
http://blog.naver.com/PostView.nhn?blogId=zero_kjy&logNo=220788807530
https://www.slideshare.net/neuroassociates/week16-d3js
v3버전에서는 scale(척도)과 axix(축)을 나누어서 구현했다.
v4버전에서는 scale 하나로 처리하는 차이가 있다.
v4에 대한 자료를 대충만 봐도...
많은 척도가 정의되어 있다.
https://github.com/d3/d3-scale
이 중에서 가장 많이 쓰이는 scaleBand라는 척도가 있다는 것만 기억하고 넘어간다.
척도에서 중요한 개념인 domain과 range가
d3.v3와 d3.v4에서 같은 개념과 방식으로 사용된다.
d3.scale() 척도 : 입력되는 정의역(domain)과 출력되는 치역(range)을 매핑한 함수 .domain() : 입력되는 데이터 값의 범위 .range() : 출력되는 범위 (단위:픽셀) d3.scale.linear() .domain([시작점,끝점]) .range([시작점,끝점)] var xAxis = d3.svg.axis() //축을 생성하는 함수 .scale(x) //축을 생성할 때는 어떤 척도를 다뤄야 하는지 알려줘야 함. .orient("bottom"); //축의 위치 |
예로, dataset = [1, 2, 3, 4, 5] 값을 가지는 데이터가 있고
출력하고자 하는 차트 SVG 너비가 100px이라고 하면,
.domain([1,5])
.range([1,100])
이 된다.
그리고, 척도(scaleBand)에서
데이터 값이 1일때는 20px, 2일때는 40px과 같은
적당한 위치값을 계산해서 반환하게 된다.
크기는 x축이니 width로 bandwidth란 메소드를 이용하고
위치는 척도의 인스턴스(xScale) 함수를 호출하면 된다.
다음은 위 지식을 가지고 다음 코드를 작성해 X축을 출력해 본다.
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 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | <!DOCTYPE html> <meta charset="utf-8"> <style> svg { border: 1px solid; } .bar { fill: orange; } .bar:hover { fill: tomato; cursor: pointer; } .text { fill: white; font-weight: bold; } </style> <svg width="500" height="300"></svg> <script src="https://d3js.org/d3.v4.min.js"></script> <script> var dataset = [ {x : 'A', y : 9} , {x : 'B', y : 19} , {x : 'C', y : 29} , {x : 'D', y : 39} , {x : 'E', y : 29} , {x : 'F', y : 19} , {x : 'G', y : 9} ]; var svg = d3.select("svg"); var width = parseInt(svg.style("width"), 10); var height = parseInt(svg.style("height"), 10)-20; var xScale = d3.scaleBand() .domain(dataset.map(function(d) { return d.x;} )) .range([0, width]).padding(0.2); svg.selectAll("rect") .data(dataset) .enter() .append("rect") .attr("class","bar") .attr("height", function(d, i) {return (d.y * 5)}) .attr("width", xScale.bandwidth()) .attr("x", function(d, i) {return xScale(d.x)}) .attr("y", function(d, i) {return (height-d.y*5)}); svg.selectAll("text") .data(dataset) .enter() .append("text") .text(function(d) {return d.y}) .attr("class", "text") .attr("x", function(d, i) {return xScale(d.x) +25}) .attr("y", function(d, i) {return height-d.y*5 + 15}); svg.append("g") .attr("transform", "translate(0," + (height) + ")") .call(d3.axisBottom(xScale)); </script> | cs |
[line 33 ~ 35].
눈금을 표시하기 위한 X축 스케일 설정이다.
domain에 지정하는 데이터 값이
연속된 값이면 시작값과 종료값(최대값)을 지정하면 된다.
여기서는 A, B, C 등의 문자열이기 때문에
배열(dataset)에 사용된 값 모두를 나열하여(map) 지정하였다.
range의 화면 범위를 지정하기 위해
SVG의 CSS width값을 구해서 지정하였다 (svg.style("width")).
[line 43 ~ 44].
바를 생성하면서(append("rect"))
바의 크기(attr-width)와 위치(attr-x)를 척도를 이용해서 지정한다.
이렇게 척도를 이용하여 차트의 크기(SVG)나
입력되는 데이터의 개수에 따라 적절한 도형(rect)이 생성되게 된다.
배열 개수를 바꿔서 확인 할 수 있다.
즉, SVG에 맞춰서 적절하게 도형이 생성됨.
[line 56 ~ 58].
마지막으로 척도를 이용하여 축(axis)을 작성한다.
X축이니 화면(SVG) 바닥(bottom)에 놓고
위치는 화면의 높이(height = Height-20)가 된다.(눈금자위치) [line 32].
(height = Height-5) (height = Height-20)
height에 20px을 뺀 것은 X 축의 값을 출력하는 공간을 계산한 것이다.
즉, translate를 이용하여 X 좌표는 0, Y 좌표는 height인 지점에
라인을 그리고 축의 값(xScale)을 출력한다.
지금까지 사용하지 않은 그룹 개념이 사용되었다 (svgG.append("g")).
눈금(tick)은 여러 개의 선으로 구성되기 때문이다.
즉, 눈금 개수(tick count) 만큼 SVG 선(Line)이 생성된다.
이것을 간편하게 관리하기 위해 그룹으로 관리한다.
웹 브라우저의 개발자 도구(F12)로 확인하면
SVG group (X축)에 여러 개의 눈금(Line)이 있는 것을 확인할 수 있다.
svg.append("g") .attr("class", "x axis") .attr("transform", "translate(0," + (height) + ")") .call(xAxis);
// g 문서요소 - 그룹을 뜻함. - 다른 문서 요소를 담는 역할. - 트랜스폼 요소 적용 가능. // call 함수 - 선택된 변수의 내용을 불러온다. |
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 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | <!DOCTYPE html> <meta charset="utf-8"> <style> svg { border: 1px solid; } .bar { fill: orange; } .bar:hover { fill: tomato; cursor: pointer; } .text { fill: white; font-weight: bold; } </style> <svg width="500" height="300"></svg> <script src="https://d3js.org/d3.v4.min.js"></script> <script> var dataset = [ {x : 'A', y : 9} , {x : 'B', y : 19} , {x : 'C', y : 29} , {x : 'D', y : 39} , {x : 'E', y : 29} , {x : 'F', y : 19} , {x : 'G', y : 9}]; var svg = d3.select("svg"); var width = parseInt(svg.style("width"), 10) -30; var height = parseInt(svg.style("height"), 10) -20; var svgG = svg.append("g") .attr("transform", "translate(30, 0)"); var xScale = d3.scaleBand() .domain(dataset.map(function(d) { return d.x;} )) .range([0, width]).padding(0.2); var yScale = d3.scaleLinear() .domain([0, d3.max(dataset, function(d){ return d.y; })]) .range([height, 0]); svgG.selectAll("rect") .data(dataset) .enter() .append("rect") .attr("class", "bar") .attr("height", function(d, i) {return height-yScale(d.y)}) .attr("width", xScale.bandwidth()) .attr("x", function(d, i) {return xScale(d.x)}) .attr("y", function(d, i) {return yScale(d.y)}); svgG.selectAll("text") .data(dataset) .enter() .append("text") .text(function(d) {return d.y}) .attr("class", "text") .attr("x", function(d, i) {return xScale(d.x)+xScale.bandwidth()/2}) .style("text-anchor", "middle") .attr("y", function(d, i) {return yScale(d.y) + 15}); svgG.append("g") .attr("transform", "translate(0," + (height) + ")") .call(d3.axisBottom(xScale)); svgG.append("g") .call(d3.axisLeft(yScale) .ticks(5)); </script> | cs |
// 눈금을 표시하기 위한 스케일 설정 var yScale = d3.scale.linear() // 스케일 설정 .domain([ 0, dataMax ]) // 원래크기 .range([ dataMax, 0 ]) // 실제 출력 크기 |
.ticks(5); - 축의 눈금 개수 지정 - 개수에 따라 눈금값이 정확히 떨어지지 않으면 입력한 눈금개수 중 값이 정확히 떨어지는 개수로 자동으로 조정해서 보여줌. |
[line 58 ~ 59]
추가로 차트에 출력된 값을 보면 앞 차트와 다른 점이 있다.
숫자가 bar(도형)의 정중앙에 출력된다.
(이전 예제는 19, 29와 같은 두자리 숫자와 9와 같은 한자리 숫자의 출력 좌표가 조금 안 맞다)
이전 예제는 도형의 중앙을 계산하기 어려웠지만
척도를 이용하여 간단하게 계산할 수 있다.
도형을 출력할 좌표(xScale)에 도형 크기(width)의 반(/2)을 더해주면
숫자가 찍힐 정확한 중앙 지점을 계산할 수 있다.
(위 코드에서 파란색으로 표시된 코드를 의미한다.)
SVG의 Text 테그의 text-anchor 스타일을 middle로 지정하면
지정된 좌표가 문자열의 중앙에 오도록 출력해 준다.
<before> <after>
척도를 이용함으로써
다양한 데이터에 유동적으로 반응하는 결과를 만들 수 있다.'D3.js' 카테고리의 다른 글
06 라인 차트(Line Chart) - 툴팁(Tooltip), 꺾은선(Curve Line) (0) | 2018.06.11 |
---|---|
05 라인 차트(Line Chart) (0) | 2018.06.05 |
04 툴팁(Tooltip) (2) | 2018.06.04 |
03 그리드(Grid) (0) | 2018.06.01 |
01 간단한 도형 차트(Bar Chart) 만들기 (1) | 2018.05.25 |