【D3.js】Facebookでフレンドがどれだけ「いいね!」しているかの視覚化
↑の補足。
Facebookから取得できるソーシャルグラフデータ(gdf)をD3で使えるようにする手順
netvizzからダウンロードしたgdfデータのフォーマットは以下
nodedef>name VARCHAR,label VARCHAR,gender VARCHAR,locale VARCHAR,agerank
INT
23917067,Jorge,male,en_US,106
23931909,Haruna,female,en_US,105
35702006,Joseph,male,en_US,104
503839109,Damian,male,en_US,103
532735006,Isaac,male,es_LA,102
. . .
edgedef>node1 VARCHAR,node2 VARCHAR
23917067,35702006
23917067,629395837
23917067,747343482
23917067,755605075
23917067,1186286815
. . .
まずは「nodedef」のデータと「edgedef」で分け、二つのcsvデータを作る
「name」のカラム名は分かりやすいように「id」に変更した
nodes.csv
id,label,gender,locale,agerank
23917067,Jorge,male,en_US,106
23931909,Haruna,female,en_US,105
35702006,Joseph,male,en_US,104
503839109,Damian,male,en_US,103
532735006,Isaac,male,es_LA,102
. . .
links.csv
node1,node2
23917067,35702006
23917067,629395837
23917067,747343482
23917067,755605075
23917067,1186286815
. . .
D3 Force Layout で使うには
フォースレイアウトでは、linkデータとしてnodeの結びつきをインデックスで表さないとならない。
(例
var nodes = [ {id:1, name:"hoge"}, {id:2, name:"fuga"} ]
hogeからfugaへの結びつき表すにはlinkデータで以下のように表現する。
var links = [ {source:0 ,target:1 }];
あくまでnodes配列のインデックス値での指定しなくてはならないことに注意。
そこで、gdfのデータからlink(source, target)データを作成する
d3.csv('nodes.csv', function(nodes){
d3.csv('links.csv', function(links){
d3main(nodes, links);
});
});
function d3main(nodes, links){
var nodeID = {}; //idの位置(配列のindex)を保存する
for(var i=0; i < nodes.length; i++){
var id = nodes[i].id;
nodeID[id] = i;
}
//source,targetの取得
for(var i=0; i < links.length; i++){
links[i]['source'] = nodeID[links[i]['node1']];
links[i]['target'] = nodeID[links[i]['node2']];
}
graph = {'nodes': nodes, 'links': links };
console.log(graph);
}
作成したデータをフォースレイアウトで表示する
var width = 960,
height = 500;
var force = d3.layout.force()
.charge(-120)
.linkDistance(30)
.size([width, height]);
force
.nodes(graph.nodes)
.links(graph.links)
.start();
var link = svg.selectAll(".link")
.data(graph.links)
.enter()
.append("line")
.attr("class", "link")
var node = svg.selectAll(".node")
.data(graph.nodes)
.enter()
.append("circle")
.attr("class", "node")
.attr("r", 5)
.style("fill", "blue")
.call(force.drag);
node.append("title")
.text(function(d) { return d.label; });
force.on("tick", function() {
link.attr("x1", function(d) { return d.source.x; })
.attr("y1", function(d) { return d.source.y; })
.attr("x2", function(d) { return d.target.x; })
.attr("y2", function(d) { return d.target.y; });
node.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; });
});