관리 메뉴

HAMA 블로그

d3.js 실시간 스트리밍 그래프 예제&설명 본문

데이터 가시화 (d3.js , Plotly, Grafana, Kibana 등)

d3.js 실시간 스트리밍 그래프 예제&설명

[하마] 이승현 (wowlsh93@gmail.com) 2015. 7. 20. 17:25


사물인터넷을 위한 관제 웹 어플리케이션에서 현재 전기/수도의 사용량을 그래프로 보여주고 싶어서 알아보던중

d3 라이브러리를 알게되어 간단히 적용해보고 (10분 완성) 주석 형식으로 설명을 달아본다. 



0. 적용 모습 





1. d3 라이브러리 include 





2. 웹 페이지에서 그래프가 위치 할만한곳에 div 설정 



3. 웹 페이지 로딩이 끝나면 그래프 시작




4. 그래프 드로잉 부분 


var current_watt_for_graph = 0;


function graphStart(){


    var n = 60,    // x 축 범위를 위한 변수 

   random = d3.random.normal(0, 0), 

   data = d3.range(n).map(random);   // 0~0 으로 x축(60) 범위를 초기화 한다. 


var margin = {top: 20, right: 20, bottom: 20, left: 40},    // 그래프 상하좌우 공백

   width = 500 - margin.left - margin.right,                      // 그래프 x 크기

   height = 280 - margin.top - margin.bottom;                 // 그래프 y 크기 


var x = d3.scale.linear()              // 그래프의 너비에 맞추어 x  축을 0~59로 나눈다.

   .domain([0, n - 1])

   .range([0, width]);


var y = d3.scale.linear()             // 그래프의 높이에 맞추어 0~100으로 나눈다.

   .domain([0, 100])

   .range([height, 0]);


var line = d3.svg.line()               // svg 라인이 설정되는(그려지는) 방법을 알려준다. 

   .x(function(d, i) { return x(i); })

   .y(function(d, i) { return y(d); });

 

   // div id 가 "graph_pane" 인것에 svg 형식의 그래프 그려준다.

var svg = d3.select("#graph_pane").append("svg")    

   .attr("width", width + margin.left + margin.right)       // 너비 설정

   .attr("height", height + margin.top + margin.bottom) // 높이 설정

 .append("g")                                                             //  그룹 "g"  속성  추가 

   .attr("transform", "translate(" + margin.left + "," + margin.top + ")");  // 변환(transform) 속성 설정 


svg.style("fill", "#fff8ee")    // 그래프 색상 설정 


svg.append("defs").append("clipPath")   // clipPath  설정 (보여지길 원하는 사이즈 설정, 이외는 버림) 

   .attr("id", "clip")

 .append("rect")  // rect 설정 

   .attr("width", width)

   .attr("height", height);


svg.append("g")   // x 축에 대한 그룹 엘리먼트 설정 

   .attr("class", "x axis")

   .attr("transform", "translate(0," + y(0) + ")")

   .call(d3.svg.axis().scale(x).orient("bottom"));


svg.append("g")  // y 축에 대한 그룹 엘리먼트 설정 

   .attr("class", "y axis")

   .call(d3.svg.axis().scale(y).orient("left"));


var path = svg.append("g") 

   .attr("clip-path", "url(#clip)")

 .append("path")    // 실제 데이터가 그려질 패스에 대한 설정 

   .datum(data)

   .attr("class", "line")

   .attr("d", line);



  path    // 실제 데이터가 그려질 패스에 대한 스타일 설정 

        .style('stroke-width', 1)

        .style('stroke', 'yellow');


tick();  


function tick() {


 // 새로운 데이터를 뒤에 추가한다. (ajax 를 통해 1초에 한번씩 가장 최신 데이터를 가져온것을 넣어줌)

 data.push(current_watt_for_graph);


 // 라인을 PATH 방식으로 그리자!!!   

 path

     .attr("d", line)

     .attr("transform", null)    // 기존 변환 행렬을 초기화하고  

     .transition()                 // 변환 시작

     .duration(1000)          // 1초동안 애니매이션하게 설정

     .ease("linear")           // ease 보간을 리니어로 처리한다.(https://github.com/mbostock/d3/wiki/Transitions#d3_ease)

     .attr("transform", "translate(" + x(-1) + ",0)")   //  변환행렬 설정   # 패스를 다시 그리는 방식이                                                                                     //  라 좌표를 변환함으로써 출렁거리는것을 막는다. 

     .each("end", tick);    //tick 함수 계속 호출 

 

 //가장 오래된 데이터를 제거한다.

 data.shift();


}

}




5. Ajax 를 통해 서버에서 데이터 가져오기 


var graph_timer = null;

var graph_time_interval = 1000;  // 1 초에 한번 꼴로 데이터 폴링 

function graph_loading()

{

clearInterval(graph_timer);

{

// ajax 로  가장 최근 데이터 1개 가져와서

$.get("cmp_test_watt.jsp", function(data, status){

if (status == "success")

{

console.info(data);

var jsonObj = $.parseJSON(data);

console.info(jsonObj.watt);

current_watt_for_graph = jsonObj.watt;  //  최근 watt 정보 대입

}

else

{

console.info("error");

}

});

}

graph_timer = setInterval(graph_loading, graph_time_interval);

}



SVG 클리핑 패스란 ? 

The clipping path restricts the region to which paint can be applied. Conceptually, any parts of the drawing that lie outside of the region bounded by the currently active clipping path are not drawn.

A clipping path is defined with a clipPath element. A clipping path is used/referenced using the clip-path property.


SVG <g/> 엘리먼트란?  (https://www.dashingd3js.com/svg-group-element-and-d3js)

The SVG Group Element is used to group SVG elements together.

The SVG Group Element is a container that contains all child SVG elements defined inside of it.

The SVG Group Element is defined by <g> and </g>.

The SVG Group Element can be nested inside of other SVG Group Elements:


d3 Transitions

http://bost.ocks.org/mike/transition/




레퍼런스:

https://gist.github.com/mbostock/1642874     





Comments