力导向图是D3里面一个比较酷炫的布局,我们只要定义好各个节点的信息及各个节点间的关系即可简历一个力导向图。
PS:重要的事情说N遍
D3提供的布局只提供生成布局的必要数据,不会直接绘图
D3提供的布局只提供生成布局的必要数据,不会直接绘图
D3提供的布局只提供生成布局的必要数据,不会直接绘图
...
数据:
var testData = {
"node":[
{
"id":"123456487",
"name":"厦门",
"type":"1"
},
{
"id":"1234fg56487",
"name":"思明区",
"type":"2"
},
{
"id":"1234sssa56487",
"name":"集美区",
"type":"2"
},
{
"id":"1234ddd56487",
"name":"湖里区",
"type":"2"
},
{
"id":"123gg456487",
"name":"海沧区",
"type":"2"
},
{
"id":"12345f6487",
"name":"同安区",
"type":"2"
},
{
"id":"12345asdf6487",
"name":"翔安区",
"type":"2"
}
],
"links":[
{
"source":"123456487",
"target":"1234fg56487",
"relation":"从属"
},
{
"source":"123456487",
"target":"1234sssa56487",
"relation":"从属"
},
{
"source":"123456487",
"target":"1234ddd56487",
"relation":"从属"
},
{
"source":"123456487",
"target":"123gg456487",
"relation":"从属"
},
{
"source":"123456487",
"target":"12345f6487",
"relation":"从属"
},
{
"source":"123456487",
"target":"12345asdf6487",
"relation":"从属"
},
{
"source":"12345f6487",
"target":"12345asdf6487",
"relation":"兄弟"
}
]
};
逻辑代码
var height = 500,width=600; //画布规格
var color = d3.scale.category20(); //颜色标尺
var svg = d3.select("body")
.append("svg")
.attr("width", width)
.attr("height", height);
var Nodes = [],tempNodesIndex = []; //新的节点数组及id数组
for(var j=0;j<testData.node.length;j++){
Nodes[Nodes.length]={
"id":testData.node[j].id,
"name":testData.node[j].name,
"type":testData.node[j].type
};
tempNodesIndex[tempNodesIndex.length] = testData.node[j].id;
}
//console.log(tempNodesIndex);
//重新映射关系
var Links = [];
for(var i=0; i<testData.links.length; i++){
Links[Links.length] = {
"source":tempNodesIndex.indexOf(testData.links[i].source),
"target":tempNodesIndex.indexOf(testData.links[i].target),
"relation":testData.links[i].relation
};
}
//console.log(links)
var force = d3.layout.force()
.nodes(Nodes)
.links(Links)
.size([width,height])//指定作用域范围
.linkDistance(150) //指定连线长度
.charge([-800]); //作用力
//上面的布局方法注入数据后获取必要的数据(定位、权重等)
/*布局不会生成图,而是提供生成图的必要数据*/
force.start();
// console.log(nodes)
// console.log(links)
//添加连线
var _lines = svg.selectAll('line')
.data(Links)
.enter()
.append('line')
.style('stroke-width',1)
.style('stroke',"#ccc")
//添加节点
var _nodes = svg.selectAll('circle')
.data(Nodes)
.enter()
.append('circle')
.attr('r',function(d){
return d.type==1?30:20;
})
.style('fill',function(d){
return color(d.type);
})
.call(force.drag); //调用drag方法使图形可拖动
//描述文字
var _texts = svg.selectAll('.nodeName')
.data(Nodes)
.enter()
.append('text')
.attr('class','nodeName')
.style('fill','block')
.attr('dx',function(d){
return d.type==1?30:20;
})
.attr('dy',8)
.text(function(d){
return d.name;
})
//更新图形的每一帧
force.on('tick',function(){
//更新连线坐标
_lines.attr("x1",function(d){
console.log(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; });
//更新节点坐标
_nodes.attr("cx",function(d){ return d.x; })
.attr("cy",function(d){ return d.y; });
//更新文字坐标
_texts.attr("x", function(d){ return d.x; })
.attr("y", function(d){ return d.y; });
});
以上例子用D3库为:D3【http://d3js.org/d3.v3.min.js】
Demo 截图: