Antv G6 force分布式布局 icon“+“ “-“收缩自定义,关系图子节点

news2024/11/25 7:46:03

子节点收缩

    const collapseIcon = (x, y, r) => {
       // 折叠
       return [
         ['M', x - r, y],
         ['a', r, r, 0, 1, 0, r * 2, 0],
         ['a', r, r, 0, 1, 0, -r * 2, 0],
         ['M', x - r + 4, y],
         ['L', x - r + 2 * r - 4, y]
       ]
     }
     const expandIcon = (x, y, r) => {
       // 拓展
       return [
         ['M', x - r, y],
         ['a', r, r, 0, 1, 0, r * 2, 0],
         ['a', r, r, 0, 1, 0, -r * 2, 0],
         ['M', x - r + 4, y],
         ['L', x - r + 2 * r - 4, y],
         ['M', x - r + r, y - r + 4],
         ['L', x, y + r - 4]
       ]
     }
draw(cfg, group) {
      const { noSubsetSty, collapsed } = cfg
      if (noSubsetSty) { // 需要折叠的节点标志,在数据中处理添加标记
        group.addShape('circle', {
          attrs: {
            x: size,
            y: 0,
            r: 13,
            fill: 'rgba(47, 84, 235, 0.15)',
            opacity: 0,
            zIndex: -2
          },
          name: 'collapse-icon-bg'
        })
        group.addShape('marker', {
          attrs: {
            x: size,
            y: 0,
            r: 7,
            symbol: collapsed ? collapseIcon : expandIcon,
            stroke: 'rgba(0,0,0,1)',
            fill: 'rgba(0,0,0,0)',
            lineWidth: 1,
            cursor: 'pointer'
          },
          name: 'collapse-icon'
        })
      }
    },
    afterDraw(cfg, group) {
      const icon = group.find(
        element => element.get('name') === 'collapse-icon'
      )
      if (icon) {
        const bg = group.find(
          element => element.get('name') === 'collapse-icon-bg'
        )
        icon.on('mouseenter', () => {
          bg.attr('opacity', 1)
        })
        icon.on('mouseleave', () => {
          bg.attr('opacity', 0)
        })
      }
    },
    setState(name, value, item) {
      const group = item.getContainer()
      if (group.get('children')) {
        if (name === 'collapsed') {
          const marker = item
            .get('group')
            .findAll(ele => ele.get('name') === 'collapse-icon')
          marker[0] &&
            marker[0].attr('symbol', value ? collapseIcon : expandIcon)
          if (item._cfg.model.depth === 0) {
            marker[1] &&
              marker[1].attr('symbol', value ? collapseIcon : expandIcon)
          }
        }
      }
    }
 this.graph.on('node:click', e => {
        // 处理子节点展示问题 + -
        if (e.target.get('name') === 'collapse-icon') {
          const item = e.item
          const nodeId = item.get('id')
          const children = selectedWorks(nodeId, regroup.nodes, regroup.edges) // 查询相关子节点
          let newNodes = children.nodes
          if (newNodes.length) {
            if (e.item._cfg.model.collapsed) {
              for (let i = 0; i < newNodes.length; i++) {
                this.hiddenElements.push(newNodes[i].id)
                const item = this.graph.findById(newNodes[i].id)
                this.graph.hideItem(item, true)
                this.graph.paint()
              }
            } else {
              for (let i = 0; i < newNodes.length; i++) {
                this.hiddenElements.splice(
                  this.hiddenElements.indexOf(newNodes[i].id),
                  1
                )
                const item = this.graph.findById(newNodes[i].id)
                this.graph.showItem(item, true)
                this.graph.paint()
              }
            }
          }
          this.graph.layout({
            type: 'force',
            nodeSize: 50,
            preventOverlap: true,
            animate: false,
            linkDistance: d => {
              return 80
            },
            nodeStrength: -150,
            onTick: () => {
              this.graph.refreshPositions()
            },
            nodeSpacing: d => {
              return 80
            }
          })
          e.item._cfg.model.collapsed = !e.item._cfg.model.collapsed
          this.graph.setItemState(
            e.item,
            'collapsed',
            e.item._cfg.model.collapsed
          )
          this.graph.paint()
        }
      })

节点查找方法

/**
 * 只有被指向的点并且没有指向的点  找最末端的点,并且被指向的方向只有一个
 * source ---->  target
 */
