'd3.js'에 해당하는 글 5건

Naver Maps + D3.js

d3.js 2014.02.18 14:15

지난 Google Map + D3.js에 이어 Naver Maps API를 이용하여 Naver Map과 D3.js를 연동해보자.


우선 Naver Map 객체를 생성한다.

Naver Map도 Google Map과 마찬가지로 MapOption 줌레벨, 지도유형 등을 세팅 가능하다.

자세한 사항은 여기를 참고하기 바란다.

var map = new nhn.api.map.Map('map' ,{
	point : new nhn.api.map.LatLng(37.556059, 126.91009),
	zoom : 8,
	enableWheelZoom : true,
	enableDragPan : true,
	enableDblClickZoom : false,
	mapMode : 0,
	activateTrafficMap : false,
	activateBicycleMap : false,
	minMaxLevel : [ 1, 14 ],
	size : new nhn.api.map.Size(1300, 600)
});

Map상에 표시할 정보로는 서울 열린 데이터 광장에서 서울시 도서관정보를 가져왔다.

해당 데이터는 도서관 위치정보(위도/경도), 면적, 주소, 전화번호의 컬럼으로 구성되어있다. 

var data = [{"OBJECTID":"21","GU_NM":"구로구","HNR_NAM":"구로3동","MTC_AT":"1","MASTERNO":"777","SLAVENO":"1","NEADRES_NM":"구로구 디지털로 27다길 65 2층","FCLTY_NM":"꿈마을 도서관","ORN_ORG":"구로구 시설관리공단","EBT_MAN":" ","FLY_GBN":"구립도서관","OPNNG_DE":"2007-04-05","AR":"476","HMPG_CN":"lib.guro.go.kr/dreamtown/","CTTPC_CN":"830-5807","CREAT_DE":" ","LNG":"126.8901147","LAT":"37.4872202"}, /*생략*/];

서울시 도서관정보에서 위도/경도(LNG/LAT)를 위용하여 Naver Map에 D3.js를 이용하여 circle를 표시하고자 한다. Naver Map API에서는 기본적으로 nhn.api.map.Circle를 제공한다. 여기서는 nhn.api.map.Circle를 사용하지 않고 D3.js로 직접 랜더링 해볼 것이다. circle의 사이즈는 도서관 면적(AR)을 중심점은 위도/경도를 이용할 것 이다.

var color = d3.scale.category10();
var radius = d3.scale.linear().domain([0, 3000]).range([10, 50]);

서울시 구별로 색상을 달리하기위한 color함수와 도서관 면적 사이즈를 적용하기 위한 radius함수를 정의하였다.

radius함수에서 domain은 도서관 면적의 min/max값이며 range는 10~50으로 설정하였다.

var layer = d3.select('.nmap_drawing_pane').append("div").attr("class", "library");

도서관 정보를 표시하고자 하는 div element을 nmap_drawing_pane에 append해준다.(nmap_overlay_pane도 가능)


Naver Map Rendering Element


var padding = 50,
	pluspadding = 1;
					
var marker = layer.selectAll("svg")
	.data(d3.entries(data))
	.each(transform)
	.enter().append("svg:svg")
	.each(transform)
	.attr("class", "marker");
					
marker.append("svg:circle")
	.attr("r", function(d){return radius(d.value.AR) >= 50 ? 50 : radius(d.value.AR);})
	.attr("cx", function(d){return padding;})
	.attr("cy", function(d){return padding;})
	.style("fill", function(d,i){return color(d.value.GU_NM);})
	.attr("fill-opacity", "0.7")
	.on("click",function(d){ alert(d.value.FCLTY_NM); map.setCenter(new nhn.api.map.LatLng(d.value.LAT, d.value.LNG)); });
					
marker.append("svg:text")
	.attr("x", function(d){return padding;})
	.attr("y", function(d){return padding;})
	.attr("dy", ".31em").style("text-anchor", "middle")
	.text(function(d) { return d.value.LNG > 0 ? d.value.HNR_NAM : ""; });

