relation-graph——数据组装+鼠标移入后的详情(自定义插槽的用法)——js技能提升

news2024/7/7 18:16:01

最近在写后台管理系统的时候,遇到一个需求,就是给我一些节点,让我渲染到页面上,效果图如下:

之前写过一篇文章关于relation-graph关系图组件http://t.csdnimg.cn/7BGYm的用法

还有一篇关于relation-graph——实现右击节点显示详情+点击展开折叠操作——技能提升http://t.csdnimg.cn/K3rzf
在这里插入图片描述
关于插件的安装和使用,在此不再赘述。可以参照上面的两个链接。
在这里插入图片描述
下面给我的数据结构及想要的效果:
在这里插入图片描述

原始数据结构

this.taskRecords = {
    "nodes": [
        {
            "taskName": "完善客诉",
            "taskNodeName": "WanShanKeSu"
        },
        {
            "taskName": "PCB判责",
            "taskNodeName": "PCBPanZe"
        },
        {
            "taskName": "PCBA判责",
            "taskNodeName": "PCBAPanZe"
        },
        {
            "taskName": "方案确定并处理",
            "taskNodeName": "FangAnQuDingBingChuLi"
        }
    ],
    "connections": [
        {
            "from": "",
            "to": "WanShanKeSu",
            "depth": null
        },
        {
            "from": "",
            "to": "PCBPanZe",
            "depth": null
        },
        {
            "from": "",
            "to": "PCBAPanZe",
            "depth": null
        },
        {
            "from": "WanShanKeSu",
            "to": "PCBPanZe",
            "depth": null
        },
        {
            "from": "WanShanKeSu",
            "to": "PCBAPanZe",
            "depth": null
        },
        {
            "from": "PCBPanZe",
            "to": "FangAnQuDingBingChuLi",
            "depth": null
        },
        {
            "from": "PCBAPanZe",
            "to": "FangAnQuDingBingChuLi",
            "depth": null
        }
    ]
}

可以看出提供的节点有4个
完善客诉 PCB判责 PCBA判责 方案确定并处理
给出的连线有:

1.空 ——> 完善客诉
2.空 ——> PCB判责
3.空 ——> PCBA判责
4.完善客诉 ——> PCB判责
5.完善客诉 ——> PCBA判责
6.PCB判责 ——> 方案确定并处理
7.PCBA判责 ——> 方案确定并处理

如果不进行任何的处理,直接通过 渲染,则会出现下面的情况
在这里插入图片描述
上图乍一看,没啥问题,但是通过拖动【完善客诉】节点,就会发现问题了,就是【完善客诉】指向【PCBA判责】与【完善客诉】指向【PCB判责】的连线重合了,就会有【完善客诉】指向【PCB判责】再指向【PCBA判责】的错觉。这样的效果不是我们想要的。
在这里插入图片描述
想要实现【完善客诉】在【PCBA判责】与【PCB判责】节点中间,则需要指定排列的顺序。

比如上面的nodes节点更改顺序如下:

"nodes": [
		{
            "taskName": "PCB判责",
            "taskNodeName": "PCBPanZe"
        },
        {
            "taskName": "完善客诉",
            "taskNodeName": "WanShanKeSu"
        },
        {
            "taskName": "PCBA判责",
            "taskNodeName": "PCBAPanZe"
        },
        {
            "taskName": "方案确定并处理",
            "taskNodeName": "FangAnQuDingBingChuLi"
        }
    ],

这样就是我们想要的效果了
考虑到还有多层路径的情况,所以要通过递归来排列节点的顺序

我的思路

根据connections将空的节点填充为start开始节点,然后将没有任何from引申的节点,通通相当于指向end结束节点

1.开始 ——> 完善客诉
2.开始 ——> PCB判责
3.开始 ——> PCBA判责
4.完善客诉 ——> PCB判责
5.完善客诉 ——> PCBA判责
6.PCB判责 ——> 方案确定并处理
7.PCBA判责 ——> 方案确定并处理
8.方案确定并处理 ——> 结束

1.给from为空的节点赋值为start

let endArr = [];
let nodeObj = {};
let nodeArr = [];
this.taskRecords.connections.forEach((item) => {
  if (!item.from) {
    item.from = 'start';
  }
  endArr.push(item.from);
});

上面的endArr就是所有连线的开始节点,比如现在的endArr=['完善客诉','PCB判责','PCBA判责']

所有节点的集合:

this.taskRecords.nodes &&this.taskRecords.nodes.forEach((item) => {
  nodeArr.push(item.taskNodeName);
  nodeObj[item.taskNodeName] = [];
});