export function noSubsetHandle(nodeID, edges) {
  let idT = edges.map(i => i.target)
  let idS = edges.map(i => i.source)
  Array.prototype.countCertainElements = function(value) {
    return this.reduce((sum, element) => (element == value ? sum + 1 : sum), 0)
  }
  let index = idT.countCertainElements(nodeID)
  let results =
    idT.indexOf(nodeID + '') > -1 &&
    index === 1 &&
    idS.indexOf(nodeID + '') === -1
  return results
}
/**
 * @description 依据节点ID 查询 子集 和 相关 边
 * @param {*} nodeID
 * @param {*} nodes
 * @param {*} edges
 */
export function selectedWorks(nodeID, nodes, edges) {
  let edgesV = []
  let nodesV = []
  edges.map(e => {
    if (+e.source === +nodeID) {
      edgesV.push({ ...e })
    }
  })
  if (edgesV.length > 0) {
    nodes.map(e => {
      if (edgesV.findIndex(x => +x.target === +e.id) > -1) {
        if (noSubsetHandle(+e.id, edges)) {
          nodesV.push({ ...e })
        }
      }
    })
  }
  let edgesVv= []
  edgesV.length && edgesV.map(i => {
    if (nodesV.findIndex(x => +x.id === +i.target) > -1) {
      edgesVv.push({...i})
    }
  })
  let obj = {}
  obj.nodes = nodesV
  obj.edges = edgesVv
  return obj
}

在这里插入图片描述

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

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

相关文章

SQL优化——插入数据优化(load指令的使用)

插入数据时的优化主键优化order by优化group by优化limit优化count优化update优化 1.插入数据时的优化 批量插入数据时最好最多别超过一千条&#xff0c;如果一次批量插入几万条数据&#xff0c;可以将其分割成多条insert语句进行插入。 mysql的事务提交方式是默认自动提交的…

Linux 下centos 查看 -std 是否支持 C17

实际工作中&#xff0c;可能会遇到c的一些高级特性&#xff0c;例如std::invoke&#xff0c;此函数是c17才引入的&#xff0c;如何判断当前的gcc是否支持c17呢&#xff0c;这里提供两种办法。 1.根据gcc的版本号来推断 gcc --version&#xff0c;可以查看版本号&#xff0c;笔者…

15.矩阵运算与img2col方式的卷积

使用矩阵计算卷积 GEMM算法 矩阵乘法运算(General Matrix Multiplication)&#xff0c;形如&#xff1a; C A B , A ∈ R m k , B ∈ R k n , C ∈ R m n C AB, A\in \mathbb{R}^{m\times k},B\in \mathbb{R}^{k\times n},C\in \mathbb{R}^{m\times n} CAB,A∈Rmk,B∈Rk…

vite4.x+vue3.x中使用装饰器语法,eslint校验不识别@的报错处理方法

在项目中&#xff0c;使用了pre-commit校验代码&#xff0c;eslint校验无法识别,导致一直无法提交代码&#xff0c;查找了资料&#xff0c;eslint版本过低&#xff0c;不能解决现在遇到的问题 最终正确的配置方法&#xff1a; 装饰器配置文件babel.config.js module.exports …

了解应用层

应用层 1. 概述2. 应用程序组织方式2.1 C/S方式2.1 P2P方式 3. 动态主机配置协议DHCP3.1 DHCP工作流程 4. 域名系统DNS4.1 域名结构4.2 域名分类4.3 域名服务器4.3.1 分类 4.4 DNS域名解析过程 5. 文件传输协议FTP5.1 FTP工作流程 6. 电子邮件系统6.1 邮件信息格式6.2 简单邮件…

EtherCAT转TCP/IP网关EtherCAT解决方案

你是否曾经为生产管理系统的数据互联互通问题烦恼过&#xff1f;曾经因为协议不同导致通讯问题而感到困惑&#xff1f;现在&#xff0c;我们迎来了突破性的进展&#xff01; 介绍捷米特JM-TCPIP-ECT&#xff0c;一款自主研发的Ethercat从站功能的通讯网关。它能够连接到Etherc…

12.面板问题

面板问题 html部分 <h1>Lorem ipsum dolor sit, amet consectetur adipisicing.</h1><div class"container"><div class"faq"><div class"title-box"><h3 class"title">Lorem, ipsum dolor.<…

TypeScript 中的常用类型声明大全

文章目录 基本数据类型1.number类型2.String 类型3. Boolean 类型4. undefined 类型5.Null类型6.Symbol类型7.BigInt类型 引用数据类型8.Array 类型9.Object 类型 TS 新增特性数据类型4.联合类型5.字面量类型6.Any 类型7.unknown 类型8.Void 类型9.never 类型10.对象类型12 tup…

基于linux下的高并发服务器开发(第三章)- 3.11 读写锁

