【前端学习】AntV G6-07 深入图形与图形分组、自定义节点、节点动画(上、中)

news2024/9/17 7:22:43

课程链接

AntV G6:深入图形与图形分组、自定义节点、节点动画(上)_哔哩哔哩_bilibili

AntV G6:深入图形与图形分组、自定义节点、节点动画(中)_哔哩哔哩_bilibili


图形分组 Group | G6 (antgroup.com)

自定义元素 G6.registerX | G6 (antgroup.com)

图形样式属性 Shape Attr | G6 (antgroup.com)


通过G6.registerNode方法,绘制基于 rect 的自定义卡片,并且提到:

1. 如果要更新自定义node,需要注意重绘时 update方法 是否要重写,有2个方法可以解决

2. 更新节点时候需要注意位置变形的问题,通过设置相对的x,y解决

3. KeyShape的draggable属性,可以控制是否这部分可以被拖拽

<!DOCTYPE html>
<html>

<head>
	<meta charset="UTF-8">
	<title>05 深入图形与图形分组、自定义节点、节点动画</title>
	<!-- 引入 G6 -->
	<script src="https://gw.alipayobjects.com/os/lib/antv/g6/4.3.11/dist/g6.min.js"></script>
</head>

<body>
	<div id="container"></div>
	<script>
		const ICON_MAP = {
			a: 'https://ts2.cn.mm.bing.net/th?id=ODLS.70f7e605-0e03-4ed5-8935-b48cb3ee855f&w=32&h=32&o=6&pid=AdsPlus',
			b: 'https://ts2.cn.mm.bing.net/th?id=OADD2.7353136438133_1J11L5COSQ5ZDZ3TDJ&w=32&h=32&o=6&pid=21.2'
		}

		const data = {
			nodes: [
				{
					id: 'node2',
					title: 'node2',
					error: false,
					nodeType: 'a',
					nodeLevel: 0,
					panels: [
						{ title: '成功率', value: '11%' },
						{ title: '耗时', value: '50s' },
						{ title: '错误数', value: '12' },
					],
					x: 100,
					y: 100
				},
				{
					id: 'node3',
					title: 'node3',
					error: true,
					nodeType: 'b',
					nodeLevel: 0,
					panels: [
						{ title: '成功率', value: '19%' },
						{ title: '耗时', value: '10s' },
						{ title: '错误数', value: '8' },
					],
					x: 100,
					y: 200
				},
			],
		}

		// 第1个参数,卡片节点的名字
		// 第2个参数,options
		// 第3个参数,继承的节点类型
		G6.registerNode('card-node', {
			// 复写 draw 方法
			// 第1个参数,这个节点的配置
			// 第2个参数,这个节点的图形分组,现在的目的是往这个图形分组中去增加图形
			draw: (cfg, group) => {
				const color = cfg.error ? '#F4664A' : '#30BF78';
				const x = -200 / 2;
				const y = -60 / 2;
				const keyShape = group.addShape('rect', {
					attrs: {
						x,
						y,
						width: 200,
						height: 60,
						stroke: color,
						fill: '#fff',
						radius: 2
					},
					name: 'card-node-keyshape'
				});
				const titleRect = group.addShape('rect', {
					attrs: {
						x,
						y,
						width: 200,
						height: 20,
						stroke: color,
						fill: color,
						radius: 2
					},
					name: 'card-node-title-back',
					draggable: true  // G6为keyShape添加了draggable属性,为true时这部分图形才可以被拖拽
				});
				const image = group.addShape('image', {
					attrs: {
						x: x + 2,
						y: y + 2,
						width: 14,
						height: 14,
						img: ICON_MAP[cfg.nodeType],
						cursor: 'pointer'
					}
				});
				const title = group.addShape('text', {
					attrs: {
						text: cfg.title,
						x: x + 30,
						y: y + 4,
						fill: '#fff',
						textBaseline: 'top'
					},
					name: 'card-node-title'
				});
				let panelX = - x + 40;  // 疑问点:视频里这里不需要负号
				const subGroup = group.addGroup();
				cfg.panels?.forEach((panel, i) => {
					const panelTitle = subGroup.addShape('text', {
						attrs: {
							text: panel.title,
							x: x + panelX,
							y: y + 38,
							fill: '#ccc',
							textAlign: 'center'
						},
						name: `card-node-panel-title-${i}`
					})
					subGroup.addShape('text', {
						attrs: {
							text: panel.value,
							x: x + panelX,
							y: y + 54,
							fill: '#111',
							textAlign: 'center'
						},
						name: `card-node-panel-title-${i}`
					})

					// 根据前面图形的大小来放置后面的图形
					const titleBBox = panelTitle.getBBox();
					// console.log(titleBBox);
					panelX = titleBBox.maxX + 40;

					// panelX += 60;
				})

				return keyShape;
			},
			// update: undefined
			// 如果重写了update方法,渲染层面就会走这个update方法,而不会清空整个节点去重新绘制
			update: (cfg, item) => {
				const group = item.getContainer(); // 获取图形容器
				const titleShape = group.find(ele => ele.get('name') === 'card-node-title') // 通过name属性找到需要更新的图形
				// titleShape.attr('text', cfg.title); // 更新title里的text字段,attr 用来更新某个绘图属性
				// 批量更新
				titleShape.attr({
					text: cfg.title,
					// ... 其他属性
				})

			}
		}, 'rect')
		// 如果要更新node,方法1:取消继承自 rect
		// 如果要更新node,方法2:在继承自 rect 的前提下,设置update方法为undefined,重绘时就会走自定义的draw

		const width = document.getElementById('container').scrollWidth
		const height = document.getElementById('container').scrollHeight || 500

		const graph = new G6.Graph({
			container: 'container',
			width,
			height,
			fitCenter: true,
			// fitView: true,
			// 模式
			modes: {
				// 拖拽画布 drag-canvas
				// 拖拽节点 drag-node 
				// 缩放画布 zoom-canvas
				default: ['drag-canvas', 'drag-node'],
			},
			defaultNode: {
				type: 'card-node'
			}

		})


		graph.data(data);
		graph.render();

		graph.updateItem(graph.getNodes()[0], {
			// 如果要更新node,方法1:取消继承自 rect
			// 如果要更新node,方法2:在继承自 rect 的前提下,设置update方法为undefined,重绘时就会走自定义的draw
			title: 'new-title~~'
		})

		if(typeof window !== 'undefined')
			window.onresize = () => {
				if(!graph || graph.get('destroyed')) return;
				if(!container || !container.scrollWidth || !container.scrollHeight)
				graph.changeSize(container.scrollWidth, container.scrollHeight);
			}
	</script>