目前nodeArr=['完善客诉','PCB判责','PCBA判责','方案确定并处理']

this.taskRecords.connections &&this.taskRecords.connections.forEach((item) => {
  nodeObj[item.from].push(item.to);
});

经过上面的处理,nodeObj内容如下:

nodeObj = {
	'开始':['完善客诉','PCB判责','PCBA判责'],
	'完善客诉':['PCB判责','PCBA判责',],
	'PCB判责':['方案确定并处理'],
	'PCBA判责':['方案确定并处理'],
	'方案确定并处理':[],
	'结束':[]
}

我的思路是:遍历nodeObj,如果节点对应的数组长度大于1,则表示有好几个分支,则分支的排序尤为重要。比如【开始】节点,指向三个节点,我需要再次遍历,每一个子节点是否有好几个分支,如果有,则需要将该节点,位置安排在分支中间。

比如【完善客诉】的子节点【PCB判责】【PCBA判责】,则【完善客诉】位置应该是位于【PCB判责】和【PCBA判责】中间。

下面的代码可以实现这一操作:

for (let key in nodeObj) {
  if (nodeObj[key].length) {
    nodeObj[key].forEach((item) => {
      if (nodeObj[item].length > 1) {
        let arr = nodeObj[item].filter(
          (n) => nodeObj[key].indexOf(n) > -1
        );
        let len = Math.floor(arr.length / 2);
        let centerIndex = this.taskRecords.connections.findIndex(
          (no) => no.from == key && no.to == item
        );
        let currentObj = this.taskRecords.connections[centerIndex];
        this.taskRecords.connections.splice(centerIndex, 1);
        this.taskRecords.connections.splice(len, 0, currentObj);
      }
    });
  }
}

经过上面的操作:
endArr=['完善客诉','PCB判责','PCBA判责']
nodeArr=['完善客诉','PCB判责','PCBA判责','方案确定并处理']
所以存在于nodeArr中,但是不存在于endArr中的【方案确定并处理】应该有一条线是指向【结束】的

 nodeArr && nodeArr.forEach((item) => {
  if (endArr.indexOf(item) == -1) {
    this.taskRecords.connections.push({
      from: item,
      to: 'end',
    });
  }
});

重新组装nodes节点数据:

let nodes = [
  {
    text: '开始',
    id: 'start',
    color: this.info.taskList.length ? '#f90' : null,
  },
];
this.taskRecords.nodes &&
  this.taskRecords.nodes.forEach((item) => {
    nodes.push({
      id: item.taskNodeName,
      text: item.taskName,
      color: item.color,
      ...item,
    });
  });
nodes.push({
  text: '结束',
  id: 'end',
});

上面的步骤基本能实现想要的效果了。

//需要指定 节点参数和连接线的参数
this.graph_json_data = {
  rootId: 'start',
  nodes: nodes,
  lines: this.taskRecords.connections,
};
this.$refs.seeksRelationGraph.setJsonData(
  this.graph_json_data,
  (seeksRGGraph) => {}
);

我的效果图中,还有节点变亮,以及变亮节点中间的连线也是变亮的。这个就是给对应的节点和连线中添加color即可。

自定义插槽

下面要讲的是自定义插槽:
鼠标移入到节点上时,可以i显示其他的内容,此时需要使用插槽了。
在这里插入图片描述

<RelationGraph
          ref="seeksRelationGraph"
          style="
            height: 300px;
            width: 80%;
            margin: 0 auto;
            border: 1px solid #666;
          "
          :options="graphOptions"
        >
          <template #node="{ node }">
            <div class="my-node">
              <div class="my-node-text">{{ node.text }}</div>
              <div
                class="my-node-detail"
                v-if="node.data && node.data.creatorName"
              >
                <div @dblclick="handleCopy(node.data)">
                  {{ node.data.taskOwnerName || node.data.creatorName }}{{
                    (node.data.completedTime || node.data.creationTime) | moment
                  }}
                </div>
              </div>
            </div>
          </template>
        </RelationGraph>

上面中的graphOptions就是一些普通的配置项,具体的可以在https://relation-graph.com/#/options-tools链接中在线配置好后,拷贝到本地使用。

在这里插入图片描述
自定义插槽,一定要注意:node中识别内容只有id``text``data,其中的data可以是个对象,一开始我使用的是detail对象,则没有显示出来。改成data就可以了。

