vue3使用AntV G6 (图可视化引擎)历程[三]

上期回顾:历程[二]描述了节点抽离自定义节点并做数据静态渲染。下面这篇继续描述节点升级版的模块化抽离以及动态数据渲染
官网地址:https://g6-next.antv.antgroup.com/manual/introduction “@antv/g6”: “^4.8.24”

一、 案例效果

在这里插入图片描述

二、自定义节点的模块化抽离

1. 组件引用
  <TopologyBase domId="featureTreeInfoContainer" :treeData="treeData" />
2. 【TopologyBase.vue】组件封装
<template>
  <div :id="domId" class="w-full h-[95%]"></div>
</template>
<script setup lang="ts">
import G6 from '@antv/g6'
import { onMounted, ref } from 'vue'
import { attrConfigHandle } from './initAttrConfig'
import { drawShape } from './registerNode'

const props = defineProps({
  domId: {
    type: String,
    default: '',
  },
  treeData: {
    type: Object,
  },
})
const initTreeData = ref(props.treeData)
const container = ref<any>()

G6.registerNode(
  'dom-node',
  {
    draw(cfg: any, group) {
      return drawShape(cfg).featureTreeShape(cfg, group)
    },
  },
  'single-node',
)

// 初始化G6图形
const initG6 = (initData: any) => {
  container.value = document.getElementById(props.domId)
  const width = container.value?.scrollWidth
  const height = container.value?.scrollHeight
  // 创建一个新的G6树形图
  const graph = new G6.TreeGraph({
    container: props.domId, // 指定图形容器的ID
    width, // 设置图形的宽度
    height, // 设置图形的高度
    modes: {
      default: [...attrConfigHandle().modes().default], // 设置图形的模式
    },
    defaultNode: {
      ...attrConfigHandle().defaultNode(), // 设置默认节点的配置
    },
    fitCenter: true, // 设置图形居中
    renderer: 'svg', // 设置渲染器为svg
    linkCenter: true, // 设置连接中心
    defaultEdge: {
      ...attrConfigHandle().defaultEdge(), // 设置默认边的配置
    },
    layout: {
      ...attrConfigHandle().layout(), // 设置布局的配置
    },
  })

  graph.node(function (node) {
    return {
      label: node.id,
      labelCfg: {
        position: node.children && node.children.length > 0 ? 'left' : 'right',
        offset: 5,
      },
    }
  })
  render(graph, initData)
}
// 调整图形的大小以适应容器的变化
const graphResize = (graph: any) => {
  if (!graph || graph.get('destroyed')) return
  if (!container.value || !container.value.scrollWidth || !container.value.scrollHeight) return
  graph.changeSize(container.value.scrollWidth, container.value.scrollHeight)
}
// 渲染图形
const render = (graph: any, initData: any) => {
  graph.data(initData) // 将数据加载到图形中
  graph.render() // 渲染图形
  graph.fitView() // 使图形适应视图
  //  如果在浏览器环境中,当窗口大小改变时,调整图形的大小以适应容器的变化
  if (typeof window !== 'undefined')
    window.onresize = () => {
      graphResize(graph)
    }
}

onMounted(() => {
  initG6(initTreeData.value)
})
</script>

3. 模块抽离

./initAttrConfig.ts

/**
 * 生成节点配置
 * @returns 返回以下配置属性
 * modes - 生成模式配置
 * defaultNode - 生成默认节点配置
 * defaultEdge - 生成默认边配置
 * layout - 生成布局配置
 */
