Vue3使用G6基础
Vue3使用G6笔记(
需要用到思维导图,找到蚂蚁金服的G6可以满足需求,不得不说阿里巴巴yyds,这一套图标全家桶可太棒了
- 熟悉了下基本用法,记录下来
- 官网讲的就很好了,建议去认真读读手册就会用了
- 这里总结的更精简和直观,需要的小伙伴可以看看
- 目前还是一些比较基础的操作,后面用的深入了还会更新
一. 安装和引入
- npm安装
npm install --save @antv/g6
- 项目中引入
import G6 from '@antv/g6';
二. 第一个小demo
通过一个小demo了解基础的创建方式
步骤
- 首先需要一个标记了id的div
<template><div><div id="mountNode"></div></div>
</template>
- 之后需要初始化G6的Graph实例,这一步需要放在onMounted生命周期中,不然加载不出来
const graph = new G6.Graph({container: 'mountNode', // String | HTMLElement,必须,在 Step 1 中创建的容器 id 或容器本身width: 800, // Number,必须,图的宽度height: 500, // Number,必须,图的高度});
- 之后需要定义一些节点数据
const data = {// 点集nodes: [{id: 'node1', // String,该节点存在则必须,节点的唯一标识x: 100, // Number,可选,节点位置的 x 值y: 200, // Number,可选,节点位置的 y 值label: 'start'},{id: 'node2', // String,该节点存在则必须,节点的唯一标识x: 300, // Number,可选,节点位置的 x 值y: 200, // Number,可选,节点位置的 y 值label: 'end'},],// 边集edges: [{source: 'node1', // String,必须,起始点 idtarget: 'node2', // String,必须,目标点 idlabel: '我是连线'},],};
- 还是在onMounted中加载数据,并且渲染
graph.data(remoteData); // 加载远程数据graph.render(); // 渲染
- 完整代码
<template><div><div id="mountNode"></div></div>
</template><script>
import G6 from '@antv/g6';
import {onMounted} from "vue";
export default {name: "Test02",setup(){const data = {// 点集nodes: [{id: 'node1', // String,该节点存在则必须,节点的唯一标识x: 100, // Number,可选,节点位置的 x 值y: 200, // Number,可选,节点位置的 y 值label: 'start'},{id: 'node2', // String,该节点存在则必须,节点的唯一标识x: 300, // Number,可选,节点位置的 x 值y: 200, // Number,可选,节点位置的 y 值label: 'end'},],// 边集edges: [{source: 'node1', // String,必须,起始点 idtarget: 'node2', // String,必须,目标点 idlabel: '我是连线'},],};onMounted(()=>{// 实例化graph对象const graph = new G6.Graph({container: 'mountNode', // String | HTMLElement,必须,在 Step 1 中创建的容器 id 或容器本身width: 800, // Number,必须,图的宽度height: 500, // Number,必须,图的高度});graph.data(remoteData); // 加载远程数据graph.render(); // 渲染};main()})}
}
</script><style scoped></style>
之后就是详细各部分的教程
三. 点和边的参数设置
1. 基本配置
点和线的样式和设置都是包裹在nodes对象数组中的,在对象中填入下面的配置即可配置点和边的样式
{id: 'node0', // 元素的 idtype: 'circle', // 元素的图形size: 40, // 元素的大小label: 'node0' // 标签文字visible: true, // 控制初次渲染显示与隐藏,若为 false,代表隐藏。默认不隐藏labelCfg: { // 标签配置属性positions: 'center',// 标签的属性,标签在元素中的位置style: { // 包裹标签样式属性的字段 style 与标签其他属性在数据结构上并行fontSize: 12 // 标签的样式属性,文字字体大小// ... // 标签的其他样式属性}}// ..., // 其他属性style: { // 包裹样式属性的字段 style 与其他属性在数据结构上并行fill: '#000', // 样式属性,元素的填充色stroke: '#888', // 样式属性,元素的描边色// ... // 其他样式属性}
}
2. 通过遍历节点来设置样式
既可以在节点数据就写好样式,但更多的我们是拿到后端传来的很标准的json数据(只有数据),这个时候可以通过遍历节点来设置各个节点的样式
要注意的是动态配置的样式会覆盖掉在graph初始化时配置的默认样式
const nodes = remoteData.nodes; //这里是拿到的节点数据
nodes.forEach((node) => { //遍历节点数据if (!node.style) {node.style = {};}switch (node.class // 根据节点数据中的 class 属性配置图形) {case 'c0': {node.type = 'circle'; // class = 'c0' 时节点图形为 circlebreak;}case 'c1': {node.type = 'rect'; // class = 'c1' 时节点图形为 rectnode.size = [35, 20]; // class = 'c1' 时节点大小break;}case 'c2': {node.type = 'ellipse'; // class = 'c2' 时节点图形为 ellipsenode.size = [35, 20]; // class = 'c2' 时节点大小break;}}
});graph.data(remoteData);
四. 初始化实例时的参数设置
1. 让画布适应图像
由于点和变数据在设置的时候可以指定位置,而如果画布不够大的话是会超出画布大小,显示不完整的
- 这一点可以在初始化的时候解决
const graph = new G6.Graph({container: 'mountNode', // String | HTMLElement,必须,在 Step 1 中创建的容器 id 或容器本身width: 800, // Number,必须,图的宽度height: 500, // Number,必须,图的高度fitView: true, // 让图片适应当前的画布大小fitViewPadding: [20,40,50,20] // 适应之后加入边框});
2. 给点和边指定默认样式
需要点和边有统一的样式的时候,可以在graph初始化的时候指定默认样式
const graph = new G6.Graph({container: 'mountNode', // String | HTMLElement,必须,在 Step 1 中创建的容器 id 或容器本身width: 800, // Number,必须,图的宽度height: 500, // Number,必须,图的高度fitView: true, // 让图片适应当前的画布大小fitViewPadding: [20,40,50,20], // 适应之后加入边框// 从这开始指定默认节点样式defaultNode: {size: 30, // 节点大小// ... // 节点的其他配置// 节点样式配置style: {fill: 'steelblue', // 节点填充色stroke: '#666', // 节点描边色lineWidth: 1, // 节点描边粗细},// 节点上的标签文本配置labelCfg: {// 节点上的标签文本样式配置style: {fill: '#fff', // 节点标签文字颜色},},},// 边在默认状态下的样式配置(style)和其他配置defaultEdge: {// ... // 边的其他配置// 边样式配置style: {opacity: 0.6, // 边透明度stroke: 'grey', // 边描边颜色},// 边上的标签文本配置labelCfg: {autoRotate: true, // 边上的标签文本根据边的方向旋转},},});
3. 添加图布局Layout
const graph = new G6.Graph({// ... // 其他配置项layout: {// Object,可选,布局的方法及其配置项,默认为 random 布局。type: 'force',linkDistance: 100, // 指定边距离为100preventOverlap: true, // 防止节点重叠// nodeSize: 30 // 节点大小,用于算法中防止节点重叠时的碰撞检测。由于已经在上一节的元素配置中设置了每个节点的 size 属性,则不需要在此设置 nodeSize。},
});
4. 添加交互模式
下文会说
5. 添加提示框
下文会说
五. 图布局Layout
当数据中没有节点位置信息,或者数据中的位置信息不满足需求时,需要借助一些布局算法对图进行布局
一般图布局
- Random Layout:随机布局;
- Force Layout:经典力导向布局:
力导向布局:一个布局网络中,粒子与粒子之间具有引力和斥力,从初始的随机无序的布局不断演变,逐渐趋于平衡稳定的布局方式称之为力导向布局。适用于描述事物间关系,比如人物关系、计算机网络关系等。
- Circular Layout:环形布局;
- Radial Layout:辐射状布局;
- MDS Layout:高维数据降维算法布局;
- Fruchterman Layout:Fruchterman 布局,一种力导布局;
- Dagre Layout:层次布局;
- Concentric Layout:同心圆布局,将重要(默认以度数为度量)的节点放置在布局中心;
- Grid Layout:格子布局,将节点有序(默认是数据顺序)排列在格子上
树图布局
- Dendrogram Layout:树状布局(叶子节点布局对齐到同一层);
- CompactBox Layout:紧凑树布局;
- Mindmap Layout:脑图布局;
- Indented Layout:缩进布局。
默认情况
- 默认情况下,如果节点数据中有坐标信息,就用坐标信息
- 没有坐标信息,就用 Random Layout 布局
const graph = new G6.Graph({// 。。。。。其他配置省略// 图布局Layoutlayout: {// Object,可选,布局的方法及其配置项,默认为 random 布局。type: 'force',linkDistance: 100, // 指定边距离为100preventOverlap: true, // 防止节点重叠// nodeSize: 30 // 节点大小,用于算法中防止节点重叠时的碰撞检测。由于已经在上一节的元素配置中设置了每个节点的 size 属性,则不需要在此设置 nodeSize。},)}
六. 图的交互
给图添加简单的交互,比如:hover 节点、点击节点、点击边、放缩画布、拖拽画布
1. 拖拽,放大,缩小
直接在graph初始化的时候写上mode就行,
const graph = new G6.graph({// 交互模式modes: {default: ['drag-canvas', 'zoom-canvas', 'drag-node'], // 允许拖拽画布、放缩画布、拖拽节点},
})
2. 提示框
- hover的时候出现提示框,在mode的数组中加入tooltip类型或edge-tooltip类型
- 实际上就是将这个节点上的一些数据输出出来,需要手动写一个html的字符串
const graph = new G6.Graph({modes: {default: ['drag-canvas', 'zoom-canvas', 'drag-node', // 允许拖拽画布、放缩画布、拖拽节点{type: 'tooltip', // 提示框formatText(model) {// 提示框文本内容,实际上就是放了个div进去const text = 'label: ' + model.label + '<br/> class: ' + model.class;return text;}},{type: 'edge-tooltip', // 边提示框formatText(model) {// 边提示框文本内容const text ='source: ' +model.source +'<br/> target: ' +model.target +'<br/> weight: ' +model.weight;return text;}},],
)}
3. 状态式交互
比如点击,hover触发的事件和样式的改变等等
(a) 交互状态
- 交互状态就是这个节点是否处于被hover,或者是否被点击等等事件触发的状态
- 比如这个节点被点击了,那这个节点的click状态就是true
- 而节点处于激活状态时候的样式,是需要在初始化的时候就进行配置的
- nodeStateStyles和edgeStateStyles下可以进行配置,注意这是激活后才生效的,这里还没绑定事件,因此是不生效的
const graph = new G6.Graph({// ... // 其他配置项// 节点不同状态下的样式集合nodeStateStyles: {// 鼠标 hover 上节点,即 hover 状态为 true 时的样式hover: {fill: 'lightsteelblue',},// 鼠标点击节点,即 click 状态为 true 时的样式click: {stroke: '#000',lineWidth: 3,},},// 边不同状态下的样式集合edgeStateStyles: {// 鼠标点击边,即 click 状态为 true 时的样式click: {stroke: 'steelblue',},},
});
(2) 绑定事件
- 绑定事件和交互状态需要联合起来用,经过绑定的事件并触发后,才会显示初始化中定义的处于true状态时候的样式
- 思路就是:拿到点击的节点/边,然后设置这个节点的状态
//graph事件监听// 鼠标进入节点graph.on('node:mouseenter', (e) => {const nodeItem = e.item; // 获取鼠标进入的节点元素对象graph.setItemState(nodeItem, 'hover', true); // 设置当前节点的 hover 状态为 true});// 鼠标离开节点graph.on('node:mouseleave', (e) => {const nodeItem = e.item; // 获取鼠标离开的节点元素对象graph.setItemState(nodeItem, 'hover', false); // 设置当前节点的 hover 状态为 false});// 点击节点graph.on('node:click', (e) => {// 先将所有当前是 click 状态的节点置为非 click 状态const clickNodes = graph.findAllByState('node', 'click');clickNodes.forEach((cn) => {graph.setItemState(cn, 'click', false);});const nodeItem = e.item; // 获取被点击的节点元素对象graph.setItemState(nodeItem, 'click', true); // 设置当前节点的 click 状态为 true});// 点击边graph.on('edge:click', (e) => {// 先将所有当前是 click 状态的边置为非 click 状态const clickEdges = graph.findAllByState('edge', 'click');clickEdges.forEach((ce) => {graph.setItemState(ce, 'click', false);});const edgeItem = e.item; // 获取被点击的边元素对象graph.setItemState(edgeItem, 'click', true); // 设置当前边的 click 状态为 true});
七. 插件的使用
步骤:
- 实例化插件
- 在初始化graph的时候在plugins中加入
- 实例化两个插件,一个是缩略图,一个是网格
// 实例化minimap插件对象const minimap = new G6.Minimap({size: [100, 100],className: 'minimap',type: 'delegate',})// 实例化网格插件对象const grid = new G6.Grid()
- 之后在实例化中加入
const graph = new G6.Graph({// ......其余配置plugins:[minimap, grid],)}
整个案例
整个组件的案例代码在这,里面包含了上面说的所有部分
<template><div><div id="mountNode"></div></div>
</template><script>
import request from "../utils/request";
import G6 from '@antv/g6';
import {onMounted} from "vue";
export default {name: "Test02",setup(){// 实例化minimap插件对象const minimap = new G6.Minimap({size: [100, 100],className: 'minimap',type: 'delegate',})// 实例化网格插件对象const grid = new G6.Grid()const data = {// 点集nodes: [{id: 'node1', // String,该节点存在则必须,节点的唯一标识x: 100, // Number,可选,节点位置的 x 值y: 200, // Number,可选,节点位置的 y 值label: 'start'},{id: 'node2', // String,该节点存在则必须,节点的唯一标识x: 300, // Number,可选,节点位置的 x 值y: 200, // Number,可选,节点位置的 y 值label: 'end'},],// 边集edges: [{source: 'node1', // String,必须,起始点 idtarget: 'node2', // String,必须,目标点 idlabel: '我是连线'},],};onMounted(()=>{const graph = new G6.Graph({container: 'mountNode', // String | HTMLElement,必须,在 Step 1 中创建的容器 id 或容器本身width: 800, // Number,必须,图的宽度height: 500, // Number,必须,图的高度fitView: true, // 让图片适应当前的画布大小fitViewPadding: [20,40,50,20], // 适应之后加入边框plugins:[minimap, grid],// 图布局Layoutlayout: {// Object,可选,布局的方法及其配置项,默认为 random 布局。type: 'force',linkDistance: 100, // 指定边距离为100preventOverlap: true, // 防止节点重叠// nodeSize: 30 // 节点大小,用于算法中防止节点重叠时的碰撞检测。由于已经在上一节的元素配置中设置了每个节点的 size 属性,则不需要在此设置 nodeSize。},// 交互模式modes: {default: ['drag-canvas', 'zoom-canvas', 'drag-node', // 允许拖拽画布、放缩画布、拖拽节点{type: 'tooltip', // 提示框formatText(model) {// 提示框文本内容,实际上就是放了个div进去const text = 'label: ' + model.label + '<br/> class: ' + model.class;return text;}},{type: 'edge-tooltip', // 边提示框formatText(model) {// 边提示框文本内容const text ='source: ' +model.source +'<br/> target: ' +model.target +'<br/> weight: ' +model.weight;return text;}},],},// 交互式状态,hover和click时候的样式改变nodeStateStyles: {// 鼠标 hover 上节点,即 hover 状态为 true 时的样式hover: {fill: 'lightsteelblue',},// 鼠标点击节点,即 click 状态为 true 时的样式click: {stroke: '#000',lineWidth: 3,},},// 边不同状态下的样式集合edgeStateStyles: {// 鼠标点击边,即 click 状态为 true 时的样式click: {stroke: 'steelblue',},},// 节点的默认样式defaultNode: {size: 30, // 节点大小// ... // 节点的其他配置// 节点样式配置style: {fill: 'steelblue', // 节点填充色stroke: '#666', // 节点描边色lineWidth: 1, // 节点描边粗细},// 节点上的标签文本配置labelCfg: {// 节点上的标签文本样式配置style: {fill: '#fff', // 节点标签文字颜色},},},// 边在默认状态下的样式配置(style)和其他配置defaultEdge: {// ... // 边的其他配置// 边样式配置style: {opacity: 0.6, // 边透明度stroke: 'grey', // 边描边颜色},// 边上的标签文本配置labelCfg: {autoRotate: true, // 边上的标签文本根据边的方向旋转},},});//graph事件监听// 鼠标进入节点graph.on('node:mouseenter', (e) => {const nodeItem = e.item; // 获取鼠标进入的节点元素对象graph.setItemState(nodeItem, 'hover', true); // 设置当前节点的 hover 状态为 true});// 鼠标离开节点graph.on('node:mouseleave', (e) => {const nodeItem = e.item; // 获取鼠标离开的节点元素对象graph.setItemState(nodeItem, 'hover', false); // 设置当前节点的 hover 状态为 false});// 点击节点graph.on('node:click', (e) => {// 先将所有当前是 click 状态的节点置为非 click 状态const clickNodes = graph.findAllByState('node', 'click');clickNodes.forEach((cn) => {graph.setItemState(cn, 'click', false);});const nodeItem = e.item; // 获取被点击的节点元素对象graph.setItemState(nodeItem, 'click', true); // 设置当前节点的 click 状态为 true});// 点击边graph.on('edge:click', (e) => {// 先将所有当前是 click 状态的边置为非 click 状态const clickEdges = graph.findAllByState('edge', 'click');clickEdges.forEach((ce) => {graph.setItemState(ce, 'click', false);});const edgeItem = e.item; // 获取被点击的边元素对象graph.setItemState(edgeItem, 'click', true); // 设置当前边的 click 状态为 true});//案例中的真实数据const main = async () => {const response = await fetch('https://gw.alipayobjects.com/os/basement_prod/6cae02ab-4c29-44b2-b1fd-4005688febcb.json',);const remoteData = await response.json();// ...graph.data(remoteData); // 加载远程数据graph.render(); // 渲染};main()})}
}
</script><style scoped>
.g6-tooltip {border: 1px solid #e2e2e2;border-radius: 4px;font-size: 12px;color: #545454;background-color: rgba(117, 77, 77, 0.9);padding: 10px 8px;box-shadow: rgb(174, 174, 174) 0px 0px 10px;
}
</style>
Vue3使用G6基础相关推荐
- vue2+vue3小白零基础教程—vue2篇,全网2021最详细教程
vue教程 提示:Vue3系列请参考Vue2+Vue3小白零基础教程-vue3篇文章,本文为vue2篇. 1. Vue核心 1.1 Vue简介 1.1.1 Vue是什么 一套用于构建用户界面的渐进式J ...
- vue3组合式api基础(常用)
vue3组合式api基础(常用) 前言:vue3中尽量不要使用'this',最好使用组合式api(Composition API),如果使用uni-app的,vue3只支持ios>=10(201 ...
- Vue3手册译稿 - 基础 - 介绍
介绍 提示 已经了解Vue2且仅想知道Vue3有哪些新功能?请参阅迁移指南 Vue.js是什么? Vue(读音/vjuː/,像view一样发音)是一套用于构建用户界面的先进框架,不像其他僵化的框架,V ...
- Ts基础知识及ts+vue3的基本使用
Ts基础知识及ts+vue3的基本使用 前言 Ts基础知识: 一.常用类型 二.类型别名与接口 三.类型保护 1. 类型断言 2. in 关键字 3. typeof 关键字 4. instanceof ...
- 基于 Vue3.0 和 Ant Design Vue ,高颜值管理后台UI框架vue-vben-admin运行
简介 Vue Vben Admin 是一个免费开源的中后台模版.使用了最新的vue3,vite2,TypeScript等主流技术开发,开箱即用的中后台前端解决方案,也可用于学习参考. Github地址 ...
- uniapp开发:uniapp快速体验vue3.2之setup语法糖,怎么使用怎么爽
目录 概要 拉开序幕的setup语法糖 生命周期钩子 ref函数与reactive函数对比 computed计算属性 监视(watch.watchEffect) 组件注册 组件传值 provide/i ...
- springboot+vue3物资管理系统实战
springboot+vue3物资管理系统实战 1.项目适合对象 2.项目涉及技术 3.项目收获 4.效果展示 5.关键代码 1.项目适合对象 有Vue2.Vue3组合api基础知识,TypeScri ...
- springboot+vue3健身房管理系统实战
springboot+vue3健身房管理系统实战 1.项目适合对象 需要有springboot.Vue2.Vue3组合api基础知识,TypeScript基础知识的小伙伴: 没有vue2/vue3.s ...
- Vue3 $set?
目录 一.背景 二.Vue3 $set 三.Vue3 和 Vue2 在编写代码中的区别 四. Vue3 使用路由router 五.Vue3 封装axios 六.Vue3 引入防抖和节流提升性能 七.V ...
最新文章
- 如何在C ++中从容器中删除元素
- Java源码详解三:Hashtable源码分析--openjdk java 11源码
- 最新综述:从多个角度介绍多模态对话信息搜索(MMCIS)任务
- 关于java嵌入式数据库的选择,强烈建议H2 嵌入式数据库
- Application Fundamentals
- (译)如何优化cocos2d程序的内存使用和程序大小:第二部分(完)
- iOS【终极方案】精准获取webView内容高度,自适应高度
- github上markdown文件编写笔记
- Optimal Marks SPOJ - OPTM(最小割)
- 安装adb、选择合适的 adb 版本
- java中重试的使用工具
- 门锁了开不了_送智能门锁丨选购时没有注意这些,着火时智能门锁可能会打不开?...
- Excel VBA入门(9):实例汇总
- 论文引用文献并插入编号
- LTspice蒙特卡罗分析正态分布图工具
- 用c语言绘制小猫图案,【科研猫·R】R语言从入门到精通:Day8
- vscode+authorized_keys登录不上的原因
- 普通用户申请微软的OneDrive免费网盘,容量5T、5T、5T,重要事情说三遍!!!!!
- 【程序人生】全国一二线程序员工资统计新鲜出炉,又涨了!
- 什么是跨域(CORS)?怎么解决跨域(CORS)?