.my-node {
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  position: relative;
  .my-node-detail {
    display: none;
  }
  &:hover {
    .my-node-detail {
      display: block;
      position: absolute;
      left: 50%;
      transform: translateX(-50%);
      top: -50%;
      width: 250px;
      height: auto;
      min-height: 60px;
      line-height: 30px;
      background: #fff;
      padding: 10px 0;
      border: 3px solid #f90;
      color: #000;
      z-index: 1;
      font-size: 18px;
      user-select: all;
    }
  }
}

监听全屏/取消全屏——保证关系图在页面中间

我的思路就是,全屏/取消全屏时,重新渲染

监听页面的全屏操作

mounted() {
  // 添加全屏变化的事件监听器
  document.addEventListener('fullscreenchange', this.onFullScreenChange);
},

方法:

onFullScreenChange() {
  this.$refs.seeksRelationGraph.setJsonData(
    this.graph_json_data,
    (seeksRGGraph) => {}
  );
},

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

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

相关文章

上位机GUI 第三弹

&#x1f60a; &#x1f60a; &#x1f60a; 从协议层面讲&#xff0c;地质单元相当重要&#xff0c;调试模式,我只能义命令发送的索引码作为,每个设备的区分方式,调试的情况&#xff0c;不在设备上设置任何东西&#xff0c;开机访问地址和端口就能用 因为懒&#xff0c;直接将…

【你真的了解double和float吗】

&#x1f308;个人主页&#xff1a;努力学编程’ ⛅个人推荐&#xff1a;基于java提供的ArrayList实现的扑克牌游戏 |C贪吃蛇详解 ⚡学好数据结构&#xff0c;刷题刻不容缓&#xff1a;点击一起刷题 &#x1f319;心灵鸡汤&#xff1a;总有人要赢&#xff0c;为什么不能是我呢 …

MySQL数据恢复(适用于误删后马上发现)

首先解释一下标题&#xff0c;之所以适用于误删后马上发现是因为太久了之后时间和当时操作的数据表可能会记不清楚&#xff0c;不是因为日志丢失 1.首先确保自己的数据库开启了binlog&#xff08;我的是默认开启的我没有配置过&#xff09; 根据这篇博客查看自己的配置和自己…

Redis持久化的三种方式(RDB、AOF和混合)

Redis持久化的三种方式(RDB、AOF和混合) 目录 Redis持久化的三种方式(RDB、AOF和混合)介绍RDB示例1.配置文件2.触发 RDB 快照保存3.验证 AOF示例1.配置文件2.校验 混合型持久化存储配置文件 介绍 Redis数据主要存储与内存中&#xff0c;因此如果服务器意外重启、宕机、崩溃&am…

Linux Rsyslog+LogAnalyzer+MariaDB部署日志服务器

文章目录 Linux RsyslogLogAnalyzerMariaDB部署日志服务器1 环境准备1.1 服务器端安装LAMP环境1.2 服务启动并加入开机启动1.2.1 Apache1.2.2 MariaDB1.2.3 Php 2 Rsyslog服务端安装及配置2.1 安装Rsyslog及Rsyslog连接MySQL的模块2.2 导入rsyslog-mysql数据库文件2.3 查看刚导…

vector与list的简单介绍

1. 标准库中的vector类的介绍&#xff1a; vector是表示大小可以变化的数组的序列容器。 就像数组一样&#xff0c;vector对其元素使用连续的存储位置&#xff0c;这意味着也可以使用指向其元素的常规指针上的偏移量来访问其元素&#xff0c;并且与数组中的元素一样高效。但与数…

顶级5款有用的免费IntelliJ插件,提升你作为Java开发者的旅程

在本文中&#xff0c;我们将深入探讨IntelliJ IDEA插件——那些可以提升你生产力的神奇附加组件&#xff0c;并微调你的代码以达到卓越。我们将探索5款免费插件&#xff0c;旨在将你的开发水平提升到一个新的高度。 1. Test Data 使用Test Data插件进行上下文操作 作为开发者&a…

IT之旅启航:高考后IT专业预习全攻略

✨作者主页&#xff1a; Mr.Zwq✔️个人简介&#xff1a;一个正在努力学技术的Python领域创作者&#xff0c;擅长爬虫&#xff0c;逆向&#xff0c;全栈方向&#xff0c;专注基础和实战分享&#xff0c;欢迎咨询&#xff01; 您的点赞、关注、收藏、评论&#xff0c;是对我最大…

yum命令提示 错误:rpmdb: BDB0113 Thread/process 4153/139708200269632

一、报错信息 [rootDawn yum.repos.d]# yum clean all 错误&#xff1a;rpmdb: BDB0113 Thread/process 4153/139708200269632 failed: BDB1507 Thread died in Berkeley DB library 错误&#xff1a;db5 错误(-30973) 来自 dbenv->failchk&#xff1a;BDB0087 DB_RUNRECOVE…

