首页 > 其他分享 >d3.js+vue生成动力图

d3.js+vue生成动力图

时间:2024-07-15 15:55:11浏览次数:25  
标签:vue const attr js source data d3 target

本文主要实现了动力图中:

        节点的显示;

        节点与节点之间关系的连接,以及对应的关系类型的显示;

        节点的拖拽;

        图谱的缩放

1.先上效果:

2. 以下是完整的代码部分:

<template>
  <div ref="chart" className="ggraph"></div>
</template>

<script>
import * as d3 from 'd3';

export default {
  data() {
    return {
      nodes: [
        {id: 1, name: '刘备', type: '皇上'},
        {id: 2, name: '关羽', type: '将军'},
        {id: 3, name: '张飞', type: '将军'},
        {id: 4, name: '诸葛亮', type: '丞相'},
        {id: 5, name: '小兵1', type: '士兵'},
        {id: 6, name: '小兵2', type: '士兵'},
      ],
      links: [
        {source: 1, target: 2, relate: '将军'},
        {source: 1, target: 3, relate: '将军'},
        {source: 1, target: 4, relate: '丞相'},
        {source: 2, target: 5, relate: '下属'},
        {source: 2, target: 6, relate: '下属'},
        {source: 3, target: 5, relate: '下属'},
      ]
    };
  },
  mounted() {
    this.drawChart();
  },
  methods: {
    drawChart() {
      const data = {
        nodes: this.nodes,
        links: this.links
      };

      const width = 600;
      const height = 400;

      // 创建SVG容器
      const svg = d3.select(this.$refs.chart)
        .append('svg')
        .attr('width', width)
        .attr('height', height);

      const g = svg.append('g'); // 将 g 元素放在 svg 元素内部

      // 创建力导向图模拟器
      const simulation = d3.forceSimulation(data.nodes)
        .force('link', d3.forceLink(data.links).id(d => d.id).distance(100))
        .force('charge', d3.forceManyBody())
        .force('center', d3.forceCenter(width / 2, height / 2));
      // 创建边
      const link = g.selectAll('line')
        .data(data.links)
        .enter()
        .append('line')
        .attr('stroke', '#999')
        .attr('stroke-width', 2)
      //创建节点
      const node = g.selectAll('.node')
        .data(data.nodes)
        .enter()
        .append('g')
        .attr('class', 'node')
        .style('fill', 'black');
      node.append('circle')
        .attr('r', 18)
        .attr('fill', 'steelblue')
        .style('fill', 'blue')
        .call(d3.drag() //节点拖拽
          .on('start', dragstarted)
          .on('drag', dragged)
          .on('end', dragended));
      //节点上面显示文字
      node.append('text')
        .text(d => d.name)
        .attr('text-anchor', 'middle')
        .attr('dy', 4)
        .attr('font-size', d => Math.min(2 * d.radius, 20))
        .attr('fill', 'black')
        .style('pointer-events', 'none');
      // 连线文字
      const linkText = g.selectAll('.linktext')
        .data(data.links)
        .enter()
        .append('text')
        .attr('class', 'linktext')
        .style('fill', 'black')
        .style('font-size', 8)
        .style('text-anchor', 'middle')
        .text(d => d.relate)
        .style('pointer-events', 'none');

      // 缩放
      svg.call(d3.zoom().on("zoom", function (event) {
        g.attr("transform", event.transform);
      }));
      // 监听力导向图模拟器的tick事件,更新节点和边的位置
      simulation
        .on('tick', () => {
          link
            .attr('x1', d => d.source.x)
            .attr('y1', d => d.source.y)
            .attr('x2', d => d.target.x)
            .attr('y2', d => d.target.y);

          node.attr('transform', d => `translate(${d.x},${d.y})`);
          // 更新连线文字的位置
          linkText
            .attr('x', d => (d.source.x + d.target.x) / 2)
            .attr('y', d => (d.source.y + d.target.y) / 2);
        });

      function dragstarted(event, d) {
        if (!event.active) simulation.alphaTarget(0.5).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;
      }
    }
  }
};
</script>