export const attrConfigHandle = () => {
  // 生成模式配置
  const modes = () => {
    return {
      // 默认模式,包括:拖拽画布、缩放画布、拖拽节点
      default: ['drag-canvas', 'zoom-canvas', 'drag-node'],
    }
  }
  // 生成默认节点配置
  const defaultNode = () => {
    return {
      type: 'dom-node', // 节点类型: 矩形 rect/ 默认circle
      size: [80, 30], // 节点大小,此处为 80*30
      anchorPoints: [
        // 节点锚点,此处为左中和右中两个点
        [0, 0.5],
        [1, 0.5],
      ],
    }
  }
  // 生成默认边配置
  const defaultEdge = () => {
    return {
      type: 'cubic-horizontal', // 边的类型,此处为水平方向的曲线
      /*  通过配置边的 style 属性来设置弯曲半径和到端节点的最小距离 */
      style: {
        radius: 5, // 弯曲半径
        offset: 10, // 到端节点的最小距离
        endArrow: true, // 是否显示箭头
        /* 设置其他样式 */
        stroke: '#2c3e50', // 边的颜色
      },
    }
  }
  // 生成布局配置
  const layout = () => {
    return {
      type: 'compactBox', // 布局类型,此处为紧凑型盒子布局
      direction: 'LR', // 布局方向,此处为从左到右
      getId: function getId(d: { id: string }) {
        // 获取节点 id 的回调函数
        return d.id
      },
      getHeight: function getHeight() {
        // 获取每个节点的高度
        return 16
      },
      getWidth: function getWidth() {
        // 获取每个节点的宽度
        return 16
      },
      getVGap: function getVGap() {
        // 获取每个节点的垂直间隙
        return 30
      },
      getHGap: function getHGap() {
        // 获取每个节点的水平间隙
        return 50
      },
    }
  }
  return {
    modes,
    defaultNode,
    defaultEdge,
    layout,
  }
}

./registerNode.ts

import TreeNodeHtml from '@/views/featureManage/featureTree/topologyToolKit/TreeNodeHtml.vue'
import { createApp } from 'vue'
/**
 * 绘制图形
 * 参数介绍:
 * @param cfg:节点的配置项
 * @param group: 图形分组,节点中的图形对象的容器
 * @returns 返回以下图形
 * featureTreeShape -创建特征树形状
 */
export const drawShape = (cfg: any) => {
  const nodeWidth = cfg.size[0]
  const nodeHeight = cfg.size[1]
  // 创建特征树形状
  const featureTreeShape = (cfg: any, group: any) => {
    const container = document.createElement('div')
    const app = createApp(TreeNodeHtml, { domNodeMsg: { ...cfg } })
    app.mount(container)
    const shape = group.addShape('dom', {
      attrs: {
        width: nodeWidth,
        height: nodeHeight,
        html: container.innerHTML,
      },
      name: 'dom-shape',
    })
    return shape
  }

  return {
    featureTreeShape,
  }
}

[TreeNodeHtml.vue] 自定义节点html渲染

<template>
  <div class="status-node" :style="nodeStyle()">
    <div :id="domNodeMsg.id" class="dom-node">
      <span style="cursor: pointer">{{ domNodeMsg.name }}</span>
    </div>
  </div>
</template>

<script lang="ts" setup>
import { ref } from 'vue'
import { attrConfigHandle } from './attrConfig'

const props = defineProps(['domNodeMsg'])
const domNode = ref(props.domNodeMsg)

const nodeStyle = () => {
  return attrConfigHandle().nodeLevelColor[domNode.value.featureCategory]
}
</script>

<style scoped>
.status-node {
  background-color: #fff;
  border: 1px solid #ccc;
  border-radius: 10px;
  text-align: center;
  font-size: 12px;
  padding: 0px 5px;
  color: #fff;
  .dom-node {
    text-overflow: ellipsis;
    overflow: hidden;
    white-space: nowrap;
  }
}
</style>

./attrConfig.ts

/**
 * 节点配置
 * @returns
 */
export const attrConfigHandle = () => {
  // 节点等级样式配置
  const nodeLevelColor: any = {
    FIRST_STAGE: {
      background: '#1b8a0f',
    },
    SECOND_STAGE: {
      background: '#5b8ff9',
    },
    THIRD_STAGE: {
      background: '#ff9d00',
    },
    FOURTH_STAGE: {
      background: '#b09a7f',
    },
    FIFTH_STAGE: {
      background: '#a27fb0',
    },
  }
  return {
    nodeLevelColor,
  }
}