【AI】DeepStream(14):图像分割deepstream-segmentation-test示例演示

【AI】AI学习目录汇总 1、简介 deepstream-segmentation-test示例演示了图像的语义分割。两个配置文件,分别加载U-Net和Res-UNet两种分割模型 unet_output_graph.uffunetres18_v4_pruned0.65_800_data.uffU-Net是一个在生物医学图像分割领域广泛应用的卷积神经网络(CNN),…

PHP花涧订购系统-计算机毕业设计源码00332

摘 要 近年来&#xff0c;电子商务的快速发展引起了行业和学术界的高度关注。花涧订购系统旨在为用户提供一个简单、高效、便捷的花卉购物体验&#xff0c;它不仅要求用户清晰地查看所需信息&#xff0c;而且还要求界面设计精美&#xff0c;使得功能与页面完美融合&#xff0c;…

Flume集群部署(手把手部署图文详细版)

前景概要&#xff1a; Kafka消息订阅系统在大数据业务中有着重要运用&#xff0c;尤其在实时业务中&#xff0c;kafka是必不可少的组件之一。 Flume是大数据组件中重要的数据采集工具&#xff0c;我们常利用Flume采集各种数据源的数据供其他组件分析使用。例如在实时业务中&…

实践Go的命令模式

简介 现在的软件系统往往是分层设计。在业务层执行一次请求时&#xff0c;我们很清楚请求的上下文&#xff0c;包括&#xff0c;请求是做什么的、参数有哪些、请求的接收者是谁、返回值是怎样的。相反&#xff0c;基础设施层并不需要完全清楚业务上下文&#xff0c;它只需知道…

【软件测试】之黑盒测试用例的设计

&#x1f3c0;&#x1f3c0;&#x1f3c0;来都来了&#xff0c;不妨点个关注&#xff01; &#x1f3a7;&#x1f3a7;&#x1f3a7;博客主页&#xff1a;欢迎各位大佬! 文章目录 1.测试用例的概念2.测试用例的好处3. 黑盒测试用例的设计3.1 黑盒测试的概念3.2 基于需求进行测…

2024年洗地机哪款最好用?全网最全洗地机选购指南

随着科技的不断进步&#xff0c;人们对生活的品质的追求也逐渐上升&#xff0c;智能家用洗地机也逐渐成为人们家务活的得力助手。随之而来的&#xff0c;洗地机品牌繁多&#xff0c;质量参差不齐&#xff0c;往往让我们无从下手&#xff0c;作为洗地机的重度用户&#xff0c;防…

220千伏变电站辅助设备智能监控平台 无人化与自动化升级改造工程

220千伏变电站特点 高电压等级&#xff1a;220千伏变电站的最大特点是其高压传输能力&#xff0c;能够将发电厂产生的电能高效地传输到较远的地区&#xff0c;满足大型城市及工业区域的用电需求。 输电能力大&#xff1a;220千伏变电站在输电能力上远大于普通的110千伏或更低…

C语言中的自定义类型: 结构体、联合体和枚举

1.结构体类型 结构体是一些值的集合,这些值称为成员变量.结构体的每个成员可以是不同类型的变量. 1.1结构体类型的声明 上述的variable-list可以有也可以没有&#xff0c;有的意思是直接在这就创建了结构体变量&#xff0c;这里创建的变量可以直接初始化&#xff0c;如下面一段…

时空预测+特征分解!高性能!EMD-Transformer和Transformer多变量交通流量时空预测对比

时空预测特征分解&#xff01;高性能&#xff01;EMD-Transformer和Transformer多变量交通流量时空预测对比 目录 时空预测特征分解&#xff01;高性能&#xff01;EMD-Transformer和Transformer多变量交通流量时空预测对比效果一览基本介绍程序设计参考资料 效果一览 基本介绍…

经典递归分析

在前面一篇中, 已经看过许多直观的递归的例子, 在这篇里, 将分析两个经典的递归问题, 阶乘与菲波那契数列数列, 在此过程中, 还将对比递归与循环(迭代)间的异同, 探讨递归与内存中的栈的关系, 以及递归的效率等问题. 如无特别说明, 示例使用的是 Java, IDE 则为 Eclipse. 阶乘(…

js学习--制作猜数字

猜数字制作 <!DOCTYPE html> <html><head><meta charset"utf-8"><title></title></head><body><script>function fun() {alert("1-100猜数字");let num Math.floor(Math.random() * 100) 1;for …