d3 -力引导图(四) vue项目中的使用及可能遇到的问题(v7版本)

如果采用npm方式安装d3的话, 一般默认都会安装最近的版本, 目前d3已经更新到了 v7版本.

vue中安装d3:

npm install d3 --save-dev

或者

cnpm install d3 --save-dev

然后在组件中引入d3:

import * as d3 from 'd3';

问题一 节点拖动

前面在非vue项目中使用时, 我们都是采用在线引入v5版本的方式, 将之前的代码修修改改复制粘贴到vue项目里的时候, 会遇到一个问题:

当绘制力引导的图的时候是成功的, 但是当我们试图拖动节点的时候, 会发现节点无法被拖动, 而且红色选中的这两行会报错, 但在之前的v5版本中, 是没有这个问题的.

错误代码:
请添加图片描述
报错信息:
请添加图片描述
网上并没有找到相应的资料, 只发现了某国外网站针对这个问题的两个提问, 所以只能靠自己发现问题了.

首先要知道这几个函数 started, dragged, ended 是用来控制节点拖拽的.
打个断点, 我们可以看到传入的d的具体数据:
在这里插入图片描述
d 下面有 active, 所以猜测可以直接把 if 条件改成 !d.active, 再结合 d3实例这部分的代码 (虽然结构不一样但是有参考意义):
在这里插入图片描述
最终把代码修改成下面这个样子, 发现节点可以正常被拖动啦!

            function started(d) {
                if (!d.active) {
                    forceSimulation.alphaTarget(0.8).restart();
                }
                d.subject.fx = d.subject.x;
                d.subject.fy = d.subject.y;
            }
            function dragged(d) {
                d.subject.fx = d.x;
                d.subject.fy = d.y;
            }
            function ended(d) {
                if (!d.active) {
                    forceSimulation.alphaTarget(0);
                }
                d.subject.fx = null;
                d.subject.fy = null;
            }

效果:
在这里插入图片描述

问题二 绑定事件

之前在v5版本中添加双击事件, 是可以正常地在警示框中展示节点内容的.

之前的代码:
在这里插入图片描述
但是在vue安装的v7版本中, 发现双击事件不管用了, 弹出 undefined, 于是我把 n 输出了一下, 发现 n 变成了一个事件, 而不是当前的节点信息了:
在这里插入图片描述

抱着侥幸心理, 我在function中传入了两个参数, 发现第二个参数中才包含当前节点的信息:
在这里插入图片描述

在这里插入图片描述
弹框中也可以看到正确的信息了:
在这里插入图片描述
绘制节点, 节点文本和绑定事件这部分的代码为:

            //draw nodes group = node+node-text
            var nodes_g = svg.append("g")
                .selectAll("g")
                .data(data.nodes)
                .enter()
                .append("g")
                .attr("transform", function (e) {
                    return "translate(" + e.x + "," + e.y + ")";
                })
                .call(d3.drag()
                    .on("start", started)
                    .on("drag", dragged)
                    .on("end", ended));
            //draw nodes
            nodes_g.append("circle")
                .attr("r", function (e) {
                    return e.relation_num * 5
                })
                .attr("fill", function(n){
                    for(let i = 0; i<ontologyList.length;i++){
                        if(n.ontology_name == ontologyList[i]){
                            return d3.interpolateSpectral(scale(i))
                        }
                    }
                })
                

            //draw node-text
            nodes_g.append("text")
                .attr("x", -15)
                .attr("y", 20)
                .attr("font-size", 10)
                .text(function (e) { return e.entity_name });


            nodes_g.on("dblclick", function(n,i){
                    alert(i.entity_id)
            });
<think>好的,用户想在Vue2中集成和使用D3.js,我需要根据提供的引用资料来给出解答。首先,引用[1]提到了Vue-D3插件,虽然引用里提到的是Vue.js应用,但Vue2和Vue3在插件机制上有相似之处,可能需要调整。然后引用[2]和[3]是关于Vue3和D3的基础集成,比如引入库和组件化方法,但用户需要的是Vue2的指导。 我应该先讲安装D3.js,用npm或者CDN方式。引用[3]展示了在HTML中引入脚本的方法,这在Vue2的public/index.html里适用。然后组件中使用可能需要mounted钩子初始化D3,因为这候DOM已经挂载。数据更新的响应式处理,可以用watch或者计算属性,引用[1]提到Vue-D3的响应式更新,可以借鉴。组件化部分,将D3表封装成Vue组件,引用[1]和[2]都提到这点,所以需要强调复用性。 可能问题包括版本兼容,比如D7Vue2是否有冲突,以及性能优化,避免频繁DOM操作。需要提醒用户注意在beforeDestroy中清理D3事件或元素,避免内存泄漏。示例代码部分,参考引用里的代码结构,用mounted里的d3.select,并绑定数据。最后生成相关问题,覆盖优化、对比Vue3、常见问题等。</think>### 分步指南:在 Vue 2 中集成和使用 D3.js #### 1. 安装 D3.js **方法一(推荐)**:通过 npm/yarn 安装 ```bash npm install d3 --save # 或 yarn add d3 ``` **方法二**:CDN 引入 在 `public/index.html` 中添加: ```html <script src="https://d3js.org/d3.v7.min.js"></script> ``` (注意版本兼容性,D3 v5+ 适用于现代浏览器)[^3] #### 2. 创建 Vue 组件 新建 `D3Chart.vue` 组件: ```vue <template> <div ref="chartContainer" class="d3-chart"></div> </template> <script> import * as d3 from &#39;d3&#39;; // 若通过 npm 安装 export default { data() { return { dataset: [10, 20, 30, 40, 50] }; }, mounted() { this.initChart(); }, methods: { initChart() { const container = d3.select(this.$refs.chartContainer); const svg = container.append("svg") .attr("width", 400) .attr("height", 200); svg.selectAll("rect") .data(this.dataset) .enter() .append("rect") .attr("x", (d, i) => i * 50) .attr("y", d => 200 - d * 3) .attr("width", 40) .attr("height", d => d * 3) .attr("fill", "steelblue"); } } }; </script> ``` #### 3. 响应式更新 通过 Vue 的响应式特性实现数据更新同步: ```vue watch: { dataset(newVal) { this.updateChart(newVal); } }, methods: { updateChart(data) { const bars = d3.select(this.$refs.chartContainer) .select("svg") .selectAll("rect") .data(data); // 更新现有元素 bars.attr("height", d => d * 3) .attr("y", d => 200 - d * 3); // 处理新增元素 bars.enter() .append("rect") /* ...属性设置同初始化... */; // 处理移除元素 bars.exit().remove(); } } ``` #### 4. 组件化最佳实践 - **封装交互逻辑**:将缩放、拖拽等 D3 交互事件与 Vue 的 `@event` 结合 - **性能优化**:对大数据集使用虚拟滚动技术(如 `d3-zoom` + 动态渲染) - **清理资源**:在 `beforeDestroy` 生命周期中移除 D3 事件监听器 --- ### 常见问题解答 **Q:D3 操作 DOM 与 Vue 的虚拟 DOM 冲突吗?** A:若 D3 仅操作其控制的 SVG 区域(通过 `ref` 指定),不会影响 Vue 的其他渲染逻辑。需避免直接操作 Vue 模板中的 DOM 元素。 **Q:如何处理动态数据更新?** A:推荐使用 D3 的 `data-join` 模式(`enter/update/exit`),配合 Vue 的响应式数据变化,如示例中的 `watch` 实现[^1]。 --- ###
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Charonmomo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值