三、目录结构

在这里插入图片描述

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

第九节HarmonyOS 常用基础组件14-DataPanel

1、描述 数据面板组件&#xff0c;用于将多个数据占比情况使用占比图进行展示。 2、接口 DataPanel(options:{values: number[], max?: numner, type?: DataPanelType}) 3、参数 参数名 参数类型 必填 描述 values number[] 是 数据值列表&#xff0c;最多含9条数…

SpringCloud微服务常见问题

1 微服务 返回面试宝典 问题1 SpringCloud常见组件有哪些&#xff1f; SpringCloud包含的组件很多&#xff0c;有很多功能是重复的&#xff0c;其中最常见的组件包括&#xff1a; 注册中心组件&#xff1a;Eureka、Nacos等&#xff1b;负载均衡组件&#xff1a;Ribbon&…

Spring Security的入门案例!!!

一、导入依赖 <dependencies><!--web--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--security--><dependency><groupId>…

如何获得《幻兽帕鲁》隐藏帕鲁唤夜兽?13000个配种配方查询 幻兽帕鲁Steam好评率还在涨 Mac苹果电脑玩幻兽帕鲁 Crossover玩Windows游戏

《幻兽帕鲁》是一款Steam平台热门游戏&#xff0c;开放式大陆和养成式冒险结合&#xff0c;成为2024首款热门游戏&#xff0c;不过由于官方仅发布了Windows版的游戏客户端&#xff0c;Mac用户无法直接玩&#xff0c;好在有Crossover这样的神器&#xff0c;让苹果电脑也能玩上《…

OCP NVME SSD规范解读-8.SMART日志要求-2

SMART-7&#xff1a; 软错误ECC计数可能是记录了被第一级ECC&#xff08;比如LDPC Hard Decode&#xff09;成功纠正过的读取错误次数。这意味着数据恢复成功&#xff0c;但依然表明存储介质出现了某种程度上的可靠性下降。 LDPC码是一种基于稀疏矩阵的纠错码&#xff0c;它由…

WebGL 入门:开启三维网页图形的新篇章(下)

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

go基础-垃圾回收+混合写屏障GC全分析

