본문 바로가기

Javascript, jQuery

[DC.js] bar Chart 사용법 정리 및 설명

반응형

 

1. CDN 삽입

<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>

<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crossfilter/1.3.12/crossfilter.min.js" integrity="sha512-nlO6OGj6wb0uu/thpSry7qFal63hfhCLExpWxYomYB3tBznqWmKggsDHNHSLjnVaoade9tv/rErN498NSzwBnA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src = "https://unpkg.com/dc@4/dist/dc.js"></script>
<link rel = "stylesheet" href="https://unpkg.com/dc@4/dist/style/dc.css">

 

jQuery, dc.js, crossfilter CDN 다운

 

 

 

2. barChart 객체 생성

var chart = dc.barChart("#test");

바 차트를 그려주는 barChart 객체를 생성 후 id="test"인 요소에 해당 차트를 생성해준다는 명령입니다.

 

 

 

 

3. 데이터를 crossfilter로!

Crossfilter is a library for multidimensional filtering and aggregation of tabular data.  

Crossfilter는 데이터를 다차원으로 바꾸어주고 테이블형식으로 데이터를 통합해주는 자바스크립트 라이브러리입니다.

 

var ndx = crossfilter(testdata),

저는 testdata를 컨트롤러에서 넘겨준 2차원 json형식의 데이터로 지정했습니다. 

CSV파일을 지정해 데이터를 뽑아오는 것도 가능합니다.

데이터를 차트로 만들기 위해 차원을 만들어 주는 등 구조화를 시켜주는 역할이라고 보시면 됩니다.

 

https://square.github.io/crossfilter/

 

Crossfilter

Crossfilter Fast Multidimensional Filtering for Coordinated Views Status Crossfilter is not under active development, maintenance or support by Square, its original author Mike Bostock, or the recent contributors (Jason Davies, Tom Carden). We still welcom

square.github.io

공식 홈페이지와 사용법을 담은 API 레퍼런스를 참고하시기 바랍니다.

 

 

 

 

 

3. Dimension (차원) 설정

"우리는 3차원 세계에 살고 있다." 라는 명제가 있죠? 우리가 3차원세계에 발을 딛고 서있다는 뜻입니다.

이처럼 Dimension, 즉 차원은 데이터가 서있는 곳을 뜻합니다.

시간-속력 2차 곡선 그래프에서는 시간이 Dimension이 됩니다. 시간은 변하지 않고 항상 그 자리에 그대로 있고 속력이 시간에 따라 변합니다. 변하지 않는 값인 시간을 Dimension으로 두고 속력이 서있는 것이죠!

 

바그래프를 그리기 위해서는 x축이 될 Dimension을 지정해줘야 합니다.

testdata.forEach(function (d) {
	d.date = new Date(d.date);
}); 

var ndx = crossfilter(testdata);
var dateDim = ndx.dimension(function (d){return d3.timeHour(d.date);});

crossfilter처리를 한 testdata값에서 Dimension을 지정합니다.

저는 날짜와 시간데이터에 따른 값의 변화를 볼 예정이기 때문에 데이터의 'date' 컬럼을 활용해 차원(x축)을 만들어주었습니다.

 

testdata의 date컬럼에는 PHP 날짜 형식인 'yyyy-mm-dd hh:mm:ss' 포맷대로 날짜와 형식이 저장되어 있습니다. 

이를 자바스크립트에서 활용하기 위해 모든 값을 new Date로 Date객체를 생성해주는 forEach문을 한번 돌려준 후,

d3의 timeHour를 활용하여 시간을 단위로 x축에서 사용할 dimension을 만들어줍니다.

 

 

 

4. group 설정

바 그래프에서는 앞에서 설정한 차원에 따른 group을 설정해주어야합니다.

이 그래프에서는 경남, 경북, 전북, 전남의 지명이 Dimension이네요. 이제 해당 지역에 살고있는 인구 수를 집계하여 값을 y축으로 보여주게 되는데요,

Dimension에 따라 group을 지정한다는 것이 이 뜻입니다. 거제, 통영, 진주 등등 경남에 속한 모든 행정구역의 인구수를 '경남'이라는 하나의 기준으로 묶어 다 더해 보여주기 때문에 행정구역 '도'로 grouping을 했다고 볼 수 있는 것이죠!

 

var cntDim = ndx.dimension(function (d){return +d.cnt;})
cntGroup = cntDim.group()
dateGroup = dateDim.group().reduceSum(d => d.cnt)

 

각 시간별로 카운팅된 개수를 보여주는 cnt컬럼을 y축을 위한 dimension으로 만들고 group으로 묶었습니다.

그리고 reduceSum을 이용해 한시간당 cnt의 총합을 구해 dateGroup 변수에 넣어줍니다.

 

 

 

5. 차트 설정

