在vue3中浅尝antv X6 2.0 demo(三)

这篇具有很好参考价值的文章主要介绍了在vue3中浅尝antv X6 2.0 demo(三)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

终于抽空把antv X6 2.0这个版本的demo抽出来了,原以为项目会一直使用vue3去做这个流程,结果最近项目经理说antv X6的菜单功能只有react才能用...然鹅...写到菜单模块的时候,发现都可以用的...

目前我项目里面react版本的多一些功能(如:新增节点时自动布局、右键菜单,如图)

在vue3中浅尝antv X6 2.0 demo(三),前端,前端框架,vue.js

这篇记一下这个小demo的一些功能和实现~~~

(附上demo仓库连接: https://github.com/Tipchak5/vue3_antv_X6_2.0.git)

  • 导入模版 (画布中的节点是点击插入模版直接形成的,且左侧目录树与模板的关系是相对应的,目录树的label我用的是节点id来显示的)

在vue3中浅尝antv X6 2.0 demo(三),前端,前端框架,vue.js

 代码实现:

1、先引入模版数据tsakMasterplate(后期应该是调后端接口选择模版导入)

2、直接调这个leadInMasterplate方法,导入模板前会先清空画布

const tsakMasterplate = ref(require('../../assets/masterplate.json')); // 引入模版数据

/** 导入模版 */
const leadInMasterplate = async () => {
	// 清空所有单元格
	const cells = graph.getCells(); // 获取所有单元格
	graph.removeCells(cells); // 画布清空
	// 模版渲染
	await new Promise((resolve) => setTimeout(resolve, 100));
	graph.fromJSON(tsakMasterplate.value).centerContent(); // 引入模版数据 这里tsakMasterplate是我自己写的一个死数据
	// 对应的目录树
	treeInfo.value = [
		{
			label: 'node2',
			children: [
				{
					label: 'task2',
					children: [
						{
							label: 'task3',
							children: [],
						},
						{
							label: 'task5',
							children: [],
						},
					],
				},
			],
		},
	];
};

  • 导出json(其实导出json就相当于创建了一个模版,以json的格式将你要常用的节点模版传给后端,以便后期调用)

  • 在vue3中浅尝antv X6 2.0 demo(三),前端,前端框架,vue.js

    代码实现:

// 导出json
function printNodeList() {
	console.log(graph.toJSON(), '导出数组');
	console.log(JSON.stringify(graph.toJSON({ diff: true })), 'JSON');
	graph.clearCells();
}

  • 新增节点

  • <el-button type="primary" :icon="Plus" :title="task" 
        @mousedown="startDrag(task, $event)" >新增{{ task }}
    </el-button>
    
    const task = ref('任务');
    
    // 新增任务节点
    const startDrag = (type) => {
    
    	const tree = startDragToGraph(graph, type); // graph就是初始化的画布 因为我是将startDragToGraph方法抽出来放在公共js中直接调用的 所以传了graph 如果你在当前页面就不需要传了
    
    	id.value = tree.id;
    	const label = { label: tree.id, children: [] };
    	treeInfo.value[0].children.push(label); // 更新树目录
    };
    
    // 这里startDragToGraph方法如下
    let count = 0;
    const startDragToGraph = (graph, type) => {
    	let node = null;
    
    	node = graph.addNode({
    		shape: 'custom-rect',
    		attrs: {
    			label: {
    				text: type,
    				// 自动换行
    				textWrap: {
    					width: '90%',
    					height: '80%',
    					ellipsis: true,
    					breakWord: true,
    				},
    			},
    		},
    
    		x: -50,
    		y: -50,
    		id: `task${++count}`, // 设置节点id 方便后期根据id抓节点 进行一些操作
    	});
    
    	ElMessage.success(`添加任务节点${node.id}成功!`);
    	return node;
    };

  •  节点连接时的一些操作

        1、首先,它节点中带有一个叫做port的连接桩(也就是节点边上的小圆点)

        2、什么时候显示port,并让节点之间相连接?案例告诉我们是鼠标移入节点时显示port,

                移出隐藏

在vue3中浅尝antv X6 2.0 demo(三),前端,前端框架,vue.js

 代码实现

// 连接桩
const ports = {
	groups: {
		top: {
			position: 'top',
			attrs: {
				circle: {
					r: 2,
					magnet: true,
					stroke: 'black',
					strokeWidth: 1,
					fill: '#fff',
					style: {
						visibility: 'hidden',
					},
				},
			},
		},
		right: {
			position: 'right',
			attrs: {
				circle: {
					r: 2,
					magnet: true,
					stroke: 'black',
					strokeWidth: 1,
					fill: '#fff',
					style: {
						visibility: 'hidden',
					},
				},
			},
		},
		bottom: {
			position: 'bottom',
			attrs: {
				circle: {
					r: 2,
					magnet: true,
					stroke: 'black',
					strokeWidth: 1,
					fill: '#fff',
					style: {
						visibility: 'hidden',
					},
				},
			},
		},
		left: {
			position: 'left',
			attrs: {
				circle: {
					r: 2,
					magnet: true,
					stroke: 'black',
					strokeWidth: 1,
					fill: '#fff',
					style: {
						visibility: 'hidden',
					},
				},
			},
		},
	},
	items: [
		{
			group: 'top',
		},
		{
			group: 'right',
		},
		{
			group: 'bottom',
		},
		{
			group: 'left',
		},
	],
};

port的显示与隐藏

	graph.on('node:mouseenter', () => {
		const container = document.getElementById('graph-container');
		const ports = container.querySelectorAll('.x6-port-body');
		showPorts(ports, true);
	});
	graph.on('node:mouseleave', () => {
		const container = document.getElementById('graph-container');
		const ports = container.querySelectorAll('.x6-port-body');
		showPorts(ports, false);
	}); 

    // 以上代码需要放在onMounted周期中 或者画布初始化的方法中也可以

    // 函数showPorts我是单独抽成一个公共js的文件里面使用的 看个人实际情况

    function showPorts(ports, show) {
	    for (let i = 0, len = ports.length; i < len; i = i + 1) {
		    ports[i].style.visibility = show ? 'visible' : 'hidden';
	    }
    }

3、连接成功后,根据连接的目标节点和源节点来判断 树目录 的数据结构要如何显示 (么错,递归要来了...)

拿到目标节点和源节点后,去 树目录 里面找这个两个id,有的话就让 树目录里面的目标节点 成为源节点子,然后你就可以拥有一个和节点相对应的目录树了

其中有一点很重要,当连接成功后,目录树里面 目标节点 会成为 源节点 的子后,要记得删除目录树原来的那个目标节点(顺便说一下: react里面的书组件是不支持整个目录树有相同的2个节点出现的,也就是一个子节点不能有两个源节点)

在vue3中浅尝antv X6 2.0 demo(三),前端,前端框架,vue.js

代码实现 

	// 节点连接成功时
	graph.on('edge:connected', ({ isNew, edge }) => {
		if (isNew) {
			const sourceId = edge.getSourceCell().id;
			const targetId = edge.getTargetCell().id;
    
    // findNodeById 是我写的一个公共方法 在树目录里找和节点相同的id

			const sourceNode = findNodeById(
				treeInfo.value[0].children,
				sourceId
			); // 源节点id

			const targetNode = findNodeById(
				treeInfo.value[0].children,
				targetId
			); // 目标节点id

			if (sourceNode && targetNode) {
				sourceNode.children.push(targetNode);
				// push之后删除原targetNode
				for (let i = 0; i < treeInfo.value[0].children.length; i++) {
					const node = treeInfo.value[0].children[i];
					if (node.label === targetId) {
						treeInfo.value[0].children.splice(i, 1);
					}
				}
			}
		}
	});



// 树形目录中添加节点
export const findNodeById = (nodes, id) => {
	for (let i = 0; i < nodes.length; i++) {
		const node = nodes[i];
		if (node.label === id) {
			return node;
		}
		if (node.children) {
			const result = findNodeById(node.children, id);
			if (result) {
				return result;
			}
		}
	}
	return null;
};

  • 删除功能

删除节点可以通过绑定键盘按钮操作,也可以使用官方的节点工具(想要实现下图的删除,可以参考官方文档,so easy)

在vue3中浅尝antv X6 2.0 demo(三),前端,前端框架,vue.js

我主要是通过键盘按钮('delete', 'backspace'都可以删除)来操作的,需要安装X6对应的插件@antv/x6-plugin-keyboard 来绑定删除事件,当然,树目录也要删除对应的节点数据(删除的时候,如果该节点有子节点会连带后续所有的子节点都删除

代码实现

/** 删除的一些操作 */
	graph.bindKey(['delete', 'backspace'], () => {
		const cells = graph.getSelectedCells();
		const cellsId = cells[0].id; // 获取删除节点的id

		if (cells.length) {
			const allChildrenNode = [];
			const nodes = cells.filter((cell) => cell.isNode());
			nodes.forEach((node) => {
				//  获取后继单元格
				const successors = graph.getSuccessors(node, { depth: 3 });
				allChildrenNode.push(...successors);
				console.log(successors, 'successors');
			});
			// 获取后继节点id
			let keyArr = [];
			allChildrenNode.forEach((i) => {
				keyArr.push(i.id);
			});

			// 删除当前节点
			graph.removeCells(cells);
			removeNodes(keyArr);
			// 如果删除的节点和其他节点有共同子节点时 删除书目录中对应的数据
			let newArr = [...keyArr, cellsId]; // 要删除的节点id
			// 删除对应树目录数据
			deleteNodeById(treeInfo.value[0].children, newArr);
			console.log(newArr, 'newArr');
		}
	});


// 删除后继节点
function removeNodes(keys) {
	if (keys && keys.length > 0) {
		keys.forEach((key) => {
			graph.removeNode(key, {
				deep: true,
			});
		});
	}
}


// 树形目录中删除对应节点
export const deleteNodeById = (treeArr, keyArr) => {
	let deleted = false;
	for (let i = treeArr.length - 1; i >= 0; i--) {
		const node = treeArr[i];
		if (keyArr.includes(node.label)) {
			treeArr.splice(i, 1);
			deleted = true;
		} else if (node.children && node.children.length) {
			if (deleteNodeById(node.children, keyArr)) {
				deleted = true;
				if (node.children.length === 0) {
					node.children = [];
				}
			}
		}
	}
	return deleted;
};

以上差不多就是这个demo的所有功能了,还有文本编辑啥的,我还没测过,暂时就不管了,先这样吧~

期待与大家一起共同交流,共同进步,如果有地方写的烂,还望海涵,欢迎大佬指导,最近卡在react版的自定义工具注册上,react是真的不是很熟悉...头疼...文章来源地址https://www.toymoban.com/news/detail-753413.html

到了这里,关于在vue3中浅尝antv X6 2.0 demo(三)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 了解AntV/x6

    先放官网和图片,最好的学习地方仍然是官网。 官网:https://x6.antv.antgroup.com/ 介绍:X6 是基于 HTML 和 SVG 的图编辑引擎,提供低成本的定制能力和开箱即用的内置扩展,方便我们快速搭建 DAG 图、ER 图、流程图、血缘图 等应用。 这个流程图其实是Echarts没有的,相信很多和我

    2024年02月05日
    浏览(31)
  • antv/x6绘图 2.2.1

    网址:https://x6.antv.antgroup.com/ 文档:https://x6.antv.antgroup.com/tutorial/about API:https://x6.antv.antgroup.com/api/graph/graph praph配置:https://x6.antv.antgroup.com/api/graph/graph#connecting 介绍:X6 是基于 HTML 和 SVG 的图编辑引擎,提供低成本的定制能力和开箱即用的内置扩展,方便我们快速搭建 DAG

    2024年02月14日
    浏览(32)
  • antv x6 神奇的图片边框

    昨天才把html节点中的图片转成base格式的,今天就发现一个用户体验的问题;那么是啥呢?就是我从左侧的树形菜单中拖拽节点的时候(鼠标按下也是同样问题),发现节点的图片区域那里会出现一个边框,持续时间不是很长,就几毫秒的时间,但是当你连续拖拽几个不同节

    2023年04月27日
    浏览(30)
  • 「AntV」X6图编辑器的应用——流程图实现

    在线预览 源码 阮一峰:SVG图像入门 SVGtutorial 因为antv/x6是基于SVG的图编辑器,所以SVG的知识有必要了解下的 简介 可缩放矢量图形【基于图形】 全称:Scalable Vector Graphics 定义基于矢量的图形 基于XML语法 放大缩小不会失真 属于万维网标准 可以插入DOM,通过JavaScript和CSS来操作

    2024年02月09日
    浏览(53)
  • 「AntV」X6开发实践:踩过的坑与解决方案

    长期更新版文档请移步语雀(「AntV」X6开发实践:踩过的坑与解决方案 (yuque.com)) --Recent update:2024-01-05 相信你们在开发中更多的需求是需要自定义拖拽源,毕竟自定义的功能扩展性高一些,而且可以根据你的业务需求灵活设置。自定义拖拽的优点就是:万物皆可成为拖拽源,

    2024年02月08日
    浏览(104)
  • springboot + vue3实现视频播放Demo(video.js & Vue3-video-play视频播放器)

    ffmpeg官网 长时长视频java存储及vue播放解决方法 【 攻城略地 】vue3 + video.js播放m3u8视频流格式 Vue3-video-play组件官网 Vue3视频播放器组件Vue3-video-play入门教程 vue-video-player播放m3u8格式的视频 Spring boot视频播放(解决MP4大文件无法播放),整合ffmpeg,用m3u8切片播放。 Java获取MP4视频文

    2024年02月07日
    浏览(64)
  • 通过anvt X6和vue3实现图编辑

    通过anvt X6 X6地址:https://x6.antv.antgroup.com/tutorial/about; 由于节点比较复杂,使用vue实现的节点; x6提供了一个独立的包 @antv/x6-vue-shape 来使用 Vue 组件渲染节点。 VUE3的案例: 节点组件内容如下: 效果如下:代码运行的效果可以进行拖动进程图 后记:画布进行缩放之后不是

    2024年02月13日
    浏览(30)
  • 【前端框架】Vue3合集

    1、create-vue create-vue是Vue官方新的脚手架工具,底层切换到了 vite (下一代前端工具链),为开发提供极速响应 前置条件:16.0或更高版本的Node.js 安装并执行 create-vue 2、项目目录和关键文件 1、setup选项 执行时机:在beforeCreate钩子之前执行 setup函数中,不能获取this 在setup函数

    2024年01月16日
    浏览(42)
  • 【前端】搭建Vue3框架

    VScode/HBuilder等任何一种前端开发工具 node.jsnpm本地开发环境 Node.js官网:Node.js官网 安装成功后,在CMD控制台输入以下两个命令验证是否安装成功 ①、创建默认安装目录和缓存日志目录(我的node.js目录在D盘,所以直接在node.js文件夹下创建) 由于在执行全局安装语句时,安装

    2024年02月08日
    浏览(45)
  • 前端框架Vue3.0

    目录 一、创建Vue3.0工程 1.使用 vue-cli 创建 1.1. 检查@vue/cli的版本,确认是否@vue/cli版本在4.5.0以上 1.2. 安装或者升级@vue/cli 1.3 创建工程 1.4 启动Vue工程 2. 使用 vite 创建 1.1. 检查@vue/cli的版本,确认是否@vue/cli版本在4.5.0以上 代码: 实例: 1.2. 安装或者升级@vue/cli 代码: 实例:

    2024年02月13日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包