</body>

</html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2116329.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ARM32开发——DMA内存到内存

&#x1f3ac; 秋野酱&#xff1a;《个人主页》 &#x1f525; 个人专栏:《Java专栏》《Python专栏》 ⛺️心若有所向往,何惧道阻且长 文章目录 需求数据交互流程开发流程依赖引入DMA初始DMA传输请求完整代码 关心的内容DMA初始化DMA初始化DMA数据传输请求完整代码 DMA中断开启…

封装智能指针 qt实现登录界面

1.封装独占智能指针——unique_ptr #include <iostream> #include <utility> // For std::move// 命名空间 namespace custom_memory { template <typename T> class myPtr { public:// 使用初始化列表进行初始化explicit myPtr(T* p nullptr) noexcept : …

卡西莫多的诗文集2022-2024.9月6-校庆国庆专版定版

通过网盘分享的文件&#xff1a;卡西莫多的诗文集2022-2024.9月6-A5-校庆国庆专版-定版.pdf 链接: https://pan.baidu.com/s/1cpFK5k1baGXbSGxY30GL_A?pwdjgnt 提取码: jgnt 卡西莫多的诗文集2022-2024.9月6-校庆国庆专版&#xff0c;又稍作修改并勘误了一些错字&#xff0c;…

AWQ量化(Activation-aware Weight Quantization)

论文&#xff1a; AWQ: Activation-aware Weight Quantization for On-Device LLM Compression and Acceleration 中文解读&#xff1a; 深入理解AWQ量化技术 - 知乎 (zhihu.com) 动机&#xff1a;端侧设备用LLM&#xff0c;为了减少显存占用量&#xff0c;所以要用INT4量化&am…

【Jupyter Notebook】汉化