<style>
svg {
  background-color: #d1e9ff;
}
</style>

标签:vue,const,attr,js,source,data,d3,target
From: https://blog.csdn.net/m0_54479027/article/details/140440995

相关文章

  • 【vue深入学习第2章】Vue.js 中的 Ajax 处理:vue-resource 库的深度解析
    Vue.js中的Ajax处理:vue-resource库的深度解析在现代前端开发中,Ajax请求是与后端进行数据交互的关键技术。Vue.js作为一个渐进式JavaScript框架,提供了多种方式来处理Ajax请求,其中vue-resource是一个较为常用的库。尽管vue-resource在Vue2.x之后不再是官方推荐的......
  • 2024-07-15 记录一则vue网站优化的小技巧
    vite+vue+某框架写的网站可以通过配置vite.config.js中的build.rollupOptions.output.manualChunks来手动分割指定的包到指定的文件夹内,然后在网站入口文件按照需求引入比如:build:{rollupOptions:{output:{manualChunks:{antd......
  • vue3中的props和emit
    首先我们要明确props和emit是在父子组件(嵌套组件)中使用的。想要在父组件中渲染出子组件里的内容,需要在父组件中导入子组件,并在模板中渲染子组件。那父子组件中如何通信呢?就需要使用到props和emit。props当子组件要接受父组件传递的数据信息时,也可以说是父组件传递数据给子......
  • vue ui + 项目创建 (基于vue脚手架创建项目)
    =======================注意全程都不要关闭cmd窗口========================= 在想要创建项目的文件目录输入cmd回车,再输入vueui (如果出现报错,可能是因为有hadoop,存在hadoop的环境变量会报错,但也能打开网页)出现下图创建——》在此创建新项目 如下图,项目名不要有中文......
  • Spring Boot Vue 毕设系统讲解 11【协同过滤方法教学】
    目录1.基础知识用户基于的协同过滤(User-basedCF)物品基于的协同过滤(Item-basedCF)优缺点实际应用2.项目功能实战1.基础知识协同过滤(CollaborativeFiltering,CF)是一种广泛应用于推荐系统中的算法,它通过分析和利用用户与物品之间的交互信息来发现用户可能感兴趣......
  • 在 package.json 文件中,版本号前的 ^ 符号含义
    在package.json文件中,版本号前的^符号表示兼容某个主版本(majorversion)的更新。具体来说,^符号允许自动安装具有相同主版本号的更新版本,但不包括主版本号变更的版本。例如:***"^1.2.3"允许的版本范围是>=1.2.3<2.0.0。这意味着会自动安装1.2.4、1.3.0等版本,但不会安装......
  • 【vue深入学习第1章】探索 Vue 2 的生命周期:从创建到销毁
    Vue.js是一个渐进式的JavaScript框架,用于构建用户界面。理解Vue的生命周期是掌握这个框架的关键之一。在这篇博客中,我们将深入探讨Vue2的生命周期,并通过代码示例来展示每个生命周期钩子的作用。Vue实例的生命周期Vue实例的生命周期可以分为四个主要阶段:创建阶段:初始......
  • Vue3+Element Plus 使用sortablejs对el-table表格进行拖拽
    sortablejs官网:点击跳转一、安装sortablejsnpminstallsortablejs--save二、 页面按需引入importSortablefrom'sortablejs';三、组件方法1.temlate:<template><el-tableref="tableHeader":data="tableData"row-key="id"style=&quo......
  • vue3+Element Plus 自定义表格单选 多选
    项目背景:用vue3+elementplus做一套考试系统功能场景:添加试题中分为客观题、主观题两种类型,在客观题会出现单选题、多选题两种类型就会导致单选题只能勾选一个答案、多选题能勾选多个答案。效果图废话不说直接上代码<el-buttonclass="btn"icon="Plus"plainst......
  • Vue2中的进度条案例
     v-bind对于样式控制的增强--操作style语法::style=“样式对象”适用于某个具体属性的动态设置<divclass="box":style="{css属性名1:css属性值,css属性名2:css属性值}"></div><!DOCTYPEhtml><htmllang="en"><head><metacharset=......