读写锁的类型 pthread_rwlock_t int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock, const pthread_rwlockattr_t *restrict attr); int pthread_rwlock_destroy(pthread_rwlock_t *rwlock); int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock); int pthread_rwlo…

macOS 下使用 brew 命令安装 Node.js

&#x1f468;&#x1f3fb;‍&#x1f4bb; 热爱摄影的程序员 &#x1f468;&#x1f3fb;‍&#x1f3a8; 喜欢编码的设计师 &#x1f9d5;&#x1f3fb; 擅长设计的剪辑师 &#x1f9d1;&#x1f3fb;‍&#x1f3eb; 一位高冷无情的编码爱好者 大家好&#xff0c;我是 DevO…

iOS内存管理--内存的分区

内存分配区域 iOS程序内存分为5个区域 栈区&#xff0c;堆区&#xff0c;BSS&#xff0c;全局变量&#xff0c;代码区 五个区域有两种分配时间 运行时分配&#xff1a;栈区&#xff0c;堆区 栈区&#xff1a;局部变量&#xff0c;函数参数&#xff08;形式参数&#xff09;&…

Hadoop概念学习(无spring集成)

Hadoop 分布式的文件存储系统 三个核心组件 但是现在已经发展到很多组件的s 或者这个图 官网地址: https://hadoop.apache.org 历史 hadoop历史可以看这个: https://zhuanlan.zhihu.com/p/54994736 优点 高可靠性&#xff1a; Hadoop 底层维护多个数据副本&#xff0c;所…

[C初阶]循环和分支语句

目录 if...else语句 ​编辑 易犯错误 打印100以内的奇数 switch...case语句 输出星期 循环语句 对比判断 1.break终止循环 2.continue 读取字符 缓冲区读取 只输出数字字符 for循环 do...while循环 n的阶乘求和 循环实现动态打印 猜数字游戏【总结】 goto ​…

C++的各种用法展示

&#xff43;&#xff0b;&#xff0b;与数学典型算法的结合 阿姆斯特朗数 // A number is called as Armstrong number if sum of cubes of digits of number is // equal to the number itself. // For Example 153 is an Armstrong number because 153 153. #include <…

K8S初级入门系列之十二-计算资源管理

一、前言 K8S集群中着这各类资源&#xff0c;比如计算资源&#xff0c;API资源等&#xff0c;其中最重要的是计算资源&#xff0c;包括CPU&#xff0c;缓存&#xff0c;存储等。管理这些资源就是要在资源创建时进行约束和限制&#xff0c;在运行时监控这些资源的指标&#xff0…

[23] HeadSculpt: Crafting 3D Head Avatars with Text

paper | project 本文主要想解决&#xff1a;1&#xff09;生成图像的不连续问题&#xff1b;2&#xff09;3D修改中的保ID问题。针对第一个问题&#xff0c;本文引入了Landmark-based ControlNet特征图和<back-view>的text embedding&#xff1b;针对第二个问题&#x…

Python 算法基础篇:插入排序和希尔排序

Python 算法基础篇&#xff1a;插入排序和希尔排序 引言 1. 插入排序算法概述2. 插入排序算法实现实例1&#xff1a;插入排序 3. 希尔排序算法概述4. 希尔排序算法实现实例2&#xff1a;希尔排序 5. 插入排序与希尔排序的对比总结 引言 插入排序和希尔排序是两种常用的排序算法…

java后端导出前端展示

效果图 前端代码 exportExcelAll(){window.location.href getBaseUrl() Action/excelDataAll?happenDatethis.params.happenDate;},后端代码 try{Workbook workbooknew XSSFWorkbook();//创建sheetSheet sheet1workbook.createSheet("结果总数拦截记录");//写入…

第一百一十二天学习记录:数据结构与算法基础:循环链表和双向链表以及线性表应用(王卓教学视频)

循环链表 带尾指针循环链表的合并 双向链表 单链表、循环链表和双向链表的时间效率比较 顺序表和链表的比较 链式存储结构的优点 1、结点空间可以动态申请和释放&#xff1b; 2、数据元素的逻辑次序靠结点的指针来指示&#xff0c;插入和删除时不需要移动数据元素。 链式存储…

【pytho】request五种种请求处理为空和非空处理以及上传excel,上传图片处理

一、python中请求处理 request.args获取的是个字典&#xff0c;所以可以通过get方式获取请求参数和值 request.form获取的也是个字典&#xff0c;所以也可以通过get方式获取请求的form参数和值 request.data&#xff0c;使用过JavaScript&#xff0c;api调用方式进行掺入jso…