1.打开:Anaconda Prompt 2.输入:"activate Zhui01"(注意&#xff1a;Zhui01是刚创建的环境名字) activate Zhui01 3.输入:"pip install jupyterlab-language-pack-zh-CN" pip install jupyterlab-language-pack-zh-CN 4.打开:Jupyter Notebook 5.点击&q…

Mysql高级篇(中)——七种常见的 join 查询图

注意&#xff1a; MySQL是不支持 FULL OUTER JOIN 这种语法的&#xff0c;因此要实现图中 6、7的查询结果&#xff0c;可以使用 UNION 关键字结合 LEFT JOIN、RIGHT JOIN 实现&#xff0c;UNION可以实现去重的效果&#xff1b; 参考如下代码&#xff1a; -- MySQL中 图标6 的实…

用Unity2D制作一个人物,实现移动、跳起、人物静止和动起来时的动画:中(人物移动、跳起、静止动作)

上回我们学到创建一个地形和一个人物&#xff0c;今天我们实现一下人物实现移动和跳起&#xff0c;依次点击&#xff0c;我们准备创建一个C#文件 创建好我们点击进去&#xff0c;就会跳转到我们的Vision Studio&#xff0c;然后输入这些代码 using UnityEngine;public class M…

MarginNote 4 激活码 - 苹果电脑(Mac)全能型的阅读工具

对广大求学者来说&#xff0c;如何科学有效地掌握知识&#xff0c;一定是大家不懈追求的方向。 众多求学者使用的&#xff0c;深度阅读学习工具 MarginNote&#xff0c;终于为 Mac 推出了官网 4.0 版。带来了众多创新的学习辅助工具。 MarginNote 4 功能简介 1、快速理清各版…

大数据新视界--大数据大厂之Java 与大数据携手:打造高效实时日志分析系统的奥秘

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

探索fastFM:Python中的高效推荐系统库

文章目录 &#x1f680; 探索fastFM&#xff1a;Python中的高效推荐系统库背景&#xff1a;为何选择fastFM&#xff1f;快照&#xff1a;fastFM是什么&#xff1f;安装指南&#xff1a;如何将fastFM加入你的项目&#xff1f;快速入门&#xff1a;五个基础函数的使用实战演练&am…

猫眼电影字体破解(图片转码方法)

问题 随便拿一篇电影做样例。我们发现猫眼的页面数据在预览窗口中全是小方框。在当我们拿到源码以后&#xff0c;数据全是加密后的。所以我们需要想办法破解加密&#xff0c;拿到数据。 破解过程 1.源码获取问题与破解 分析 在我们刚刚请求url的时候是可以得到数据的&#xff…

halcon 由离散点云生成3d模型(2步)

一&#xff0c;创建立方体的3d坐标&#xff0c;定义X,Y,Z坐标 dev_open_window (0, 0, 512, 512, black, WindowHandle) x:[0,0,1,1,0,0,1,1] y:[0,1,1,0,0,1,1,0] z:[0,0,0,0,2,2,2,2] 二&#xff0c;由3创建3d模型&#xff08;在这里是将所有的点集合为一体&#xff09; ge…

多路转接之select(fd_set介绍,参数详细介绍),实现非阻塞式网络通信

目录 多路转接之select 引入 介绍 fd_set 函数原型 nfds readfds / writefds / exceptfds readfds 总结 fd_set操作接口 timeout timevalue 结构体 传入值 返回值 代码 注意点 -- 调用函数 select的参数填充 获取新连接 注意点 -- 通信时的调用函数 添…

JavaScript使用高德API显示地图

前言 在JavaScript中&#xff0c;使用Leaflet库显示地图是一种常见的做法。Leaflet是一个开源的JavaScript库&#xff0c;用于在Web应用程序中创建互动地图。它非常轻量级&#xff0c;易于使用&#xff0c;并且提供了多种功能&#xff0c;使开发者能够轻松地将地图集成到他们的…

【Python报错已解决】 SyntaxError: positional argument follows keyword argument

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 文章目录 前言一、问题描述1.1 报错示例1.2 报错分析1.3 解决思路 二、解决方法2.1 方法一&#xff1a;调整参数顺序2.2 步骤二…

银行贷款产品

1、对公贷款 1.1 一般贷款 按贷款期限可分为短期贷款和中长期贷款。短期贷款是指金融企业根据有关规定发放的,期限在1年(含1年)以下的各种贷款。中长期贷款是指金融企业发放的贷款期限在1年以上的各种贷款。 按提供方式不同可分为信用贷款、担保贷款等。信用贷款是指金融企…

springboot实战学习(1)(开发模式与环境)

目录 一、实战学习的引言 &#xff08;1&#xff09;前后端的大致学习模块 &#xff08;2&#xff09;后端 &#xff08;3&#xff09;前端 二、开发模式 一、实战学习的引言 &#xff08;1&#xff09;前后端的大致学习模块 &#xff08;2&#xff09;后端 Validation&#xf…

ubuntu上通过openvswitch卸载实现roce over vxlan

环境 操作系统&#xff1a; uname -a Linux 5.4.0-187-generic #207-Ubuntu SMP Mon Jun 10 08:16:10 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux Mellanox网卡&#xff1a; ethtool -i ens6np0 driver: mlx5_core version: 23.10-2.1.3 firmware-version: 20.39.3004 (MT_0…

在Linux下查看HBA卡的速率和状态

平时在Linux下映射存储&#xff0c;都是映射哪台就给哪台插线&#xff0c;然后在存储端扫描WWPN&#xff0c;简单粗暴&#xff0c;没技术含量。当然&#xff0c;光交下也可以看。 1&#xff0c;查看当前卡的品牌&#xff0c;常用的卡有两种&#xff0c;Emulex和Qlogic。 lspc…

C语言 - 预处理详解(一)#预定义符号 ##define #undef

文章目录 前言 一、预定义符号 二、#define (一)、#define 定义的标识符 (二)、#define 定义的宏 (三)、#define 替换规则 (四)、# 和 ## 1、 # 的作用 2、## 的作用 (五)、带副作用的宏参数 (六)、宏和函数的对比 (七)、命名约定 三、#undef 总结 前言 路漫漫其修远兮&#…