chart
    .width(768)
    .height(480)
    .dimension(dateDim)
    .group(dateGroup)
    .x(d3.scaleTime()) 
    .xUnits(d3.timeHours)
    .clipPadding(10)
    .elasticX(true)
    .elasticY(true);

dc.renderAll();

차트의 레이아웃을 결정합니다.

  • .width(768) .height(480) -> 너비 768, 높이 480
  • .dimension(dateDim) -> 위에서 지정한 dimension 지정
  • .group(dateGroup) -> 위에서 지정한 group 지정
  • .x(d3.scaleTime()) -> scale에 대한 설명은 밑에서 계속 진행하도록 하겠습니다.
  • .xUnits(d3.timeHours) -> x축의 단위를 d3.timeHours라고 지정
  • .elasticX(true) , .elasticY(true) -> X축과 Y축을 가진 값에 맞게 신축적으로 조정합니다.
  • dc.renderAll(); -> 설정한 차트의 세부사항들을 담아 차트를 그려줍니다.
     
더보기

scale??

 

'스케일이 작다 또는 크다.' 라는 말, 많이 들어보셨죠??

여기서 생각해볼 점은 여기서 사용하는 스케일이라는 말이 상대적인 수치라는 점입니다.

월 200만원을 버는 주갬의 통장에서 월 100만원의 투자는 '스케일이 큰' 투자지만

정부 예산에서 월 100만원의 투자는 '스케일이 큰' 투자일까요?

 

이렇게 얘기해보면 어떨까요?

'주갬은 월급의 50%정도의 '스케일이 큰' 투자를 하고 있습니다.'

'정부는 예산의 50%정도를 할당해 '스케일이 큰' 투자를 하고 있습니다.'

 

느낌 가져가셨나요? :)

 

차트로 시각화를 하는 이유는 각자 제각각 가지고 있는 수의 범위를 한 눈에 쏙들어오는 범위로 축소하여 예쁘게 보여주기 때문입니다. 월 200을 버는 주갬의 월급사용현황을 담은 원형차트도, 정부의 예산활용현황을 담은 원형차트도 가로세로 300px안에서 한눈에 확인할 수 있도록 하는게 차트의 역할, 그리고 scale의 역할입니다.

 

d3의 scale함수는 차트를 본격적으로 그리기 전에 받아온 데이터를 x축에 구겨넣기 위해 다른 범위의 숫자로 변경해주는 함수입니다.  0~ 200의 수의 범위가 있다면 x축의 가운데에 100이 위치할 수 있게 50%로 만들어주는 역할을 합니다.

 

  • d3.scaleLinear()
  • d3.scalePower()
  • d3.scaleLog()
  • d3.scaleIdentity()
  • d3.scaleTime()

종류는 다음과 같습니다. 저는 여기서 시간에 관련된 값을 받아 자동으로 시간을 단위로 scaling 해주는 d3.scaleTime()을 사용했습니다.

 

 

 


차트 부분 전체 코드를 공유합니다.

function drawchart(data) {
	var testdata = data['mydata'];
	console.log(data)
	
	testdata.forEach(function (d) {
        d.date = new Date(d.date);
    }); 

	var chart = dc.barChart("#test");

	var ndx = crossfilter(testdata);
	var cntDim = ndx.dimension(function (d){return +d.cnt;})
    console.log(cntDim.top(Infinity)) 
    //this prints out the entire data1 json in the console 
    var dateDim = ndx.dimension(function (d){return d3.timeHour(d.date);});     

	//Define the Group elements 
    cntGroup = cntDim.group()
    dateGroup = dateDim.group().reduceSum(d => d.cnt)
    console.log(cntDim)
    console.log(dateGroup)

    function render_plots(){
 
    chart
        .width(768)
        .height(480)
        .x(d3.scaleTime()) //this defines a range of 0 to 200
        .xUnits(d3.timeHours)
        // but we use elasticX so its not really relevant 
        .clipPadding(10)
        .elasticX(true)
        .elasticY(true)
        .dimension(dateDim)
        .group(dateGroup);

    dc.renderAll();
    }

render_plots();

 

dc.js 공식 홈페이지에 있는 jsfiddle을 참고했습니다.

https://jsfiddle.net/gordonwoodhull/2cLbd9ry/15/

 

Edit fiddle - JSFiddle - Code Playground

 

jsfiddle.net

 

 

실행화면 입니다.

 

 

 


 

 

저도 공부하는 중이라 설명이 미숙할 수 있지만, DC.js 자체가 한글 문서가 턱없이 적은 만큼 여러분들께 도움이 되었으면 좋겠습니다.

 

DC.js에 대한 지식이 더 쌓인 후에 내용도 더 보강하고 새로운 내용으로 게시글도 더 작성해볼 생각입니다.

 

어려운 내용 따라오시느라 고생 많으셨습니다 :) 

 

반응형