gpt4 book ai didi

d3.js - 如何为 Vue.js 实现 D3

转载 作者:搜寻专家 更新时间:2023-10-30 22:11:21 26 4
gpt4 key购买 nike

D3 与 React 有多种实现。其中一个比较有趣的是使用 react-faux-dom 项目。这种方法的优点是 React 了解 D3 创建的 DOM 元素以及创建同构图表的能力。

引用以下内容:

在 Vue.js 中实现 D3 并获得相同的好处需要什么?

是否需要创建类似于 react-faux-dom 的东西,或者 Vue 是否已经有可以用于此的东西?

考虑到 Vue 的架构,这种方法有何意义(或没有意义)?

最佳答案

从版本 4 开始,D3 高度模块化,计算部分在小型库中得到很好的隔离,例如 d3-force .我喜欢的一种方法是让 Vue.js 处理 DOM 操作和事件,并使用 d3.js 进行计算。您的可视化组件与您的其他组件类似,对于熟悉 Vue.js 但不熟悉 d3.js 的人来说更容易理解。

我创建了一个 codepen显示力图实现:

HTML:

<div id="app">
<svg xmlns="http://www.w3.org/2000/svg" :width="width+'px'" :height="height+'px'" @mousemove="drag($event)" @mouseup="drop()" v-if="bounds.minX">
<line v-for="link in graph.links" :x1="coords[link.source.index].x" :y1="coords[link.source.index].y" :x2="coords[link.target.index].x" :y2="coords[link.target.index].y" stroke="black" stroke-width="2"/>
<circle v-for="(node, i) in graph.nodes" :cx="coords[i].x" :cy="coords[i].y" :r="20" :fill="colors[Math.ceil(Math.sqrt(node.index))]" stroke="white" stroke-width="1" @mousedown="currentMove = {x: $event.screenX, y: $event.screenY, node: node}"/>
</svg>
</div>

Javascript:

new Vue({
el: '#app',
data: {
graph: {
nodes: d3.range(100).map(i => ({ index: i, x: null, y: null })),
links: d3.range(99).map(i => ({ source: Math.floor(Math.sqrt(i)), target: i + 1 }))
},
width: Math.max(document.documentElement.clientWidth, window.innerWidth || 0),
height: Math.max(document.documentElement.clientHeight, window.innerHeight || 0) - 40,
padding: 20,
colors: ['#2196F3', '#E91E63', '#7E57C2', '#009688', '#00BCD4', '#EF6C00', '#4CAF50', '#FF9800', '#F44336', '#CDDC39', '#9C27B0'],
simulation: null,
currentMove: null
},
computed: {
bounds() {
return {
minX: Math.min(...this.graph.nodes.map(n => n.x)),
maxX: Math.max(...this.graph.nodes.map(n => n.x)),
minY: Math.min(...this.graph.nodes.map(n => n.y)),
maxY: Math.max(...this.graph.nodes.map(n => n.y))
}
},
coords() {
return this.graph.nodes.map(node => {
return {
x: this.padding + (node.x - this.bounds.minX) * (this.width - 2*this.padding) / (this.bounds.maxX - this.bounds.minX),
y: this.padding + (node.y - this.bounds.minY) * (this.height - 2*this.padding) / (this.bounds.maxY - this.bounds.minY)
}
})
}
},
created(){
this.simulation = d3.forceSimulation(this.graph.nodes)
.force('charge', d3.forceManyBody().strength(d => -100))
.force('link', d3.forceLink(this.graph.links))
.force('x', d3.forceX())
.force('y', d3.forceY())
},
methods: {
drag(e) {
if (this.currentMove) {
this.currentMove.node.fx = this.currentMove.node.x - (this.currentMove.x - e.screenX) * (this.bounds.maxX - this.bounds.minX) / (this.width - 2 * this.padding)
this.currentMove.node.fy = this.currentMove.node.y -(this.currentMove.y - e.screenY) * (this.bounds.maxY - this.bounds.minY) / (this.height - 2 * this.padding)
this.currentMove.x = e.screenX
this.currentMove.y = e.screenY
}
},
drop(){
delete this.currentMove.node.fx
delete this.currentMove.node.fy
this.currentMove = null
this.simulation.alpha(1)
this.simulation.restart()
}
}
})

我看到的主要缺点是,如果你有一个大型 d3.js 代码库,你想在你的 Vue.js 应用程序中重用,因为你将不得不重写它。您还会发现很多用纯 d3.js 语法编写的示例,您将不得不调整它们。

关于d3.js - 如何为 Vue.js 实现 D3,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41067022/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com