上一篇只是將數據根據默認的索引值關係展示了出來,而實際開發中這樣的方式肯定是行不通的,比如要展示人物關係圖,你不可能把每個人指向和被指向關係正好和默認的索引值對上號,所以我們需要確定一個指定的字段或關鍵字來展示他們的關係,如身份證號、電話號碼等。只要包含其中的一個屬性(身份證號、電話號碼等),我們便可以確定其相關的連接關係。
直接看代碼,不明白之處請留言。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script src="https://d3js.org/d3.v3.min.js"></script>
<title>vichun-CSDN</title>
</head>
<body>
<script>
let dataset={
'nodes':[
{
name:'亞瑟',
id:100,
type:"坦克"
},
{
name:'后羿',
num:6998998,
type:'射手'
},
{
name:'虞姬',
id:101,
type:"射手"
},
{
name:'妲己',
num:6998997,
type:'法師'
},
{
name:'荊軻',
id:102,
type:"刺客"
},
{
name:'哪吒',
num:6998996,
type:'戰士'
},
{
name:'羋月',
id:103,
type:"輔助"
},
{
name:'孫悟空',
num:6998995,
type:'打野'
},
],
'links':[
{
from:100,
to:6998998
},
{
from:100,
to:101
},
{
from:100,
to:102
},
{
from:100,
to:6998997
},
{
from:6998998,
to:103
},
{
from:6998998,
to:6998996
},
{
from:100,
to:6998995
}
]
};
let nodes = dataset.nodes;
let links = dataset.links;
links.forEach(function(e){
let sourceNode = nodes.filter(function(n){
//可以在nodes裏邊加一個字段,用來說明當前對象裏包含的是id還是num,
// 判斷時直接判斷字段的值
// 例如:
//nodes:[
// {
// name:'亞瑟',
// id:100,
// label:'ID'
// }
// ]
// 則判斷可以寫爲:
// if(n.label === 'ID')
if((n.id !== undefined) && (n.id !== null) && (n.id !== '')){
return n.id === e.from;
}
else if((n.num !== undefined) && (n.num !== null) && (n.num !== '')){
return n.num === e.from;
}
})[0];
let targetNode = nodes.filter(function(n){
if((n.id !== undefined) && (n.id !== null) && (n.id !== '')){
return n.id === e.to;
}
else if((n.num !== undefined) && (n.num !== null) && (n.num !== '')){
return n.num === e.to;
}
})[0];
e.source = sourceNode;
e.target = targetNode;
});
let width = 1000;
let height = 1000;
let svg = d3.select('body')
.append('svg')
.attr('width',width)
.attr('height',height);
let force = d3.layout.force()
.nodes(nodes) //設定節點數組
.links(links) //設定關係數組
.size([width,height]) //設定作用域的範圍
.distance(1000)
.linkDistance(300) //設定關係連線的長度
.charge(-1500); //節點間的相互作用力
force.start(); //開始引力作用
// 定義一個顏色生成器,由d3提供
let color = d3.scale.category20(); //20表示可以生成20種不同的顏色
// 下邊開始繪製
// 繪製節點間的關係連線
let linksLine = svg.selectAll('line')
.data(links)
.enter()
.append('line')
.style('stroke','#ccc')
.style('stroke-width',2);
// 繪製節點
let nodesCic = svg.selectAll('circle')
.data(nodes)
.enter()
.append('circle')
.attr('r',25)
.style('fill',function(d,i){
return color(i); //根據自身的索引號,自動隨機獲取一種背景顏色
})
.call(force.drag); //調用drag函數,是的節點可以拖動
// 給節點添加名稱
let nodesTitle = svg.selectAll('text')
.data(nodes)
.enter()
.append('text')
.style('fill','#fff')
.attr("text-anchor", "middle") //是的文字居中顯示在節點上
// .attr('dx',20) //自定義文字的x座標
// .attr('dy',5) //自定義文字的y座標
.text(function(d){
return d.name;
});
force.on('tick',tick);
function tick(){
// 更新連線的座標
linksLine.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;});
// 更新節點座標
nodesCic.attr('cx',function(d){return d.x;})
.attr('cy',function(d){return d.y});
// 更新文字座標
nodesTitle.attr('x',function(d){return d.x})
.attr('y',function(d){return d.y + 5});
}
</script>
</body>
</html>