D3.js实现力向导图的绘制教程详解
什么是力导向图
力导向图(Force-Directed Graph),又称作弹簧-电荷网络图(Spring-Electrical Network),是一种用于表现连接关系的图表类型。力导向图主要用于网络,社交网络分析、生物信息学、市场营销、数据挖掘等方面。它使用物理引力和斥力来模拟节点之间的连接,使得节点之间趋于平衡,可以形成有意义的可视化图表。
D3.js是什么
D3.js(Data-Driven Documents)是一个基于JavaScript的开源可视化库。它通过使用HTML、SVG和CSS等不同的Web标准,帮助用户在网页上实现各种各样的可视化。
实现力向导图的D3.js代码
1. 基础模板
首先,我们需要准备HTML文件,并包含以下的模板:
<!DOCTYPE html>
<meta charset="utf-8">
<style>
/* 样式 */
</style>
<body>
<!-- SVG画布 -->
<script src="https://d3js.org/d3.v5.min.js"></script>
<script>
// D3.js代码
</script>
</body>
2. 数据准备
接着,准备用于绘制网络的数据。这里我们使用一个JSON对象:
var graph = {
"nodes": [
{"id": "0", "label": "Node 1"},
{"id": "1", "label": "Node 2"},
{"id": "2", "label": "Node 3"},
{"id": "3", "label": "Node 4"}
],
"links": [
{"source": "0", "target": "1"},
{"source": "1", "target": "2"},
{"source": "2", "target": "3"},
{"source": "3", "target": "0"}
]
};
其中,nodes表示节点列表,每个节点有一个id和一个label;links表示节点之间的关系列表,每个关系有一个source和一个target,分别对应起点和终点的节点id。
3. 力导向图生成器
接着,我们使用D3.js的力导向图生成器(forceSimulation)来计算节点之间的力量和位置。在这个例子中,我们使用以下代码:
var width = 960;
var height = 600;
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
var simulation = d3.forceSimulation()
.nodes(graph.nodes)
.force("link", d3.forceLink(graph.links).id(function(d) { return d.id; }))
.force("charge", d3.forceManyBody())
.force("center", d3.forceCenter(width / 2, height / 2));
解释一下每段代码的作用:
- 选择body,然后添加一个SVG画布,并设置宽度和高度。
- 使用d3.forceSimulation()方法创建一个新的力导向图模拟器。在这个模拟器中,我们还可以添加力的类型,例如link、charge和center。
- 使用.nodes()方法传递节点列表的引用。
- 使用.force("link")方法传递连接关系列表的引用,并使用.forceLink()方法设置连接关系的id。
- 使用.force("charge")添加一种与节点之间的互动力量有关的力。
- 使用.force("center")将力起点设置为画布的中心。
4. 节点绘制
接着,我们需要绘制节点(圆形)和它们的标签。使用以下代码:
var node = svg.selectAll(".node")
.data(graph.nodes)
.enter().append("g")
.attr("class", "node");
node.append("circle")
.attr("r", 10);
node.append("text")
.attr("dx", 12)
.attr("dy", ".35em")
.text(function(d) { return d.label });
解释一下每段代码的作用:
- 使用selectAll()方法选择所有节点,并使用.data()方法绑定节点列表到选择的DOM元素上。
- 使用.enter()方法获取新节点,并使用.append()方法添加节点到SVG画布上。
- 使用.attr()方法设置节点的样式。
- 添加了一个g元素,方便以后进行平移操作。
- 给节点添加圆形和标签。
其中,在node.append("g").attr("class", "node")中,我们创建了一个g元素,将其定义为“node”类,这意味着我们可以在它们上面执行相同的操作。聚合圆圈和文本,以便在应用力时它们能一起移动。
5. 连接线绘制
最后,我们需要绘制连接线(边缘)。使用以下代码:
var link = svg.selectAll(".link")
.data(graph.links)
.enter().append("line")
.attr("class", "link");
d3.forceSimulation()
.nodes(graph.nodes)
.force("link", d3.forceLink(graph.links))
.on("tick", ticked);
function ticked() {
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("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
}
解释一下每段代码的作用:
- 使用.selectAll()方法选择所有连接线,并使用.data()方法绑定连接列表到选择的DOM元素上。
- 使用.enter()方法添加连接到SVG画布上,并使用.attr()方法设置样式。
- 使用d3.forceSimulation()方法重新设置力导向图模拟器的节点,连接和力(在这个例子中,仅针对连接)。
- 使用.on("tick", ticked)方法创建一个回调函数,当力模拟器运作时(每个内部计算步骤)即重绘页面。
- ticked()函数在节点移动时不断被调用,并使用link.attr()方法绘制连接线,使用node.attr()方法移动节点。
示例解释
示例1:集成到已有的网站
下面是一个将力导向图集成到现有网站(TaipeiCityBus.com)的示例。假设我们要在该网站上绘制公交车的运行路线。以下是实现步骤:
-
首先,我们获取公交车路线的JSON数据。
-
然后,我们需要转换该JSON数据,以适应力导向图的格式。在这个例子中,转换JSON时我们增加了一个id值,并删除了一些数据。
-
接着,我们根据转换后的JSON数据和D3.js的代码绘制力导向图。
<!DOCTYPE html>
<meta charset="utf-8">
<style>
#map {
position: relative;
}
#map-svg {
position: absolute;
top: 0;
left: 0;
}
</style>
<body>
<div id="map">
<!-- 添加一些HTML标签和CSS样式 -->
</div>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script>
/* 加载JSON数据、转换JSON格式、绘制力导向图并在SVG中插入地图 */
</script>
</body>
示例2:交互式力导向图
下面是交互式力导向图的示例。我们将使用D3.js和类似chord diagram的力导向图实现,在线展示流音乐的播放次数数据。当鼠标指向某首歌时,它的播放次数会在整个图表中突出显示。
以下是实现步骤:
-
首先,我们需要准备用于绘制流音乐播放次数的数据。
-
然后,我们可以使用D3.js的chord force-directed diagram generator来生成一个力导向图。
-
最后,我们可以对这个力导向图进行一些交互处理,如鼠标移动到特定部分时改变颜色。
<!DOCTYPE html>
<meta charset="utf-8">
<style>
/* 样式 */
</style>
<body>
<div id="viz"></div>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script>
/* 绘制力导向图 */
</script>
</body>
总结
通过以上步骤,我们可以使用D3.js轻松绘制力导向图。它功能强大,确保您的数据可视化和网站设计趋于完美。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:D3.js实现力向导图的绘制教程详解 - Python技术站