网络公司做的网站我能改后台么/关键词搜索排名公司
文章目录
- 项目需求
- 一、需要解决的问题
- 二、初步使用
- 1.动态数据-组件封装(解决拖拽会留下痕迹的问题,引用图片,在节点右上角渲染图标,实现,事现旋转动画,达到loading效果)
- 2.文本太长,超出部分显示(...),如下函数返回新的文本和文本宽度
- 3.根据某些字段的值给线增加动画,并在线上渲染文本
- 4.自定义按钮,实现局部区域点击
- 5.开启自带的操作栏
- 5.鼠标悬浮展示数据
项目需求
antv/G6 - 4.8.24 版本地址
实现一个流程图,根据不同阶段、不同功能、不同状态来显示图形
1、线,需要根据状态展示不同的颜色和动画效果
2、节点部分区域需要点击功能
3、文本太长需要显示…(三个点)
4、不同状态的节点需要使用不同icon(svg图片)
5、根据需求,采用G6缩进树的布局方式,缩进树地址
6、鼠标悬浮需要展示详情数据
7、需要操作栏快速缩放还原比例
一、需要解决的问题
1、4xx版本,节点拖拽会留下痕迹,由于我画布是白色的底,所以使用官方提供的解决方案,就是在节点最底层画一个白色的矩形(图形后画的会覆盖先画)
二、初步使用
1.动态数据-组件封装(解决拖拽会留下痕迹的问题,引用图片,在节点右上角渲染图标,实现,事现旋转动画,达到loading效果)
由于旋转会绕着节点的中心点,所以需要将节点的中心点移到右上角图形的中心
假设:右上角图形中心点距离顶部和在右边的距离是12,则中心点设置为(-w + 12,-12)
vue3代码如下(示例):
<template><divid="mountNode"ref="mountNodeRef"></div>
</template>
<script setup lang="ts">
import { ref,reactive } from 'vue'
import G6 from '@antv/g6'
import runImg from '@/assets/run.svg'const treeGraph = reactive<any>({graph: {},
})interface DataType{id:stringchildren:DataType[]
}const drawerImg= (cfg: any, group: any, w: number, h: number) => {// 图片let imgswitch (cfg.status) {case StatusType.ING:img = runImgbreakcase StatusType.ABNORMAL:img = abnormalImgbreakcase StatusType.END:img = successImgbreakdefault:img = waitImg}const image = group.addShape('image', {attrs: {x: -8,y: -8,width: 16,height: 16,img, // import 引入的图片},name: 'image-shape',})// 旋转动画if (cfg.status === StatusType.ING) {image.animate((ratio: any) => {// 每一帧的操作,入参 ratio:这一帧的比例值(Number)。返回值:这一帧需要变化的参数集(Object)。// 旋转通过矩阵来实现// 当前矩阵(矩阵文档中有描述)const matrix = [1, 0, 0, 0, 1, 0, 0, 0, 1]// 目标矩阵const toMatrix = G6.Util.transform(matrix, [['r', ratio * Math.PI * 2]])// 返回这一帧需要的参数集,本例中只有目标矩阵return {matrix: toMatrix,}},{repeat: true, // 动画重复duration: 3000,easing: 'easeLinear',})}
}// 注册自定义节点
G6.registerNode('card-node', {draw: function drawShape(cfg: any, group) {// 获取初始化时defaultNode设置的宽高const w = cfg.size[0]const h = cfg.size[1]// 中心点坐标(默认是节点左上角),这里设置成图形中心(影响图像旋转等功能)// const centerX = -w / 2// const centerY = -h / 2// 中心点坐标(默认是节点左上角),这里设置成节点右上角距离顶部和右边12的位置const centerX = -w + 12const centerY = -12const r = 10 // 边的倒角 radiusconst color = '#004CFE' // 文本颜色const baseColor = '#001043' // 文本颜色const backgroundColor = 'rgba(0,76,254,0.2)' // 填充颜色// 主图,容器矩形,画白色容器矩形,防止拖拽产生的痕迹const shape = group.addShape('rect', {attrs: {x: centerX,y: centerY,width: w,height: h,shadowColor: 'rgba(0,0,0,0.16)',shadowOffsetX: 0,shadowOffsetY: 0,shadowBlur: 4,radius: r, // 4个角都设置圆角fill: '#fff',},name: 'main-box', // 必须,用来操作图行,需要唯一// draggable: true, // 只用为true,图形才可以拖拽,同时需要配置modes中开启拖拽功能,如果上层重叠有图形,重叠的图形也需要开启该属性})// 之后添加的图形会默认覆盖在之前添加的图形上面// 新增图形,矩形头部group.addShape('rect', {attrs: {x: centerX,y: centerY,width: w,height: 28,fill: baseColor ,radius: [r, r, 0, 0], // 左上和右上设置圆角,左下和右下不变},name: 'header-box',// draggable: true,})// 矩形头部文本group.addShape('text', {attrs: {x: centerX + 8,y: centerY + 14,lineHeight: 20,text: cfg.text, // 节点数据text字段fill: color,textBaseline: 'middle', // 文本垂直居中},name: 'title',// draggable: true,})// 右上角图标drawerImg(cfg, group, w, h)// 有子数据的矩形添加收起/展开的按钮cfg.children &&group.addShape('marker', {attrs: {x: 12,y: h / 2 - 12,r: 6,cursor: 'pointer',symbol: cfg.collapsed ? G6.Marker.expand : G6.Marker.collapse,// G6 自带的标记stroke: '#666',lineWidth: 1,fill: '#fff',},name: 'collapse-icon',})return shape},setState(name, value, item: any) {// 开启缩进树的节点按钮,响应节点点击事件,展开、收起子节点树if (name === 'collapsed') {const marker = item.get('group').find((ele: any) => ele.get('name') === 'collapse-icon')const icon = value ? G6.Marker.expand : G6.Marker.collapsemarker.attr('symbol', icon)}},
})// 初始化图形实例
const initGraph = () => {const width = mountNodeRef.value.scrollWidthconst height = mountNodeRef.value.scrollHeightconst graph = new G6.TreeGraph({container: 'mountNode', // String | HTMLElement,必须,容器 id 或容器本身width, // Number,必须,图的宽度height, // Number,必须,图的高度plugins: [tooltip, toolbar], // 添加tooltip// 画布配置modes: {default: ['drag-canvas', 'zoom-canvas'], // 允许拖拽画布、放缩画布(没有添加节点拖拽)},defaultNode: {type: 'card-node',// 自定义node节点size: [132, 98],},defaultEdge: {type: 'cubic-horizontal',style: {endArrow: true,},},// 基本布局配置layout: {type: 'indented', // 布局模式(缩进树布局)direction: 'LR', // 布局方向dropCap: false,indent: 260, // 图形水平间距getHeight: () => {return 100 // 图形垂直间距},},})toRaw(treeGraph).graph = graph
}onMounted(() => {if (mountNodeRef.value) {// 初始化图形,渲染需要在异步数据更新之后initGraph()}
})// 模拟数据
// const data = {
// id: 'A',
// text:'我是文本超级长的文本给个省略号',
// status:'ING',
// children: [
// {
// id: 'A1',
// text:'我是文本',
// status:'ING',
// children: [{ id: 'A11', text:'我是文本', }, { id: 'A12', text:'我是文本', }],
// },
// {
// id: 'A2',
// text:'我是文本',
// children: [
// {
// id: 'A21',
// text:'我是文本',
// children: [{ id: 'A211', text:'我是文本', }, { id: 'A212', text:'我是文本', }],
// },
// {
// id: 'A22',
// text:'我是文本',
// },
// ],
// },
// ],
// };// 监听数据变化渲染图形
watch(() => props.data,(value) => {toRaw(treeGraph).graph.data(value)toRaw(treeGraph).graph.render() // 渲染图toRaw(treeGraph).graph.fitView() // 布局// 监听节点点击toRaw(treeGraph).graph.on('node:click', (e: any) => {/*** 控制展开收起的小图标事件* collapse-icon 是创建图形的name,将点击响应确定在一定的范围*/if (e.target.get('name') === 'collapse-icon') {e.item.getModel().collapsed = !e.item.getModel().collapsedtoRaw(treeGraph).graph.setItemState(e.item, 'collapsed', e.item.getModel().collapsed)toRaw(treeGraph).graph.layout()}})// 可视窗口变化,更新视图if (typeof window !== 'undefined') {window.onresize = () => {if (!toRaw(treeGraph).graph || toRaw(treeGraph).graph.get('destroyed')) returnif (!mountNodeRef.value || !mountNodeRef.value.clientWidth || !mountNodeRef.value.clientHeight) returntoRaw(treeGraph).graph.changeSize(mountNodeRef.value.clientWidth, mountNodeRef.value.clientHeight)toRaw(treeGraph).graph.fitView()}}}
)
</script>
2.文本太长,超出部分显示(…),如下函数返回新的文本和文本宽度
// 计算文本宽度,和超出显示三个点
const truncateText = (text: string, maxWidth: number, fontSize = 12, fontFace = 'Microsoft YaHei') => {// 创建一个临时canvas来测量文本宽度const tempCanvas = document.createElement('canvas')const tempCtx = tempCanvas.getContext('2d')!tempCtx.font = fontSize + 'px ' + fontFace// 计算文本宽度let textWidth = tempCtx.measureText(text).width// 如果文本宽度超出最大宽度,则截断并添加省略号if (textWidth > maxWidth) {// 尝试去除一个字符,然后重新测量,直到文本宽度小于或等于最大宽度while (textWidth > maxWidth) {text = text.slice(0, -1) // 移除最后一个字符并添加省略号textWidth = tempCtx.measureText(text).width}return {width: textWidth,text: text + '...', // 移除最后一个字符并添加省略号}} else {return {width: textWidth,text,}}
}// 用例,修改上文 - 矩形头部文本
G6.registerNode('card-node', {draw: function drawShape(cfg: any, group) {// ...其他配置// 矩形头部文本const { text } = truncateText(cfg.text, 100)group.addShape('text', {attrs: {x: centerX + 8,y: centerY + 14,lineHeight: 20,// text: cfg.text, // 节点数据text字段text: text,fill: color,textBaseline: 'middle', // 文本垂直居中},name: 'title',// draggable: true,})}
})
3.根据某些字段的值给线增加动画,并在线上渲染文本
需要修改defaultEdge配置,代码如下(示例):
const lineDash = [4, 2, 1, 2]
G6.registerEdge('line-dash',{afterDraw(cfg: any, group: any) {// 获取图形组中的第一个图形,在这里就是边的路径图形const shape = group.get('children')[0]// 由于没有直接的线数据,需要根据线上的源节点或者目标节点的id来获取,节点的数据// 这里获取目标节点的模型数据const targetModel = toRaw(treeGraph).graph.findById(cfg.target).getModel()if (targetModel.status && targetModel.status === 'ING') {// 增加动画let index = 0// Define the animationshape.animate(() => {index++if (index > 9) {index = 0}const res = {lineDash,lineDashOffset: -index,}return res},{repeat: true, // whether executes the animation repeatlyduration: 3000, // the duration for executing once})}},},'cubic-horizontal' // extend the built-in edge 'cubic-horizontal'
)const initGraph = () => {const graph = new G6.TreeGraph({// ...其他配置defaultEdge: {type: 'line-dash',// 自定义线段style: {lineWidth: 2,stroke: '#bae7ff',endArrow: true,},// 线上文本的样式配置labelCfg: {autoRotate: true,style: {fill: '#1890ff',fontSize: 14,background: {fill: '#ffffff',padding: [2, 2, 2, 2],radius: 2,},},},},})
}
线上配置文本需要在graph.render() 之前,修改上文中的watch
watch(() => props.data,(value) => {// 设置各个边样式及其他配置,以及在各个状态下节点的 KeyShape 的样式。toRaw(treeGraph).graph.edge(function (edge: any) {const targetItem = toRaw(treeGraph).graph.findById(edge.target as string).getModel()const config: any = {}// 存在流量if (targetItem.status) {if (targetItem.status === 'ERROR') {config.style = {stroke: 'red',}}config.label = targetItem.status}return config})// ...其他配置toRaw(treeGraph).graph.render() // 渲染图})
4.自定义按钮,实现局部区域点击
1、按钮由一个矩形节点和文本节点组成,上文G6.registerNode增加配置
2、节点点击,锁定局部区域,graph的node:click事件
G6.registerNode('card-node', {draw: function drawShape(cfg: any, group) {// ...其他配置// 按钮矩形区域group.addShape('rect', {attrs: {x: -52,y: h - 38,width: 64,height: 26,fill: 'rgba(35,131,228,0.1)',radius: [4, 0, r, 0],cursor: 'pointer',},name: 'btn',draggable: true,})group.addShape('text', {attrs: {x: -20,y: h - 25,text: '查看详情',fill: '#2383E4',fontSize: 12,fontFamily: textFontFace,textAlign: 'center', // 文本水平居中textBaseline: 'middle', // 文本垂直居中cursor: 'pointer',},name: 'btn-text',draggable: true,})}
})toRaw(treeGraph).graph.on('node:click', (e: any) => {// 点击了查看详情if (e.target.get('name') === 'btn-text' || e.target.get('name') === 'btn') {const model = e.item.getModel()// 获取数据console.log(model)}
})
5.开启自带的操作栏
const toolbar = new G6.ToolBar()
const graph = new G6.TreeGraph({plugins: [..., toolbar], // 添加tooltip
})
5.鼠标悬浮展示数据
const graph = new G6.TreeGraph({plugins: [..., tooltip], // 添加tooltip
})const tooltip = new G6.Tooltip({offsetX: 10,offsetY: 10,// 允许出现 tooltip 的 item 类型itemTypes: ['node'],shouldBegin: (e: any) => {const model = e.item.getModel()const type = e.item.getType()// if (type === 'node' && model.id !== 'custom') {// return true// }return false},// 自定义 tooltip 内容getContent: (e: any) => {const model = e.item.getModel()let outDiv = document.createElement('div')outDiv.style.width = 'fit-content'outDiv.innerHTML = `<h4 style="font-size:16px;font-weight:bold;margin-bottom:6px">节点详情</h4><ul style="font-size:14px;"><li>type: ${model.nodeType}</li><li>code: ${model.code}</li><li>name: ${model.name}</li></ul>`return outDiv},
})
相关文章:

vue3项目使用@antv/g6实现可视化流程功能
文章目录 项目需求一、需要解决的问题二、初步使用1.动态数据-组件封装(解决拖拽会留下痕迹的问题,引用图片,在节点右上角渲染图标,实现,事现旋转动画,达到loading效果)2.文本太长,超出部分显示(...),如下函…...

【Linux网络(一)初识计算机网络】
一、网络发展 1.发展背景 2.发展类型 二、网络协议 1.认识协议 2.协议分层 3.OSI七层模型 4.TCP/IP协议 三、网络传输 1.协议报头 2.局域网内的两台主机通信 3.跨网络的两台主机通信 四、网络地址 1.IP地址 2.MAC地址 一、网络发展 1.发展背景 计算机网络的发展…...

Vulhub——Log4j、solr
文章目录 一、Log4j1.1 Apache Log4j2 lookup JNDI 注入漏洞(CVE-2021-44228)1.2 Apache Log4j Server 反序列化命令执行漏洞(CVE-2017-5645) 二、Solr2.1 Apache Solr 远程命令执行漏洞(CVE-2017-12629)2.…...

linux 设置程序自启动
程序随系统开机自启动的方法有很多种, 这里介绍一种简单且常用的, 通过系统的systemd服务进行自启动。 第一步: 新建一个.service文件 sudo vim /etc/systemd/system/myservice.service[Unit] DescriptionMy Service #Afternetwork.target[…...

PostgreSQL 分区表与并行查询(十)
1. 分区表概述 1.1 什么是分区表 分区表是将大表分割成更小、更可管理的部分的技术。每个分区表都可以单独进行索引和查询,从而提高查询性能和管理效率。 1.2 分区策略 1.2.1 基于范围的分区 按照时间范围或者数值范围进行分区,如按月或按地区。 C…...

React Hooks使用规则:为什么不在条件语句和循环中使用它们
React Hooks为函数组件引入了状态和生命周期特性,极大地增强了其功能。然而,正确使用Hooks是确保组件稳定性和性能的关键。本文将探讨React Hooks的基本规则,以及为什么我们不应该在条件语句和循环中使用它们。 Hooks的基本规则 React团队为…...

【Docker】Consul 和API
目录 一、Consul 1. 拉取镜像 2. 启动第一个consul服务:consul1 3. 查看consul service1 的ip地址 4. 启动第二个consul服务:consul2, 并加入consul1(使用join命令) 5. 启动第三个consul服务:consul3&…...

Python polars学习-07 缺失值
背景 polars学习系列文章,第7篇 缺失值 该系列文章会分享到github,大家可以去下载jupyter文件,进行参考学习 仓库地址:https://github.com/DataShare-duo/polars_learn 小编运行环境 import sysprint(python 版本:…...

前端面试题(八)答案版
面试形式:线下面试:一面:30分钟二面:30分钟 特殊要求:内网开发自研UI组件库(无文档介绍)学习能力要求高 面试评价:题目灵活应用性较强 面试官:项目负责人前端负责人 …...

在交易中出场比入场更为重要
出场策略和交易退出机制比交易者入场的方式更为关键,它们对整体回报和结果的持续性有着更大的影响。 即使交易者入场时的条件并非最佳,良好的出场策略也能扭转局势。反之,即使交易者以近乎完美的条件入场,若出场策略管理不当&…...

【D3.js in Action 3 精译】关于本书
文章目录 本书读者本书结构与路线图本书代码liveBook 在线论坛 D3.js 项目的传统开发步骤 本书读者 这本书适用于所有渴望在数据可视化工作中获得完全创意自由的人,从定制化的经典图表到创建独特的数据可视化布局,涵盖内容广泛,应有尽有。您…...

【408考点之数据结构】二叉树的概念与实现
二叉树的概念与实现 一、二叉树的概念 二叉树是一种特殊的树结构,其中每个节点最多有两个子节点,分别称为左子节点和右子节点。二叉树广泛应用于许多计算机科学领域,如表达式解析、排序、搜索算法等。 二、二叉树的性质 性质1:…...

STM32之二:时钟树
目录 1. 时钟 2. STM3时钟源(哪些可以作为时钟信号) 2.1 HSE时钟 2.1.1 高速外部时钟信号(HSE)来源 2.1.2 HSE外部晶体电路配置 2.2 HSI时钟 2.3 PLL时钟 2.4 LSE时钟 2.5 LSI时钟 3. STM32时钟(哪些系统使用时…...

第十四站:Java玫瑰金——移动开发(第二篇)
处理不同类型的网络连接和增强错误处理及用户反馈,需要我们对网络状态检查逻辑进行扩展,并在UI上给予用户适当的提示。以下是对Java代码的进一步扩充: 网络状态检查扩展:区分Wi-Fi和移动数据,并根据网络类型提供不同的…...

数据处理技术影响皮质-皮质间诱发电位的量化
摘要 皮质-皮质间诱发电位(CCEPs)是探究颅内人体电生理学中有效连接性的常用工具。与所有人体电生理学数据一样,CCEP数据极易受到噪声的影响。为了解决噪声问题,通常会对CCEP数据进行滤波和重参考,但不同的研究会采用不同的处理策略。本研究…...

ResultSet的作用和类型
ResultSet的作用: ResultSet在Java中主要用于处理和操作数据库查询结果。它是一个接口,提供了一系列方法来访问和操作数据库查询得到的结果集。具体来说,ResultSet的作用包括: 获取查询结果:通过ResultSet可以获取数…...

计算机网络:运输层 - TCP首部格式 连接的创建与释放
计算机网络:运输层 - TCP首部格式 & 连接的创建与释放 TCP首部格式源端口 目的端口序号确认号数据偏移保留控制位窗口检验和紧急指针 TCP连接创建 - 三次握手TCP传输过程TCP连接释放 - 四次挥手 TCP首部格式 TCP的首部如下: 首部的前20 byte是固定的…...

妈耶!被夸爆的零售数据分析方案在这里
在竞争激烈的零售市场中,数据分析已成为企业决胜的关键。今天,就为大家揭秘一份备受赞誉的零售数据分析方案——奥威BI零售数据分析方案,它围绕“人、货、场、供、财”五大主题,助力企业精准决策,实现业务增长。 一、人…...

AI探索:最佳落地应用场景
如果说今年的风口,那一定是 AI。不过AI像一把双刃剑,既有助益也有风险。我们将从IBM Watson的高飞与坠落,到Google Allo的黯然失色,探索AI应用中的教训。同时,瑞幸咖啡的成功故事展现了凭借策略得当的AI应用࿰…...

2024年最新机动车签字授权人考试题库。
31."简易瞬态工况法"所使用的五气分析仪的温度范图:分析系统及相关部件应在( )。 A.0-40℃ B.0-50℃ C.0-60℃ D.-10-40℃ 答案:A 32.稀释氧传感器环境空气量程检测时的读数值位于( )%vol范围之外时,应…...

软RAID
硬盘 连续空间 无法 扩容 lvm 非连续空间 可以动态扩容 raid 备份, 提高读写性能,不能扩容 raid 是磁盘的集合,按照排列组合的方法不 一,给 raid 去了不同的名字 raid0 raid1 raid5 raid10 什么是 RAID "RAID"…...

IDEA 学习之 启动“卡死”
目录 1. 断点问题2. IDEA 版本问题 1. 断点问题 部分断点涉及应用启动,会导致启动“卡死” 2. IDEA 版本问题 部分 IDEA 版本存在启动问题,本人之前遇到过(别人启动三分钟,我启动半个小时)。更换别的版本ÿ…...

豆瓣高分项目管理书籍推荐
📬豆瓣网站上有很多项目管理领域的书籍获得了较高的评分,以下是一些高分项目管理书籍的精选列表,发出来跟大家分享一下: 《项目管理知识体系指南(PMBOK指南)》 【内容简介】这本书是美国项目管理协会&…...

关于docker存储overlay2相关问题
报错如下: 报错原因:使用rm -rf 清理overlay2导致的,非正常清理。 正常清理命令如下: # 清理Docker的所有构建缓存 docker builder prune# 删除旧于24小时的所有构建缓存 docker builder prune --filter "until24h"#删…...

实现批量自动化电商数据采集|商品详情页面|店铺商品信息|订单详情数据
电商数据采集是指通过技术手段获取电商平台上的商品信息、店铺信息和订单信息等数据。这些数据可以用于市场分析、竞品分析、用户行为分析等。 商品详情页面是指电商平台上展示商品详细信息的页面,包括商品名称、价格、图片、描述、评价等信息。通过采集商品详情页…...

ES6(ECMAScript 6.0) 新特性
1 ES6 基本介绍 (1)ECMAScript 6.0(简称 ES6)是 JavaScript 语言的下一代标准, 2015 年 6 月发布。 (2)ES6 设计目标:达到 JavaScript 语言可以用来编写复杂的大型程序,成为企业级开发语言 &…...

性能工具之 JMeter 常用组件介绍(八)
文章目录 一、Jmeter命令行启动二、Jmeter脚本录制 本文主要介绍JMeter命令行启动和脚本录制功能 一、Jmeter命令行启动 Jmeter有两种运行: 一种是采用的界面模式(GUI)启动,会占用不少系统资源;另一种是命令行模式(n…...

分布式锁(Redission)
分布式锁: 使用场景: 通常对于一些使用率高的服务,我们会进行多次部署,可能会部署在不同的服务器上,但是他们获取和操作的数据仍然是同一份。为了保证服务的强一致性,我们需要对线程进行加锁,…...

【ARMv8/v9 GIC 系列 3 -- GIC 的 类型寄存器 GICD_TYPER】
文章目录 GIC 类型寄存器 GICD_TYPERESPI_Range, 位[31:27]RSS, 位[26]No1N, 位[25]A3V, 位[24]IDBits, 位[23:19]DVIS, 位[18]LPIs, 位[17]MBIS, 位[16]NUM_LPIs, 位[15:11]SecurityExtn, 位[10]NMI, 位[9]ESPI, 位[8]CPUNumber, 位[7:5]ITLinesNumber, 位[4:0]GIC 类型寄存器…...

MATLAB算法实战应用案例精讲-【数模应用】线性判别分析(附MATLAB、python和R语言代码实现)
目录 前言 算法原理 什么是判别分析 线性判别分析(LDA) 数学模型 二分类 多分类LDA 编辑 算法思想: 费歇(FISHER)判别思想 贝叶斯(BAYES)判别思想 LDA算法流程 LDA与PCA对比 SPSSPRO 1、作用 2、输入输出描述 3、案例示例 4、案例数据 5、案例操作 …...