垃圾回收(Garbage Collection&#xff0c;简称GC)是编程语言中提供的自动的内存管理机制&#xff0c;自动释放不需要的对象&#xff0c;让出存储器资源&#xff0c;无需程序员手动执行。 Golang中的垃圾回收主要应用三色标记法&#xff0c;GC过程和其他用户goroutine可并发运行…

高端车规MCU的破局之路

目录 1 低质量的无效内卷 2 高端车规MCU产品共性 2.1 支持标定测量 2.2 低延迟通信加速 2.3 完备的网络安全解决方案 2.4虚拟化 3 国产替代的囚徒困境 1 低质量的无效内卷 近几年&#xff0c;车规MCU国产替代的呼声此消彼长&#xff0c;但仍然集中在低端产品。 从产…

网络安全知识和华为防火墙

网络安全 网络空间安全 ---Cyberspace 2003年美国提出的网络空间概念 ---一个由信息基础设施组成的互相依赖的网络。 我国官方文件定义&#xff1a;网络空间为继海、陆、空、天以外的第五大人类互动领域。 通信保密阶段 --- 计算机安全阶段 --- 信息系统安全 --- 网络空间安…

引用httplib时报undefined reference to `__imp_WSASocketW‘的解决方案

报错信息如下&#xff1a; undefined reference to __imp_getaddrinfo undefined reference to __imp_WSASocketW’ undefined reference to __imp_socket undefined reference to __imp_setsockopt’ undefined reference to __imp_setsockopt undefined reference to __imp_…

主从数据库MySQL服务重启步骤与注意事项

主从数据库MySQL服务重启步骤与注意事项 实验环境&#xff1a; 172.20.26.34 &#xff08;主应用服务器&#xff09; 172.20.26.26 &#xff08;备应用服务器&#xff09; 172.20.26.37 &#xff08;主库服务器&#xff09; 172.20.26.38 &#xff08;从库服务器&…

防御保护----防火墙基本知识

一.防火墙的基本知识--------------------------------------------------------- 防火墙&#xff1a;可以想象为古代每个城市的城墙&#xff0c;用来防守敌军的攻击。墙&#xff0c;始于防&#xff0c;忠于守。从古至今&#xff0c;墙予人以安全之意。 防火墙的主要职责在于&…

【客户端性能测试】手机设备的“高中端”怎么判断

在做客户端性能测试的时候&#xff0c;选择手机是一个老大难话题了&#xff0c;我们不可能随便拿一台设备就开工&#xff0c;最少也得选择高端机、终端机、低端机来看看结果。 一、先上科普 1.1 SoC 1.2 CPU 1.3 厂商rom 1.4 XXXm 二、划分思路 2.1 思路【目前是没有市面…

python字典JSON 和csv文件

JSON与Python字典 Python中的字典与JSON非常类似而且支持嵌套结构。Json通过key取值的过程和python字典通过索引取值过程完全一致。JavaScript数据类型&#xff08;值&#xff09;对应的Python数据类型&#xff08;值&#xff09; JSONPythonobjectdictarraylist/tuplestring…

Linux自动备份MySQL数据库

目录 1. 创建备份目录2. 创建自动化备份脚本3. 执行备份脚本测试4. 设置每天凌晨两点自动执行 1. 创建备份目录 cd home mkdir backup2. 创建自动化备份脚本 vim backup.sh编辑脚本内容主机&#xff0c;用户名&#xff0c;密码&#xff0c;备份数据库及备份路径自行填写 #!/…

ESP8266 传感器搭配 Node-RED实时显示数据,邮件告警 实验

前言 esp8266 12f,wif模块,接倾斜传感器,火焰传感器,烟雾传感器,水浸传感器,蜂鸣器。通过mqtt发布数据,并使用node-red实时获取数据,显示到页面上。并且通过邮件和页面两种方式报警。 需求如下: ①倾斜传感器:监测是否保持平衡。UI界面显示平衡度。如果不平衡,UI界…

制作OpenSSH 9.6 for openEuler 22.03 LTS的rpm升级包

OpenSSH作为操作系统底层管理平台软件&#xff0c;需要保持更新以免遭受安全攻击&#xff0c;编译生成rpm包是生产环境中批量升级的最佳途径。本文在国产openEuler 22.03 LTS系统上完成OpenSSH 9.6的编译工作。 一、编译环境 1、准备环境 基于vmware workstation发布的x86虚…

基于模型参考自适应的永磁同步电机MATLAB仿真模型

微❤关注“电气仔推送”获得资料&#xff08;专享优惠&#xff09; 模型简介 首先对传感器采集的电机电流和电压进行坐标变换&#xff0c;分别求得 dq轴的电流、电压。以此为依据&#xff0c;通过并联条模型计算 dq轴的电流的估计量&#xff0c;得到电流误差&#xff0c;然后…

Cloudreve个人网盘系统源码 支持云存储(七牛、阿里云OSS、腾讯云COS、又拍云、OneDrive) 基于Go框架

现在的网盘动不动就限速&#xff0c;涨价&#xff0c;弄得很是心烦。今天分享一款开源免费的网盘项目&#xff0c;基于 Go 语言开发的 Cloudreve。Cloudreve基于Go框架云存储个人网盘系统源码支持多家云存储驱动&#xff08;从机、七牛、阿里云 OSS、腾讯云 COS、又拍云、OneDr…

[GXYCTF2019]禁止套娃(特详解)

刚打开页面什么都没有&#xff0c;抓包也什么都没有 那就dirsaerch扫一下&#xff0c;发现状态码都是429&#xff0c;访问太快了&#xff08;这里很多师傅都没有说明或者说清楚&#xff09; 这里改了一下线程&#xff08;kali自带的&#xff0c;如果用的脚本要加前面要加python…