여기까지는 특별할게 없다. 서울시 도서관정보를 토대로 D3.js를 이용하여 circle를 랜더링하는 소스이다.

아래 transform 함수에서 서울시 도서관 위치정보를 토대로 Naver Map상에 표시해준다.

function transform(d) {
	var r = radius(d.value.AR) >= 50 ? 50 : radius(d.value.AR);
	LatLng = new nhn.api.map.LatLng(d.value.LAT, d.value.LNG);
						
	var oSize  = new nhn.api.map.Size(28, 37); 
	var oOffset = new nhn.api.map.Size(28, 37); 
	var oIcon  = new nhn.api.map.Icon('http://static.naver.com/maps2/icons/pin_spot2.png', oSize, oOffset); 
					    
	var oMarker = new nhn.api.map.Marker(oIcon, { title : d.value.FCLTY_NM }); 
	oMarker.setPoint(LatLng);
						
	map.addOverlay(oMarker);
	oMarker.setVisible(true);
						
	return d3.select(this)
		.style("left", (parseInt(d3.select(oMarker)[0][0]["_elEl"].style.left)-padding) + "px")
		.style("top", (parseInt(d3.select(oMarker)[0][0]["_elEl"].style.top)-padding) + "px")
		.style("width", (r+padding+pluspadding) + "px")
		.style("height", (r+padding+pluspadding) + "px");
}

이 함수의 역활은 서울시 도서관 위치 정보(위도/경도)를 Naver Map상에 픽셀로 변환된 LEFT, TOP값을 알아내기 위함이다. google map의 경우 projection.fromLatLngToDivPixel() 메서드로 해당 값들을 알아낼 수 있었는데 Naver Map의 경우 내가 잘 모르는건지 해당 값을 리턴해주는 메서드가 없더라... 그래서 위 소스를 보면 Marker의 style정보에서 LEFT, TOP값을 얻어오는 것을 볼 수 있다. 


Marker Rendering Element


위 정보를 얻어와서 circle marker의 Naver Map상의 position left, top설정을 해준다.


D3.js Circle Redering Element


이제 완성된 소스를 실행해보면 아래와 같은 결과를 볼수 있다.


Naver Maps + D3.js Circle

위 Map상에 Naver Map Marker를 없애려면  oMarker.setVisible(false); 로 수정하면 된다.


Naver Map도 Google Map과 마찬가지로 zoom, dragend와 같은 각종 이벤트를 제공한다.

해당 이벤트를 사용하는 방법도 간단하게 살펴보자.

var zoomEvent = function(zoom){
	var defaultBounds = map.getBound();
	var defaultCenter = map.getCenter();
	var defaultLevel = map.getLevel();
	var defaultMapMode = map.getMapMode();
}
					
var dragEvent = function(drag){
	console.log(drag);
}
map.attach("zoom",zoomEvent);
map.attach("dragend",dragEvent);
위 소스를 보면 Naver Map에서 zoom 이벤트가 발생할때 Map상에 줌레벨, 위도/경도 정보를 구할 수 있다. 해당 정보를 이용하여 현재 Map상에 표현할 마커나 차트정보를 서버 측에서 구해와 랜더링 할 수 있을 것이다.


참고자료


'd3.js' 카테고리의 다른 글

Naver Maps + D3.js  (0) 2014.02.18
Google Maps + D3.js  (8) 2014.02.11
bar chart  (4) 2013.09.16
Using D3.js to draw a grid‎  (3) 2013.05.31

