以《连城诀》为例:
结果图:
人物和关系如下:
.nodetext {
font-size: 18px ;
font-family: SimSun;
fill:#000000;
}
.linetext {
font-size:18px ;
font-family: SimSun;
fill:#0000FF;
fill-opacity:0.0;
}
</style>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script>
var nodes = [
{"name":"狄云"},
{"name":"丁典"},
{"name":"戚长发"},
{"name":"戚芳"},
{"name":"万震山"},
{"name":"血刀老祖"},
{"name":"凌霜华"},
{"name":"凌退思"},
{"name":"空心菜"},
{"name":"万圭"},
{"name":"水笙"},
{"name":"梅念笙"},
{"name":"言达平"}
]
var edges = [
{"source":0, "target":1, "relation":"义兄弟"},
{"source":0, "target":2, "relation":"师徒"},
{"source":0, "target":3, "relation":"初恋"},
{"source":0, "target":5, "relation":"师徒"},
{"source":0, "target":10, "relation":"相爱"},
{"source":1, "target":6, "relation":"相爱"},
{"source":1, "target":7, "relation":"被毒杀"},
{"source":1, "target":11, "relation":"师徒"},
{"source":2, "target":11, "relation":"师徒"},
{"source":4, "target":11, "relation":"师徒"},
{"source":2, "target":3, "relation":"父女"},
{"source":3, "target":9, "relation":"夫妻"},
{"source":3, "target":8, "relation":"母女"},
{"source":4, "target":9, "relation":"父子"},
{"source":6, "target":7, "relation":"父女"},
{"source":11, "target":12, "relation":"师徒"},
{"source":12, "target":0, "relation":"利用"}
]
svg画图
var width = 1366
var height = 692
var svg = d3.select("body")
.append("svg")
.attr("width",width)
.attr("height",height)
var force = d3.layout.force()
.nodes(nodes) //指定节点数组
.links(edges) //指定连线数组
.size([width,height]) //指定范围
.linkDistance(150) //指定连线长度
.charge(-400) //相互之间的作用力
force.start();
console.log(nodes);
console.log(edges);
var svg_edges = svg.selectAll("line")
.data(edges)
.enter()
.append("line")
.style("stroke","#ccc")
.style("stroke-width",1)
var color = d3.scale.category20()
var svg_nodes = svg.selectAll("circle")
.data(nodes)
.enter()
.append("circle")
.attr("r",20)
.style("fill",function(d,i){return color(i)})
.on("mouseover",function(d,i){
//显示连接线上的文字
edges_text.style("fill-opacity",function(edge){
if( edge.source === d || edge.target === d ){
return 1.0;
}
});
})
.on("mouseout",function(d,i){
//隐去连接线上的文字
edges_text.style("fill-opacity",function(edge){
if( edge.source === d || edge.target === d ){
return 0.0;
}
});
})
.call(force.drag);
var svg_texts = svg.selectAll(".nodetext")
.data(nodes)
.enter()
.append("text")
.style("fill","black")
.attr("class","nodetext")
.attr("dx",-15)
.attr("dy",-25)
.text(function(d){
return d.name
}
)
var edges_text = svg.selectAll(".linetext")
.data(edges)
.enter()
.append("text")
.style("fill","blue")
.attr("class","linetext")
.text(function(d){
return d.relation;
});
force.on("tick",function(){
svg_edges.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;})
svg_nodes.attr("cx",function(d){return d.x})
.attr("cy",function(d){return d.y})
svg_texts.attr("x",function(d){return d.x})
.attr("y",function(d){return d.y})
edges_text.attr("x",function(d){ return (d.source.x + d.target.x) /2 ; })
.attr("y",function(d){ return (d.source.y + d.target.y) / 2 ; });
})
</script>