概述
D3(或D3.js)是一个 JavaScript 库,用于使用 Web 标准可视化数据。D3 帮助您使用 SVG、Canvas 和 HTML 使数据栩栩如生。D3 将强大的可视化和交互技术与数据驱动的 DOM 操作方法相结合,为您提供现代浏览器的全部功能,并为您的数据设计合适的可视化界面的自由。
力导向布局
D3力导向概述
力导向布局(force-directed layout)是一种基于物理学原理的图形布局算法,它使用节点之间的引力和斥力来决定节点在可视化图形中的位置。在D3中,力导向布局是通过d3-force
模块实现的。
在力导向布局中,每个节点都是一个带有位置、速度和加速度的物体,节点之间的连线被看作是弹簧,节点与节点之间的引力、节点与节点之间的斥力以及每个节点的阻尼都被建模为物理量。这些物理量会在每个迭代步骤中更新,并且节点位置会根据当前速度和加速度更新。
D3力导向布局主要包括以下步骤:
- 创建一个力导向布局对象:使用
d3.forceSimulation()
函数创建一个力导向布局对象。 - 定义节点和边:使用
nodes()
和links()
函数分别定义节点和边。 - 配置节点和边的力属性:使用
force()
函数来配置节点和边的力属性,例如设置节点之间的斥力和吸引力的大小,以及阻尼大小等。 - 启动力导向布局:使用
simulation.alpha(1).restart()
函数启动力导向布局,将节点和边放置到初始位置并开始模拟力学运动。 - 监听布局的变化:使用
simulation.on()
函数来监听布局变化,例如节点和边的位置更新、力的变化等。 - 更新可视化图形:在每个布局变化事件发生时,使用D3的数据绑定和选择方法来更新可视化图形的位置和属性。
通过调整力导向布局的参数和添加其他交互性的功能,可以创建各种类型的动态可视化图形,例如网络图、关系图等。
力导向与SVG
SVG(Scalable Vector Graphics)是一种用于描述二维矢量图形的XML标记语言,它可以通过浏览器渲染为图像或动画。在D3中,SVG是默认的图形渲染引擎,因此力导向布局与SVG密切相关。
具体来说,D3力导向布局可以通过SVG元素来创建和呈现节点和连线。在创建力导向布局时,可以使用d3.forceSimulation()
函数来创建一个力模拟器,并将节点和连线的位置属性绑定到SVG元素上,例如:
const simulation = d3.forceSimulation(nodes) .force("link", d3.forceLink(links).id(d => d.id)) .force("charge", d3.forceManyBody()) .force("center", d3.forceCenter(width / 2, height / 2)); const link = svg.append("g") .selectAll("line") .data(links) .enter().append("line") .attr("stroke", "#999") .attr("stroke-opacity", 0.6) .attr("stroke-width", d => Math.sqrt(d.value)); const node = svg.append("g") .selectAll("circle") .data(nodes) .enter().append("circle") .attr("r", 5) .attr("fill", d => color(d.group)) .call(d3.drag() .on("start", dragstarted) .on("drag", dragged) .on("end", dragended));
在上面的代码中,d3.forceSimulation()
函数创建了一个力模拟器,并使用forceLink()
、forceManyBody()
和forceCenter()
来定义节点之间的连线、节点的斥力和图形的中心位置。然后,使用SVG的line
元素来呈现连线,使用circle
元素来呈现节点,并将节点和连线的位置属性绑定到SVG元素上。同时,使用D3的drag()
方法为节点添加拖动交互。
通过以上代码,我们可以将D3力导向布局中的节点和连线呈现为一个SVG图形,并且可以使用D3的数据绑定和选择方法来更新图形的位置和属性,从而实现交互式和动态的数据可视化效果。
其他力导向布局库
在JavaScript中,有许多力导向布局的库可供选择。以下是一些比较流行的库:
- D3.js:D3是一个JavaScript库,它提供了各种数据可视化功能,包括力导向布局。D3的力导向布局功能非常强大,它可以创建各种类型的动态可视化图形,例如网络图、关系图等,并且具有灵活的配置选项和丰富的交互性功能。
- Sigma.js:Sigma是一个基于WebGL的图形可视化库,它提供了各种类型的图形布局算法,包括力导向布局。Sigma的力导向布局算法快速且适合大型数据集,而且可以与其他布局算法和插件结合使用。
- Cytoscape.js:Cytoscape是一个基于WebGL的图形可视化库,它专注于生物信息学和网络科学领域,提供了各种类型的图形布局算法,包括力导向布局。Cytoscape的力导向布局算法支持各种常见的布局参数和约束,例如节点间距、重力、斥力等。
- Vis.js:Vis是一个JavaScript可视化库,提供了各种类型的图形布局算法,包括力导向布局。Vis的力导向布局算法可以实现各种类型的动态可视化效果,并支持多种数据格式和交互式操作。
这些库各有特点和优劣,具体选择取决于项目需求和个人偏好。如果需要灵活的数据绑定和定制化配置,D3.js是一个不错的选择。如果需要快速绘制大型网络图,并希望使用WebGL技术提高性能,可以考虑使用Sigma.js或Cytoscape.js。如果需要简单易用的API和多种数据格式的支持,可以考虑使用Vis.js。
D3 V7
在 D3 v7 版本中,d3.event
已经被移除了,可以通过将 d3-selection
模块作为依赖项引入,并使用 d3.pointer(event)
来代替 d3.mouse()
和 d3.touches()
,使用 event.sourceEvent
来代替 d3.event
。
例如,可以像下面这样更改 dragstarted
和 dragged
函数:
function dragstarted(event, d) { if (!event.active) simulation.alphaTarget(0.3).restart(); d.fx = d.x; d.fy = d.y; } function dragged(event, d) { d.fx = event.x; d.fy = event.y; } function dragended(event, d) { if (!event.active) simulation.alphaTarget(0); d.fx = null; d.fy = null; }
然后在代码中引入 d3-selection
模块:
<script src="https://d3js.org/d3-selection.v2.min.js"></script>