WRITTEN BY
빵군
Web Programmer HOONS닷넷(http://www.hoons.kr) 2011 ASP.NET 시삽 http://about.me/y2kpooh

받은 트랙백이 없고 , 댓글이 없습니다.
secret

Google Maps + D3.js

d3.js 2014.02.11 11:08

Google Map위에 D3.js를 이용하여 마커 혹은 차트를 랜더링 하는 방법을 알아보자.


우선 Google Map 객체를 생성해보자.

Google Map 객체는 MapOption 줌레벨, 지도유형 등을 세팅 가능하다.

자세한 사항은 여기를 참고하기 바란다.

var map = new google.maps.Map(d3.select("#map").node(), {
	zoom: 12, 
	center: new google.maps.LatLng(37.556059, 126.91009),
	mapTypeId: google.maps.MapTypeId.ROADMAP
});

여기서는 줌레벨과 초기 지도 센터 위도/경도 정보, 그리고 지도유형을 설정하였다.


이제 지도위에 마커정보(위도/경도)와 오버레이 객체를 생성한다.

지도위에 마커나 차트를 랜더링하기 위해서는 오버레이 객체를 생성해야 한다.

오버레이는 지도 상의 위도/경도 좌표에 연결된 객체를 말한다.

지도를 드래그하거나 확대/축소하면 연결된 오버레이도 함께 움직이며 지도에 '추가'하는 객체를 말한다.

var overlay = new google.maps.OverlayView();
var data = {"우리집":[126.8998768,37.4639925, 15,],"구로디지털단지역":[126.901472,37.48525, 15,2], /*생략*/};

data는 마커용 라벨정보와 위도/경도 정보 마커크기, 그리고 지하철 노선정보가 있다. 이 데이터를 이용하여 D3.js로 Circle를 랜더링할 수 있으며 이 글에서는 해당 정보에서 위도/경도만 사용하여 Pie Chart를 그려보고자 한다.

이제 오버레이에 Pie Chart를 랜더링 해보자.

overlay.onAdd = function() {
	var layer = d3.select(this.getPanes().overlayMouseTarget).append("div").attr("class", "stations");
		
	overlay.draw = function() {
		var projection = this.getProjection(), padding = 50;

여기까지 코드를 살펴보면 지도에 오버레이 랜더링할 준비가 되었을 경우(onAdd) stations div를 추가하고

오버레이에 초기 랜더링(draw)해준다. getProjection()은 Map상에 표시할 좌표를 계산하기 위한 메소드이다.

여기서 중요한건 overlayMouseTarget이다. 마커나 차트에 이벤트 바인딩을 하려면 해당 속성을 지정해줘야 한다.


이제 실제 마커할 D3.js소스를 추가해보자. 여기서 Pie Chart는 NVD3.js 라이브러리를 사용하였다.

		var marker = layer.selectAll("svg")
			.data(d3.entries(data))
			.each(transform)
			.enter().append("svg:svg")
			.each(transform)
			.attr("class", "marker");

		var pieData = [{"key": "One","value" : 29.765957771107} , {"key": "Two","value" : 10} ,{"key": "Three","value" : 32.807804682612} , {"key": "Four","value" : 196.45946739256}];

		nv.addGraph(function() {
			var chart = nv.models.pieChart()
				.x(function(d) { return d.key; })
				.y(function(d) { return d.value; })
				.margin({top: 0, right: 0, bottom: 0, left: 0})
				.showLabels(true)
				.labelThreshold(.05)
				.donut(true)
				.showLegend(false);
						  
			marker.datum(pieData).transition().duration(1200).call(chart);

			return chart;
		});
		function transform(d) {
			d = new google.maps.LatLng(d.value[1], d.value[0]);
			d = projection.fromLatLngToDivPixel(d);
			return d3.select(this)
				.style("left", (d.x-padding) + "px")
				.style("top", (d.y-padding) + "px");
		}
	}; //overlay.draw end
}; //overlay.onAdd end
overlay.setMap(map);

2번 라인 d3.entries(data)으로 data를 key, value로 변경해준다.

[{"key":"우리집","value":[126.8998768,37.4639925,15]},{"key":"구로디지털단지역","value":[126.901472,37.48525,15,2]}];

3번 라인에서 data 갯수만큼 each 메소드이용하여 24-30라인의 transform함수를 호출한다.

transform함수의 역활은 Map상에서 실제 마커될 Pie Chart의 픽셀 위치를 위도/경도를 이용하여 세팅해준다.


1-6라인으로 생성된 Element


8번 라인은 Pie Chart의 Data이다. 10-23라인은 NVD3.js를 이용한 Pie Chart를 추가해준다.


Google Maps + Pie Chart


Google Map은 zoom_changed, dragend와 같은 각종 이벤트를 제공한다.

해당 이벤트를 사용하는 방법도 간단하게 살펴보자.

google.maps.event.addListener(map, 'zoom_changed', function() {
	var zoomLevel = map.getZoom();
	var lat_south = map.getBounds().getSouthWest().lat();
	var lat_north = map.getBounds().getNorthEast().lat();
	var lng_west = map.getBounds().getSouthWest().lng();
	var lng_east = map.getBounds().getNorthEast().lng();
	var lat_center = map.getCenter().lat();
	var lng_center = map.getCenter().lng();
});

위 소스를 보면 Google Map에서 zoom_charged 이벤트가 발생할때 Map상에 줌레벨, 위도/경도 정보를 구할 수 있다.

해당 정보를 이용하여 현재 Map상에 표현할 마커나 차트정보를 서버 측에서 구해와 랜더링 할 수 있을 것이다.


서울시 도서관정보 마커



참고자료




'd3.js' 카테고리의 다른 글

Naver Maps + D3.js  (0) 2014.02.18
Google Maps + D3.js  (8) 2014.02.11
bar chart  (4) 2013.09.16
Using D3.js to draw a grid‎  (3) 2013.05.31

WRITTEN BY
빵군
Web Programmer HOONS닷넷(http://www.hoons.kr) 2011 ASP.NET 시삽 http://about.me/y2kpooh

받은 트랙백이 없고 , 댓글  8개가 달렸습니다.
  1. 안녕하세요! 궁금한것이 있어서 문의드립니다. 구글맵으로 자료를 불러온 후에 특정 구간 몰려있으면 자동으로 Cluster로 만들고 싶은데요, 혹시 이런 기능을 구현하는 것이 가능할까요?
    • d3만 가지고 하기에는 좀 어려울 것 같습니다. 비슷한 예제를 보기는 했는데 소스분석해서 적용하기가 어려울 겁니다.
      보다 쉬운 방법은 서버에서 zoom이벤트 발생 시 해당 영역에 대하여 계산을 해서 내려주는 방식이 더 쉬울 것같네요.

  2. 음, 그렇다면 다른 질문인데요, 지도 상에 100개의 점이 찍혀있을경우, 각 점에서 가장 가까운 점을 찾을 수 있을까요?
    • 클러스터링 알고리즘을 얘기하시는군요.
      여기 비슷한 내용이 있네요. https://www.youtube.com/watch?v=Z0PpaI0UlkE
  3. 아 안돌아가요 아 ㅠㅠ
    data에 설정된 위치대로 들어가지도 않고..

    {"우리집":[126.8998768,37.4639925, 15,],"구로디지털단지역":[126.901472,37.48525, 15,2], /*생략*/};

    []에서 첫 두개 인자는 좌표고, 그 이후에 15, 2는 뭔지 이해가 안가네요 흐아..
  4. Db에서 가져온 데이터를 Data에 넣고 좌표를 찾았는데 pidata에 값을 넣기위해 marker.append(function(d) { 안에 piedata를 넣어봤습니다 그런데 Uncaught TypeError Failed to execute appendchild on Node : parameter 1 is not of type Node 라고 뜨는데요~
    function(d) 없이도 위에 예제처럼 piedata 를 넣을 수 있을까요?
    • 샘플 데이터 형태가 달라 생기는 문제로 보입니다.

      var data = {"우리집":[126.8998768,37.4639925, 15,],"구로디지털단지역":[126.901472,37.48525, 15,2], /*생략*/};

secret

bar chart

d3.js 2013.09.16 11:29

d3.js를 이용하여 기본적인 Bar Chart를 생성해보자.

Bar Chart 형태는 유명한 dc.js의 Sample 내의 Bar Chart를 생성 해보려고 한다.



필요한 데이터로는 x축은 날짜가 필요하며 y축은 수치 즉 numeric이 필요하다.

그래서 아래와 같은 샘플 데이터를 생성하였다.


 "date":"2013-02-18", "count":33, "price":3421000 },

{  "date":"2013-02-19", "count":4, "price":223000 },

{  "date":"2013-02-19", "count":6, "price":464000 },

{  "date":"2013-02-20", "count":2, "price":218000 },

{  "date":"2013-02-20", "count":4, "price":392000 },

{  "date":"2013-02-21", "count":8, "price":752700 },


위 데이터를 보면 date는 x축이 되겠고 count or price중 하나가 y축으로 지정하면 된다.

그런데 여기서 문제는 date가 unique하지 않다는 거다. 

Bar Chart의 x축은 date를 daily로 표현하므로 데이터를 date key로 하며 그룹으로(?) 묶어줘야 한다.

쉽게 설명하면 SQL문의 group by가 되겠다.


SELECT DATE, SUM(COUNT), SUM(PRICE) FROM TABLE GROUP BY DATE


이 점을 유념하고 Bar Chart를 생성해보자.


우선 Chart 영역 즉 사이즈를 지정한다.


var margin = {top: 10, right: 10, bottom: 40, left: 60},
    width =
960 - margin.left - margin.right,
    height =
110 - margin.top - margin.bottom;


x축은 date type이다 즉 날짜로 x축 scale을 지정해야 한다. d3.js는 날짜형 데이터로 scale을 지정할 수 있는 d3.time.scale() 을 지원한다. y축의 경우 숫자형이기 때문에 d3.scale.linear() 메소드를 사용하였다.

(만약 문자형이라면 d3.scale.ordinal()를 사용하여야 한다.)


var x = d3.time.scale().range([0, width]);
var y = d3.scale.linear().range([height, 0]);


이제 축을 생성한다.


var xAxis = d3.svg.axis().scale(x).orient("bottom").ticks(20);
var yAxis = d3.svg.axis().scale(y).orient("left").ticks(5);


x축은 orient메소드를 이용하여 bottom으로 지정하였고 y축은 left로 지정하였다. ticks메소드는 축의 tick 갯수를 지정한다.


이제 기본설정은 끝이 났고 이전에 언급했던 데이터를 date로 group by해야 한다.

관련 코드는 아래와 같다. key는 date로 sum값은 count값으로 지정하였다.


var nodes = d3.nest()
.key(
function(d) { return d.date; })
   .rollup(
function(r){
         
return d3.sum(r, function(d){
              
return parseInt(d.count);
         })
    })
    .entries(data);


여기서 중요한 건 nodes 객체를 확인하는 것으로 console로 해당 객체를 확인해보면 아래 그림과 같다.

date는 key로 count는 values로 key값이 지정되어 nodes 객체가 생성된 것을 알 수 있다.



이제 데이터 가공도 끝이 났고 chart를 그려주기만 한다.


var svg = d3.select("body").append("svg")
   .attr(
"width", width + margin.left + margin.right)
   .attr(
"height", height + margin.top + margin.bottom)
   .append(
"g")
      .attr(
"transform", "translate(" + margin.left + "," + margin.top + ")");


x, y축의 scale영역의 정의역을 지정한다. d3.min, max 메소드로 key(날짜)의 범위를 지정한다.(scale과 domain?)


x.domain([
   d3.min(nodes,
function(d) { return new Date(d.key); }),
   d3.max(nodes,
function(d) { return new Date(d.key); })
]);
y.domain([
0, d3.max(nodes, function(d) { return d.values; })]);


x, y축을 생성한다. 


svg.append("g").attr("class", "x axis")
   .attr(
"transform", "translate(0," + height + ")")
   .call(xAxis);

svg.append("g").attr("class", "y axis").call(yAxis);


각각의 데이터의 bar를 생성한다.


svg.selectAll(".bar").data(nodes).enter()
   .append(
"rect")
      .attr(
"class", "bar")
      .attr(
"fill", function(d) { return "steelblue"; })
      .attr(
"x", function(d) { return x(new Date(d.key)); })
      .attr(
"width", 2)
      .attr(
"y", function(d) { return y(d.values); })
     .attr(
"height", function(d) { return height - y(d.values) < 0 ? 0 : height - y(d.values); });


이제 저장 후 결과물을 확인해보면 아래와 같을 것이다.


그런데 x축의 tick text가 겹치는 것을 확인할 수 있다. 위 xAxis의 tick메소드의 값을 조절할 수도 있겠지만 아래와 같이

text를 회전을 시켜 보여주면 더 좋을 것 같다.


svg.selectAll(".x.axis text")
    .attr(
"transform", function(d) {
return "translate(" + this.getBBox().height * -2 + "," + this.getBBox().height + ")rotate(-45)";


소스보기



'd3.js' 카테고리의 다른 글

Google Maps + D3.js  (8) 2014.02.11
bar chart  (4) 2013.09.16
Using D3.js to draw a grid‎  (3) 2013.05.31
visualization using d3.js  (1) 2013.05.28

WRITTEN BY
빵군
Web Programmer HOONS닷넷(http://www.hoons.kr) 2011 ASP.NET 시삽 http://about.me/y2kpooh

받은 트랙백이 없고 , 댓글  4개가 달렸습니다.
  1. 안녕하세요 이제 막 d3를 시작하려고 하는사람인데요...
    혹시 data를 수동으로 다 일일이 입력하셨는데 그렇게 말고 동적으로 입력할수있는 방법이있을까요?
    • 안녕하세요. 해당 아티클은 샘플 예제로써 data를 표현한 것이구요. 문의주신 동적Data는 사용하시고자 하는 저장된 Data를 서버를 통해서 가져오신 후 처리하셔야 됩니다.
  2. ㅠㅡㅠ 제가 스프링으로 프로젝트를만들고 있는데 db에서 값을 가져와서 화면에 뿌려주거든요..
    그거를 지금 올리신것처럼 날짜별로 묶어서 날짜별로 몇개의 게시글이 올라왔는지를 해보고싶은데..
    var dataSet =[] 에서 어떻게 그 데이터를 처리할수있나요? 예로들면 jsp에서 db값을 가져올때 ${row.crea_dtm} 이렇게 가져오듯 dataSet에도 이와같이 호출할수있는 방법이 있ㄴ나요??ㅠㅠ
    • 질문주신 내요으로 봐서는 이제 막 시작하시는 분 같은데요 ^^;
      서버사이드 혹은 프론트앤드에서 DB에서 조회하신 정형화된 데이터를
      원하는 json포맷으로 가공하셔서 사용하셔야 합니다.
secret


D3.js는 SVG뿐만 아니라 HTML DOM 핸들링이 가능하다.

이번에는 D3.js를 이용하여 아래와 같은 Grid(Table)을 그려본다.


실행화면 미리보기



샘플 데이터

var matrix = [{"Girth":8.3,"Volume":10.3,"Height":70},{"Girth":8.6,"Volume":10.3,"Height":65} ...];


우선 아래 그림에 표시된 테이블 헤더를 추가해보자.

테이블 HEAD


d3.select("body")
	.append("table")
	.style("border-collapse", "collapse")
	.style("border", "2px black solid")
	.append("tr")
	.attr("class", "tr_head")
	.selectAll("td")
		.data(d3.keys(matrix[0]))
		.enter().append("td")
		.style("border", "1px black solid")
		.style("padding", "5px")
		.style("text-align", "center")
		.on("mouseover", function(){ d3.select(this).style("background-color", "aliceblue")})
		.on("mouseout", function(){ d3.select(this).style("background-color", "white")})
		.text(function(d) { return d; } )
		.style("font-size", "12px");

1~7라인까지는 table, tr, td태그를 순차적으로 생성한다.

8번라인에서는 td에 세팅될 데이터를 매핑한다. 

td에 matrix객체의 키를 삽입하기 위하여 d3.keys()로 메서드를 사용하였다.

8번 라인의 리턴 값

["Girth", "Volume", "Height"]

10~16라인까지는 해당 td에 대한 이벤트와 속성을 추가해주었다.

D3.js의 on메서드와 관련하여서는 여기를 참고하기 바란다.


이제 아래그림에 표시된 body부분을 추가해보자.


테이블 BODY


d3.select("body table").selectAll("tr") .data(matrix) .enter().append("tr") .attr("class", "tr_body") .selectAll("td") .data(function(d){ return d3.values(d);}) .enter().append("td") .style("border", "1px black solid") .style("padding", "5px") .style("text-align", "center") .on("mouseover", function(){ d3.select(this).style("background-color", "aliceblue")}) .on("mouseout", function(){ d3.select(this).style("background-color", "white")}) .text(function(d, i){ return d;}) .style("font-size", "12px");

2번라인에서 matrix객체를 data메서드에 연결 시키고 

6번라인에서 matrix객체의 value값을 삽입하기 위하여 d3.values() 메서드를 사용하였다.

나머지는 테이블 HEAD부분과 동일하다.


참고자료 : http://christopheviau.com/d3_tutorial/

'd3.js' 카테고리의 다른 글

Google Maps + D3.js  (8) 2014.02.11
bar chart  (4) 2013.09.16
Using D3.js to draw a grid‎  (3) 2013.05.31
visualization using d3.js  (1) 2013.05.28

WRITTEN BY
빵군
Web Programmer HOONS닷넷(http://www.hoons.kr) 2011 ASP.NET 시삽 http://about.me/y2kpooh

받은 트랙백이 없고 , 댓글  3개가 달렸습니다.
  1. 안녕하세요,
    완성된 표를 보면 맨 처음 데이터인
    {"Girth":8.3,"Volume":10.3,"Height":70}
    는 없어진 것으로 보이는데요,
    다시 보이게 하는 방법은 무엇인가요?
secret

visualization using d3.js

d3.js 2013.05.28 14:50


현재 소속된 회사에서 빅데이터를 시각화 하는 방법을 찾던 중 D3.js를 학습하게 되었다.

처음에는 쉽게 접근 가능한 highcharts 와 같은 라이브러리를 사용하려고 했으나

D3.js의 확장성과 유연성으로 D3.js를 선택하게 되었다.

역시나 D3.js는 쉽지 않다.... 몇가지의 메서드는 그냥 이런 기능이다 정도만 알겠더라... 설명도 이해하기도 쉽지 않다. 개인학습용도로 정리하고자 한다.


1. D3.js란

D3.js는 데이터 시각화 프레임워크로 잘 알려져 있고, 자바스크립트로 개발을 한다.

HTML5의 SVG을 통하여 다양한 화면 해상도에서 깨짐없는 Visualizing이 가능하다.


이와 같은 막강한 시각화를 쉽게(?) 작성할 수 있다.(D3 Example 더보기)


2. 기본설정

D3.js 라이브러리는 여기 에서 다운받을 수 있다.

JS 파일 하나만 내려받게 되면 준비끝이다.


3. D3.js 코딩

아래와 같은 pie 그래프를 그려보자

실행화면 보기


D3.js의 경우도 jquery와 같은 CSS 선택자, 메소드 체인 등과 같은 기능이 제공된다. 

jquery를 해보았다면 수월하게 접근 가능하다.


자 이제 위와 같은 pie그래프를 그려주기 위한 Data가 필요하다. D3.js의 경우 JSON, CSV와 같은 데이터 타입을 쉽게 사용가능하며 아래 예제는 몇가지 데이터가 필요하지 않은 관계로 자바 배열 객체를 사용하였다.


우선 Data 객체를 선언한다.

var DATA = [10, 40, 80];


이제 SVG를 이용하여 시각화 하기 위하여 캔버스(HTML5와 혼돈하지 마시기를...) 영역을 생성한다. 쉽게 얘기하면 그림을 그리기 위한 용지영역을 생성한다고 보면 된다.

var canvas = d3.select("body").append("svg")
	.attr("width", 1500)
	.attr("height", 1500);


javascript나 jquery를 조금 아시는 분이라면 위 코드를 굳이 설명하지 않아도 알 수 있을 것이다.

그렇다 jquery와 매우 유사하다. select 메서드에 셀렉터 문자열 body를 인자로 넘기게 되면 html문서 중 일치하는 첫번째 dom 노드를 반환한다. 그리고 append 메서드로 svg tag를 추가하고 width, height를 각각 1500식 주었다. canvas는 객체이면서 함수로 사용가능하다.


이와 같이 추가된다.


이제 group tag g를 추가하고 캔버스에서 상단과 좌측으로 부터 각 300식 이동 시킨다.

var group = canvas.append("g")
	.attr("transform", "translate(300, 300)");


arc(호)의 경로 데이터 문자열을 반환하는 arc 메서드를 선언한다. innerRadius는 안쪽 호의 반지름이고 outerRadius는 바깥쪽 반지름 수치이다.

var arc = d3.svg.arc()
	.innerRadius(100)
	.outerRadius(200);



D3.js는 레이아웃을 제공한다. 해당 레이아웃 메서드를 사용하면 조금 수월하게 그래프를 그릴 수 있다. 

pie layout 을 사용한다.

var pie = d3.layout.pie()
	.value(function(d) { return d; });


arc(호)를 그리기 위한 group tag g를 생성한다.

var arcs = group.selectAll(".arc")
	.data(pie(DATA))
	.enter()
	.append("g")
	.attr("class", "arc");

data 메서드는 데이터 집합의 각 데이터를 빈 셀렉션에 연결시킨다. 

DATA 개수 만큼 생성하게 된다. enter 메서드를 이용하여 데이터를 추가할 수 있다.


앞서 pie 객체에 DATA를 인자로 넘기면 pie layout에 의하여 아래와 같이 객체에 프로퍼티에 값이 할당 된다.


arc(호)에 path를 추가한다.

arcs.append("path")
	.attr("d", arc);

이제까지 작업한 내용을 확인하면 아래와 같다.

arc(호)별로 색상과 text를 삽입해보자.



arc(호)에 text를 삽입한다.

	arcs.append("text")
	.attr("transform", function(d) { return "translate(" + arc.centroid(d) + ")"; })
	.attr("text-anchor", "middle")
	.attr("text-size", "10px")
	.text(function(d) { return d.data});

색상을 추가한다.

	var color = d3.scale.ordinal()
	.range(["red", "orange", "blue"]);

	arcs.append("path")
	.attr("d", arc)
	.attr("fill", function (d) { return color(d.data); });

전체소스

var DATA = [10, 40, 80];

var canvas = d3.select("body").append("svg")
	.attr("width", 1500)
	.attr("height", 1500);

var group = canvas.append("g")
	.attr("transform", "translate(300, 300)");

var color = d3.scale.ordinal()
	.range(["red", "orange", "blue"]);

var arc = d3.svg.arc()
	.innerRadius(100)
	.outerRadius(200);

var pie = d3.layout.pie()
	.value(function(d) { return d; });

var arcs = group.selectAll(".arc")
	.data(pie(DATA))
	.enter()
	.append("g")
	.attr("class", "arc");

arcs.append("path")
	.attr("d", arc)
	.attr("fill", function (d) { return color(d.data); });

arcs.append("text")
	.attr("transform", function(d) { return "translate(" + arc.centroid(d) + ")"; })
	.attr("text-anchor", "middle")
	.attr("text-size", "10px")
	.text(function(d) { return d.data});


.arc text{
	font-family: arial;
	font-size:2em;
	fill: #fff;
	font-weight:bold;
}

해당샘플소스는 여기를 참고하였으며

위 소스에 대하여 자세한 API Reference를 알고 싶다면 여기를 참고하길 바란다.

'd3.js' 카테고리의 다른 글

Google Maps + D3.js  (8) 2014.02.11
bar chart  (4) 2013.09.16
Using D3.js to draw a grid‎  (3) 2013.05.31
visualization using d3.js  (1) 2013.05.28

WRITTEN BY
빵군
Web Programmer HOONS닷넷(http://www.hoons.kr) 2011 ASP.NET 시삽 http://about.me/y2kpooh

받은 트랙백이 없고 , 댓글 하나 달렸습니다.
  1. 비밀댓글입니다
secret