d3.js 사용법 - ② bar chart 그리기
d3.js 를 사용하여 막대그래프(bar chart)를 그려보기 전에 , 기초 세팅을 해야함
기초 세팅은 아래 포스팅에서 확인가능
d3.js 사용법 - ① 개념 및 초기세팅 (tistory.com)
d3.js 사용법 - ① 개념 및 초기세팅
Data - Driven Documents. JavaScript 데이터 중심의 문서 (Data - Driven Documents)의 약자로 자바스크립트 기반의 라이브러리 언어 웹브라우저 상에서 동적인 정보시각화를 구현하기 위한 자바스크립트 라이
tjqud531531.tistory.com
그리드와 차트를 그릴때 사용한 데이터
1. 데이터 세팅
차트를 불러오기전에 Jgrid 와 마찬가지고 데이터를 먼저 불러와야한다.
ajax를 통해 컨트롤러에서 json데이터를 불러오고, DB에서 불러드린 데이터를 getData라는 변수에 담아 사용
drawChart1()이라는 함수를 호출 . 실행함수를 빠져나와 drawChart1이라는 이름을 가진 함수를 만들어주자
데이터를 가지고 올 getData와 이후 버튼 이벤트 추가를 고려하여 type을 변수에 넣어줌
2. html에 차트가 들어갈 공간 만들어주기
3. d3.js chart 그리기
function drawChart1(getData,type){
// 순서대로 척도만들고, 축도 생성해주기
if(!type){
chartHeight = 500 // 차트의 전체 높이
chartWidth = 500 // 차트의 전제 너비
// de.select함수를 이용해 차트가 만들어질 공간의 아이디 선택
// 아이디에 svg라는 공간 확보 후 높이와 넓이 속성 추가
chartSvg = d3.select("#yerin-chart")
.append("svg")
.attr("height",500).attr("width",500)
.attr("id","svg1")
// 척도 만들기
// Y축은 숫자가 증가하는 선형모양 - linear함수사용
// X축은 문자가 증가하는 모양 - ordinal 함수 사용
// Domain(실제값의 array), range(픽셀값)
Yscale = d3.scale.linear().domain([0,40]).range([470,30])
Xscale = d3.scale.ordinal()
.domain(["A","B","C","D","E","F","G","H","I","J"])
.rangeBands([30,470]);
// 축만들기
// 위에 만들어 놓은 svg호출 후 axis()함수 호출
// 축의 방향을 정하는 orient 태그를 활용 하여 축의 위치 정하기
Yaxis = d3.svg.axis().scale(Yscale).orient("left")
Xaxis = d3.svg.axis().scale(Xscale).orient("bottom")
// 만들어진 svg 공간에 'g'공간을 추가한 후 이 공간 안에 축을 그리는 axis를 불러온다.
chartSvg.append("g").call(Yaxis)
.attr("transform","translate(30,0)")
.attr("class","axis")
chartSvg.append("g").call(Xaxis)
.attr("transform","translate(0,470)")
.attr("class","axis")
}
}
* Yscale 에는 domain은 범위를 쓰고, Xscale에는 하나하나 넣어주는 이유
- Y축에 들어갈 숫자는 범위로 쓰는게 가능하지만 X축에 들어가는 글자는 따로따로 다 써줘야함 (글자는 범위를 지정하
기가 애매하기 때문
* domain과 range의 정확한 차이
- 지도를 생각했을때 우린 축적을 계산하여 엄청나게 큰 지구를 작게 축소시켜 나타낸다 차트도 데이터 값이 어떨지 모
르므로 사용자가 봤을때 한눈에 보이도록 다 담아야한다
- 따라서 실제 값을 domain에 써주고, 사용자가 인식하는 픽셀값은 range에 해당한다고 이해하면 된다
* Yscale 에는 range를 쓰고, Xscale에는 rangeBands를 쓰는 이유
- scale은 말그대로 축적을 얘기 하는 것. 숫자로 표현된 Yscale은 range또한 범위로 지정하기가 쉽지만 Xscale은
문자가 들어가게 됨. 그럼 그 문자열을 하나하나 위치 지정을 해주어야 하지만 이 행동이 귀찮기 때문에 자동으로
width검사를 해서 글자 사이의 간격을 맞추는 아이가 rangeBands임
3. 만들어놓은 차트의 틀 내부에 데이터 집어 넣기
* 위에서 만들어 놓은건 말그대로 데이터가 들어가기 전의 차트의 공간만 확보해놓은 상황
* 만들어 놓은 공간에 데이터를 집어 넣어 보자
//위에 만들어 놓은 drawChart() 코드에 이어서 바로 쓰면됨
// 데이터가 들어갈 공간을 'g'=group 속성으로 만든 뒤 dataSvg 변수에 넣기
// 앞으로 var1과 var2 두가지의 변수가 들어갈 것이기 때문에 if문으로 type구분
// 데이터를 하나만 넣고 싶다면 이렇게 만들 필요 없음
dataSvg = chartSvg.append("g").attr("class","datasvg");
if(type=="var1"){
// 데이터를 집어 넣는 부분
dataSvg.selectAll("rect").data(getData).enter().append("rect")
.attr("x", function(d){return Xscale(d.group)})
.attr("y", function(d){return Yscale(d.var1)})
.attr("width",30)
.attr("height", function(d){return chartHeight-Yscale(d.var1)-30})
.attr("transform","translate(7,0)")
.style("fill","#687F8F").attr("id","var1")
}else if(type=="var2"){
dataSvg.selectAll("rect").data(getData).enter().append("rect")
.attr("x", function(d){return Xscale(d.group)})
.attr("y", function(d){return Yscale(d.var2)})
.attr("width",30)
.attr("height", function(d){return chartHeight-Yscale(d.var2)-30})
.attr("transform","translate(7,0)")
.style("fill","#687F8F").attr("id","var2")
}
*소스 분석하기
* 우리는 아직까지 rect라는 공간을 만든적이 없음. 하지만 데이터가 들어가 있어야 rect를 생성할 수 있음
* 다시 말해 실제로는 만들어지지 않았지만 임의로 rect라는아이를 집어내야한다는 뜻 따라서
* selectAll("rect") - 임의로 rect라는 요소들을 모두 선택
* .data(getData).enter() 임의 rect에 data를 집어 넣음 (하지만 실제 rect가 만들어지기 전이므로 이 또한 임의적인 행동)
* .append("rect") - 실제로 rect를 만드는 부분
* .attr("x", function(d){return Xscale(d.group)}) 콜백 함수를 통해 x축에 위에서 만들어 놓은 X축의 틀을 집어 넣는 과
정 (group에 해당되는 변수를 x축의 틀에 담아 실제 x축 데이터로 집어넣어라)
* .attr("y", function(d){return Yscale(d.var1)}) 위와 동일. y축에는 var1의 값들이 들어갈 것
* attr("width",15) 생성할 차트의 막대 너비
* attr("height",function(d){return chartHeight-Yscale(d.var1)-30}) : 좌표 [0,0] 기준 화면상 왼쪽 맨 위끝임. chart는
저 0,0 좌표를 기준으로 생성되다보니 막대그래프의 시작점은 0,0이 되어버림. 즉 그래프가 위에서 부터 생성됨
* 아래 포스팅에 bar chart의 높이 및 모양을 설정하는 부분만 따로 빼서 설명해 놨으니 이해가 되지 않으면 한번 보기
d3.js 막대그래프 높이 및 위치 설정 (tistory.com)
d3.js 막대그래프 높이 및 위치 설정
d3.js를 이용하여 막대 그래프를 그릴 때 그래프가 아래서부터 그려지는 것이 아닌 위에서부터 그려지는 경우가 있다 이 부분을 해결하기 위해선 (전체 높이-넣고자 하는 데이터 값) 계산을 해야
tjqud531531.tistory.com
4. 데이터를 집어넣은 drawChart()를 실행함수에서 호출시켜주면 끝 (우린 이미 1번 과정에서 drawChart(getData)로 호
출 시켜놨음
[위를 다 적용시킨 전체 drawChart 소스]
function drawChart1(getData,type){
if(!type){
chartHeight = 500
chartWidth = 500
chartSvg = d3.select("#yerin-chart").append("svg")
.attr("height",500).attr("width",500)
.attr("id","svg1")
Yscale = d3.scale.linear().domain([0,40]).range([470,30])
Xscale = d3.scale.ordinal()
.domain(["A","B","C","D","E","F","G","H","I","J"])
.rangeBands([30,470]);
Yaxis = d3.svg.axis().scale(Yscale).orient("left")
Xaxis = d3.svg.axis().scale(Xscale).orient("bottom")
chartSvg.append("g").call(Yaxis)
.attr("transform","translate(30,0)")
.attr("class","axis")
chartSvg.append("g").call(Xaxis)
.attr("transform","translate(0,470)")
.attr("class","axis")
}
dataSvg = chartSvg.append("g").attr("class","datasvg");
if(type=="var1"){
dataSvg.selectAll("rect").data(getData).enter().append("rect")
.attr("x", function(d){return Xscale(d.group)})
.attr("y", function(d){return Yscale(d.var1)})
.attr("width",30)
.attr("height", function(d){return chartHeight-Yscale(d.var1)-30})
.attr("transform","translate(7,0)")
.style("fill","#687F8F")
.attr("id","var1")
}else if(type=="var2"){
dataSvg.selectAll("rect").data(getData).enter().append("rect")
.attr("x", function(d){return Xscale(d.group)})
.attr("y", function(d){return Yscale(d.var2)})
.attr("width",30)
.attr("height", function(d){return chartHeight-Yscale(d.var2)-30})
.attr("transform","translate(7,0)")
.style("fill","#687F8F").attr("id","var2")
}
}
다음 포스팅에선 기본으로 그려놓은 차트를 가지고 여러가지 이벤트를 추가해 볼 예정