antv x6使用(支持节点排序、新增节点、编辑节点、删除节点、选中节点)
项目需要实现如下效果流程图,功能包括节点排序、新增节点、编辑节点、删除节点、选中节点等

html部分如下:
<template><div class="MindMapContent"><el-button size="small" @click="addNode">新增节点</el-button><el-button size="small" @click="updateNode">编辑节点</el-button><el-button size="small" type="danger" plain @click="removeNode">删除节点</el-button><div id="mindContent" style="height: 300px"><div id="container"></div></div><el-dialog v-model="visible" :title="pageType == 'edit' ? '编辑' : '新增'"><div><el-form class="search-form" ref="formData" size="small" label-width="120px" :model="formData"><el-form-item label="节点名称" prop="label" :rules="[{required: true, message: '请输入节点名称',trigger: 'blur'}]"><el-input v-model="formData.label" style="width: 60%"></el-input></el-form-item></el-form></div><span slot="footer" class="dialog-footer"><el-button @click="cancelDialog">返回</el-button><el-button type="primary" @click="submitData">提交</el-button></span></el-dialog></div>
</template>
需要后后端返回的数据格式如下:
mindData: {edgeList: [{source: '50',target: '54'},{source: '50',target: '61'},{source: '54',target: '66'},{source: '61',target: '67'},{source: '67',target: '69'},{source: '50',target: '71'},],nodeList: [{id: '50', label: '根节点'},{id: '54', label: '111'},{id: '61', label: '222'},{id: '66', label: '333'},{id: '67', label: '444'},{id: '69', label: '555'},{id: '71', label: '666'},]
}
获取后端返回数据后, 需要为节点和边设置样式,所以需要对数据进行处理。x6图最好只加载一次,后续再进行操作时只需要更新数据即可。因为在项目中可以为某个节点绑定其它属性id,绑定后仍保持选中状态,所以设置selectNodeId,当有selectNodeId时,需要选中node.id为selectNodeId的节点
//获取节点数据getNodeData(bool,selectNodeId){this.objData.nodes = (this.mindData.nodeList || []).map(item => {return {id: item.id, // String,可选,节点的唯一标识width: 120, // Number,可选,节点大小的 width 值height: 30, // Number,可选,节点大小的 height 值label: item.label, // String,节点标签data: {portalId: item.portalId || '',},attrs: {body: {stroke: 'rgba(238, 238, 238, 1)',strokeWidth: 1,rx: 5,ry: 5,style: {filter: 'drop-shadow(0px 0px 8px rgba(0,0,0,0.07))'}},label: {fontSize: 12,textWrap: {ellipsis: true,width: 105}}}}})this.objData.edges = (this.mindData.edgeList || []).map(item => {return{source: item.source, // String,必须,起始节点 idtarget: item.target, // String,必须,目标节点 idrouter: {name: 'manhattan',args: {startDirections: ['right'],endDirections: ['left']}},attrs: {line: {stroke: '#1d6ee4'}}}})//初始化加载mind,更新数据时不初始化mindif(bool){this.initGraph()}else {this.graph.cleanSelection()this.nowData = {}//更新节点信息后重新布局 let gridLayout = new DagreLayout({type: 'dagre',rankdir: 'LR',align: undefined,ranksep: 45,nodesep: 5,})this.graph.fromJSON(gridLayout.layout(this.objData))//如果有selectNodeId,则选中node.id为selectNodeId的节点if (selectNodeId) {const node = this.graph.getCellById(selectNodeId)if (node) {this.graph.resetSelection(node)this.nowData = {id: node.id,label: node.label,portalId: node.data.portalId || ''}//返回选中的数据 this.$emit('getData', this.nowData)}}}},
初始化画布
// 初始化流程图画布initGraph() {let container = document.getElementById('container')this.graph = nullthis.graph = new Graph({container,width: '100%',height: '100%',//最大最小缩放比例scaling: {min: 0.7,max: 1.2},autoResize: true,panning: true,mousewheel: true,background: {color: '#ffffff', // 设置画布背景颜色},})//使用布局插件自动布局 let gridLayout = new DagreLayout({type: 'dagre',rankdir: 'LR',align: undefined,ranksep: 45,nodesep: 5,})//渲染布局数据this.graph.fromJSON(gridLayout.layout(this.objData))//使用x6选中插件this.graph.use(new Selection({enabled: true,multiple: false,movable: false,rubberband: false,showNodeSelectionBox: true,clearSelectionOnBlank: false}))//节点点击选中 this.graph.on('node:click', ({ e,node }) => {e.stopPropagation()tooltip.style.display = 'none'this.graph.resetSelection(node)this.nowData = {id: node.id,label: node.label,portalId: node.data.portalId || ''}this.$emit('getData',this.nowData)})//点击节点外清空点击数据 this.graph.on('blank:click', ({ e,node }) => {this.graph.cleanSelection()this.nowData = {}})//node节点有宽度限制,label超过宽度时显示...,但是需要tooltip显示完整的label const tooltip = document.createElement('div')tooltip.className = 'x6-tooltip'tooltip.style.position = "absolute"tooltip.style.display = 'none'tooltip.style.padding = '6px'tooltip.style.borderRadius = '5px'tooltip.style.backgroundColor = '#303133'tooltip.style.color = '#ffffff'tooltip.style.fontSize = '12px'let mindContent = document.getElementById('mindContent')mindContent.appendChild(tooltip)this.graph.on('node:mouseenter', ({ node }) => {if(node.label){const position = this.graph.localToGraph(node.getBBox().getCenter())tooltip.style.display = 'block'tooltip.style.left = `${position.x - 60}px`tooltip.style.top = `${position.y - 50}px`tooltip.textContent = node.label}})this.graph.on('node:mouseleave', ({ node }) => {tooltip.style.display = 'none'})},
节点操作
//删除节点removeNode(){if(!this.nowData.id){this.$message.error('请选择需要删除的节点')}else{this.mindData.nodeList = this.mindData.nodeList.filter(item => item.id != this.nowData.id)this.mindData.edgeList = this.mindData.edgeList.filter(item => item.target != this.nowData.id)this.getNodeData(false)}},//新增节点addNode(){this.formData = {}this.pageType = 'add'if (this.objData.nodes.length == 0){this.visible = true} else{if(!this.nowData.id){this.$message.error('请选择父节点')}else{this.visible = true}}},//编辑节点updateNode(){this.formData = {}this.pageType = 'edit'if(!this.nowData.id){this.$message.error('请选择编辑的节点')}else{this.formData = this.nowDatathis.visible = true}},
新增节点和编辑节点弹窗操作
//cancelDialogcancelDialog(){this.visible = false},submitData(){// 新增的时候,formData就是新增本身,nowData就是父节点// 编辑的时候,获取到nowData,赋值给formDatathis.$refs.formData.validate(valid => {if(valid){if (this.pageType == 'edit'){let obj = this.mindData.nodeList.find(item => item.id == this.formData.id)obj.label = this.formData.labelthis.visible = falsethis.getNodeData(false)}else{let id = Math.random().toString(36).substring(2, 4)this.mindData.nodeList.push({id, label: this.formData.label,})this.mindData.edgeList.push({target: id, source: this.nowData.id,})this.visible = falsethis.getNodeData(false)}}})},
涉及的样式
<style scoped>
.MindMapContent{padding: 10px 25px;height: 350px;background-color: #ffffff;
}
#mindContent{position: relative;
}
</style>
项目地址
相关文章:
antv x6使用(支持节点排序、新增节点、编辑节点、删除节点、选中节点)
项目需要实现如下效果流程图,功能包括节点排序、新增节点、编辑节点、删除节点、选中节点等 html部分如下: <template><div class"MindMapContent"><el-button size"small" click"addNode">新增节点&…...
DP主站如何华丽变身Modbus TCP网关!
DP主站如何华丽变身Modbus TCP网关! 在工业自动化领域,Profibus DP和Modbus TCP是两种常用的通信协议。Profibus DP通常应用于制造业自动化场景,而Modbus TCP则广泛使用于工业自动化和楼宇自动化等领域。为了实现这两种协议之间的互联互通&a…...
榕壹云在线商城系统:基于THinkPHP+ Mysql+UniApp全端适配、高效部署的电商解决方案
项目背景:解决多端电商开发的痛点 随着移动互联网的普及和用户购物习惯的碎片化,传统电商系统面临以下挑战: 1. 多平台适配成本高:需要同时开发App、小程序、H5等多端应用,重复开发导致资源浪费。 2. 技术依赖第三方…...
Pinia最基本用法
1. 定义 Store 首先,定义一个 Pinia Store,使用组合式 API 风格和 ref 来管理状态。 示例:stores/ids.js import { defineStore } from pinia; import { ref } from vue;export const useIdsStore defineStore(ids, () > {const ids …...
Android studio打包uniapp插件
一.参考资料与环境准备 原生工程配置需要使用到Android studio和HbuilderX 当前测试的as版本-20240301,下载地址:HbuilderX版本:4.36 二.插件创建流程 1.导入下载的UniPlugin-Hello-AS工程(下载地址见参考资料) 2.生成jks证书…...
App Cleaner Pro for Mac 中 Mac软件卸载工具
App Cleaner Pro for Mac 中 Mac软件卸载工具 一、介绍 App Cleaner & Uninstaller Pro Mac破解,是一款Mac软件卸载工具,残余垃圾清除工具!可以卸载应用程序或只删除不需要的服务文件,甚至可以删除以前删除的应用程序中的文…...
多线程与Tkinter界面交互
在现代图形用户界面(GUI)应用程序中,可能会遇到需要长时间运行的任务,例如网络请求、数据处理或文件读取等。如果这些任务直接在主线程中运行,会导致GUI界面“卡顿”或“不响应”。为了保持界面流畅和响应用户操作,我们可以通过使用多线程来将这些任务移到后台运行。然而…...
开发规范——Restful风格
目录 Restful Apifox 介绍 端口号8080怎么来的? 为什么要使用Apifox? Restful 如果请求方式是Post,那我就知道了要执行新增操作,要新增一个用户 如果请求方式是Put,那就代表我要修改用户 具体要对这些资源进行什么样的操…...
大模型——Llama Stack快速入门 部署构建AI大模型指南
Llama Stack快速入门 部署构建AI大模型指南 介绍 Llama Stack 是一组标准化和有主见的接口,用于如何构建规范的工具链组件(微调、合成数据生成)和代理应用程序。我们希望这些接口能够在整个生态系统中得到采用,这将有助于更轻松地实现互操作性。 Llama Stack 定义并标准化…...
符号右移“ >>= “ 与 无符号右移“ >>>= “ 的区别
符号右移" >> " 与 无符号右移" >>> " 的区别 一、符号右移" >> " 与 无符号右移" >>> " 的区别1. 符号右移(>>)与无符号右移(>>>)的区别…...
利用阿里云企业邮箱服务实现Python群发邮件
目录 一、阿里云企业邮箱群发邮件全流程实现 1. 准备工作与环境配置 2. 收件人列表管理 3. 邮件内容构建 4. 附件添加实现 5. 邮件发送核心逻辑 二、开发过程中遇到的问题与解决方案 1. 附件发送失败问题 2. 中文文件名乱码问题 3. 企业邮箱认证失败 三、完整工作流…...
探秘 Ruby 与 JavaScript:动态语言的多面风采
1 语法特性对比:简洁与灵活 1.1 Ruby 的语法优雅 Ruby 的语法设计旨在让代码读起来像自然语言一样流畅。它拥有简洁而富有表现力的语法结构,例如代码块、符号等。 以下是一个使用 Ruby 进行数组操作的简单示例: # 定义一个数组 numbers [1…...
08-JVM 面试题-mk
文章目录 1.JVM 的各部分组成2.运行时数据区2.1.什么是程序计数器?2.2.你能给我详细的介绍Java堆吗?2.3.能不能解释一下方法区?2.3.1常量池2.3.2.运行时常量池2.4.什么是虚拟机栈?2.4.1.垃圾回收是否涉及栈内存?2.4.2.栈内存分配越大越好吗?2.4.3.方法内的局部变量是否线…...
PostgreSQL技术大讲堂 - 第86讲:数据安全之--data_checksums天使与魔鬼
PostgreSQL技术大讲堂 - 第86讲,主题:数据安全之--data_checksums天使与魔鬼 1、data_checksums特性 2、避开DML规则,嫁接非法数据并合法化 3、避开约束规则,嫁接非法数据到表中 4、避开数据检查,读取坏块中的数据…...
DOM解析XML:Java程序员的“乐高积木式“数据搭建
各位代码建筑师们!今天我们要玩一个把XML变成内存乐高城堡的游戏——DOM解析!和SAX那种"边看监控边破案"的刺激不同,DOM就像把整个乐高说明书一次性倒进大脑,然后慢慢拼装(内存:你不要过来啊&…...
C++ 入门六:多态 —— 同一接口的多种实现之道
在面向对象编程中,多态是最具魅力的特性之一。它允许我们通过统一的接口处理不同类型的对象,实现 “一个接口,多种实现”。本章将从基础概念到实战案例,逐步解析多态的核心原理与应用场景,帮助新手掌握这一关键技术。 …...
关于获取文件大小的方法总结
编程开发中,获取文件大小是一项常见的需求,无论是进行文件管理、数据传输还是资源监控等操作,都可能需要知道文件的具体大小。下面将介绍几种常见的获取文件大小的方式,并进行对比分析。 几种可行的文件大小获取方式 1. 使用 fs…...
从宇树摇操avp_teleoperate到unitree_IL_lerobot:如何基于宇树人形进行二次开发(含Open-TeleVision源码解析)
前言 如之前的文章所述,我司「七月在线」正在并行开发多个订单,目前正在全力做好每一个订单,因为保密协议的原因,暂时没法拿出太多细节出来分享 但可以持续解读我们所创新改造或二次开发的对象,即解读paper和开源库…...
告别 ifconfig:为什么现代 Linux 系统推荐使用 ip 命令
告别 ifconfig:为什么现代 Linux 系统推荐使用 ip 命令 ifconfig 指令已经被视为过时的工具,不再是查看和配置网络接口的推荐方式。 与 netstat 被 ss 替代类似。 本文简要介绍 ip addr 命令的使用 简介ip ifconfig 属于 net-tools 包,这个…...
MySQL——MVCC(多版本并发控制)
目录 1.MVCC多版本并发控制的一些基本概念 MVCC实现原理 记录中的隐藏字段 undo log undo log 版本链 ReadView 数据访问规则 具体实现逻辑 总结 1.MVCC多版本并发控制的一些基本概念 当前读:该取的是记录的最新版本,读取时还要保证其他并发事务…...
Gateway-网关-分布式服务部署
前言 什么是API⽹关 API⽹关(简称⽹关)也是⼀个服务, 通常是后端服务的唯⼀⼊⼝. 它的定义类似设计模式中的Facade模式(⻔⾯模式, 也称外观模式). 它就类似整个微服务架构的⻔⾯, 所有的外部客⼾端访问, 都需要经过它来进⾏调度和过滤. 常⻅⽹关实现 Spring Cloud Gateway&a…...
火影 遇上 python Baby_Brother_GGY
上视频先~ 66666 import pygame import random import sys import math from pygame.locals import *# 初始化pygame pygame.init() pygame.mixer.init()# 屏幕设置 WIDTH, HEIGHT 1480, 750 screen pygame.display.set_mode((WIDTH, HEIGHT)) py…...
Docker部署MySQL大小写不敏感配置与数据迁移实战20250409
Docker部署MySQL大小写不敏感配置与数据迁移实战 🧭 引言 在企业实际应用中,尤其是使用Java、Hibernate等框架开发的系统,MySQL默认的大小写敏感特性容易引发各种兼容性问题。特别是在Linux系统中部署Docker版MySQL时,默认行为可…...
面试题之网络相关
最近开始面试了,410面试了一家公司 问了我几个网络相关的问题,我都不会!!现在来恶补一下,整理到博客中,好难记啊,虽然整理下来了。在这里先祝愿大家在现有公司好好沉淀,定位好自己的…...
使用MPI-IO并行读写HDF5文件
使用MPI-IO并行读写HDF5文件 HDF5支持通过MPI-IO进行并行读写,这对于大规模科学计算应用非常重要。下面我将提供C和Fortran的示例程序,展示如何使用MPI-IO并行读写HDF5文件。 准备工作 在使用MPI-IO的HDF5之前,需要确保: HDF5库编译时启用…...
[春秋云镜] Tsclient仿真场景
文章目录 靶标介绍:外网mssql弱口令SweetPotato提权上线CSCS注入在线用户进程上线 内网chisel搭建代理密码喷洒攻击映像劫持 -- 放大镜提权krbrelayup提权Dcsync 参考文章 考点: mssql弱口令SweetPotato提权CS注入在线用户进程上线共享文件CS不出网转发上线密码喷洒…...
在人工智能与计算机技术融合的框架下探索高中教育数字化教学模式的创新路径
一、引言 1.1 研究背景 在数字中国战略与《中国教育现代化 2035》的政策导向下,人工智能与计算机技术的深度融合正深刻地重构着教育生态。随着科技的飞速发展,全球范围内的高中教育都面临着培养具备数字化素养人才的紧迫需求,传统的教学模式…...
数据集 handpose_x_plus 3D RGB 三维手势 - 手工绘画 场景 draw picture
数据集 handpose 相关项目地址:https://github.com/XIAN-HHappy/handpose_x_plus 样例数据下载地址:数据集handpose-x-plus3DRGB三维手势-手工绘画场景drawpicture资源-CSDN文库...
deskflow使用教程:一个可以让两台电脑鼠标键盘截图剪贴板共同使用的开源项目
首先去开源网站下载:Release v1.21.2 deskflow/deskflow 两台电脑都要下载这个文件 下载好后直接打开找到你想要的exe desflow.exe 然后你打开他,将两台电脑的TLS都关掉 下面步骤两台电脑都要完成: 电脑点开edit-》preferences 把这个取…...
详解MYSQL表空间
目录 表空间文件 表空间文件结构 行格式 Compact 行格式 变长字段列表 NULL值列表 记录头信息 列数据 溢出页 数据页 当我们使用MYSQL存储数据时,数据是如何被组织起来的?索引又是如何组织的?在本文我们将会解答这些问题。 表空间文…...
