RelationGraph实现工单进度图——js技能提升

news2024/12/23 2:29:47

直接上图:
在这里插入图片描述
从上图中可以看到整个工单的进度是从【开始】指向【PCB判责】+【完善客诉】+【PCBA列表】,同时【完善客诉】又可以同时指向【PCB判责】+【PCBA列表】,后续各自指向自己的进度。

直接上代码:

1.安装

1.1 Npm 方式

npm i relation-graph

1.2 Yarn方式

yarn add relation-graph

2.使用

2.1 html部分代码

 <RelationGraph
          v-if="visible"
          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.taskOwner }}){{
                    (node.data.completedTime || node.data.creationTime) | moment
                  }}
                </div>
              </div>
            </div>
          </template>
        </RelationGraph>

2.2 script部分代码

 <script>
 import RelationGraph from 'relation-graph';//引入插件
 export default {
   name: 'Demo',
   components: { RelationGraph },//注册插件
   data() {
     return {
     	//设置插件的参数
      graphOptions: {
        allowSwitchLineShape: true,
        allowSwitchJunctionPoint: true,
        // 这里可以参考"Graph 图谱"中的参数进行设置:http://relation-graph.com/#/docs/graph
        layouts: [
          {
            label: '中心',
            layoutName: 'tree', //布局方式(tree树状布局/center中心布局/force自动布局)
            // layoutClassName: 'seeks-layout-center', //当使用这个布局时,会将此样式添加到图谱上
            // centerOffset_y: 130, //根节点y坐标偏移量(针对项目配置单位为px)
            min_per_width: 150, //节点距离限制:节点之间横向距离最小值
            min_per_height: 180, //节点距离限制:节点之间纵向距离最小值
            from: 'left',
          },
        ],
        defaultLineMarker: {
          markerWidth: 40,
          markerHeight: 40,
          refX: 6,
          refY: 6,
          data: 'M2,2 L10,6 L2,10 L6,6 L2,2',
        },
        defaultNodeShape: 0, //默认的节点形状,0:圆形;1:矩形
        // defaultExpandHolderPosition: 'right', //节点展开关闭的按钮位置
        defaultLineShape: 1, //默认的线条样式(1:直线/2:样式2/3:样式3/4:折线/5:样式5/6:样式6)
        defaultJunctionPoint: 'border', //默认的连线与节点接触的方式(border:边缘/ltrb:上下左右/tb:上下/lr:左右)当布局为树状布局时应使用tb或者lr,这样才会好看
        // defaultNodeBorderWidth: 0.2, //节点边框粗细
        // defaultcolor: 'rgba(0, 186, 189, 1)', //默认的线条颜色
        // defaultNodeColor: 'rgba(0, 206, 209, 1)', //默认的节点背景颜色
        // defaultFocusRootNode: false, //默认为根节点添加一个被选中的样式
        // moveToCenterWhenResize: true, //当图谱的大小发生变化时,是否重新让图谱的内容看起来居中
        // 这里可以参考"Graph 图谱"中的参数进行设置
        moveToCenterWhenRefresh: false,
        // graphOffset_x: -500,
        // graphOffset_y: -100,
      },
     }
   },
 }
 </script>

接口返回的数据结构是这样的:
在这里插入图片描述
上图中的connections是线的关系,nodes是节点。

需要对上面的数据结构进行处理后,才能实现上面的效果:

this.taskRecords = {
    "nodes": [
        {
            "taskName": "完善客诉",
            "taskNodeName": "WanShanKeSu"
        },
        {
            "taskName": "PCB判责",
            "taskNodeName": "PCBPanZe"
        },
        {
            "taskName": "PCBA判责",
            "taskNodeName": "PCBAPanZe"
        },
        {
            "taskName": "客服处理",
            "taskNodeName": "KeFuChuLi"
        },
        {
            "taskName": "OA审批",
            "taskNodeName": "OAShenPi"
        }
    ],
    "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": "KeFuChuLi",
            "depth": null
        },
        {
            "from": "PCBAPanZe",
            "to": "KeFuChuLi",
            "depth": null
        },
        {
            "from": "KeFuChuLi",
            "to": "OAShenPi",
            "depth": null
        },
        {
            "from": "OAShenPi",
            "to": "KeFuChuLi",
            "depth": null
        }
    ]
}
showSeeksGraph() {
      let nodeArr = [];
      let endArr = [];
      let nodeObj = {
        start: [],
        end: [],
      };
      this.taskRecords.connections.forEach((item) => {
        if (!item.from) {
          item.from = 'start';
        }
        endArr.push(item.from);
      });
      this.taskRecords.nodes &&
        this.taskRecords.nodes.forEach((item) => {
          nodeArr.push(item.taskNodeName);
          nodeObj[item.taskNodeName] = [];
        });

      this.taskRecords.connections &&
        this.taskRecords.connections.forEach((item) => {
          nodeObj[item.from].push(item.to);
        });
      console.log(222, this.taskRecords.connections);
      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);
            }
          });
        }
      }
      nodeArr &&
        nodeArr.forEach((item) => {
          if (endArr.indexOf(item) == -1) {
            this.taskRecords.connections.push({
              from: item,
              to: 'end',
            });
          }
        });

      let nodes = [
        {
          text: '开始',
          id: 'start',
        },
      ];
      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',
      });
      console.log(
        'this.taskRecords.connections',
        nodes,
        this.taskRecords.connections
      );
      //需要指定 节点参数和连接线的参数
      this.graph_json_data = {
        rootId: 'start',
        nodes: nodes,
        lines: this.taskRecords.connections,
      };
      this.$refs.seeksRelationGraph.setJsonData(
        this.graph_json_data,
        (seeksRGGraph) => {}
      );
    },

上面的代码就可以实现了。如果要i

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

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

相关文章

“探索端智能,加速大模型应用” 火山引擎边缘智能x扣子技术沙龙圆满落幕!

9月21日&#xff0c;火山引擎边缘智能扣子技术沙龙在上海圆满落地&#xff0c;沙龙以“探索端智能&#xff0c;加速大模型应用”为主题&#xff0c;边缘智能、扣子、地瓜机器人以及上海交通大学等多位重磅嘉宾出席&#xff0c;从多维视角探讨 AI、 AIoT、端侧大模型等技术与发展…

嵌入式数据结构中线性表的具体实现

大家好,今天主要给大家分享一下,如何使用数据结构中的线性表以及具体的实现。 第一:线性表的定义和表示方法 线性表的定义 – 线性表就是零个或多个相同数据元素的有限序列。 • 线性表的表示方法 – 线性表记为: L=(a0,∙∙∙∙∙∙∙∙ai-1aiai+1 ∙∙∙∙∙∙an-1) •…

HTTP的工作原理

HTTP&#xff08;Hypertext Transfer Protocol&#xff09;是一种用于在计算机网络上传输超文本数据的应用层协议。它是构成万维网的基础之一&#xff0c;被广泛用于万维网上的数据通信。&#xff08;超文本(Hypertext)是用超链接的方法&#xff0c;将各种不同空间的文字信息组…

数据交换的金钟罩:合理利用安全数据交换系统,确保信息安全

政府单位为了保护网络不受外部威胁和内部误操作的影响&#xff0c;通常会进行网络隔离&#xff0c;隔离成内网和外网。安全数据交换系统是专门设计用于在不同的网络环境&#xff08;如内部不同网络&#xff0c;内部网络和外部网络&#xff09;之间安全传输数据的解决方案。 使用…

Redis 其他类型 渐进式遍历

我们之前已经学过了Redis最常用的五个类型了&#xff0c;然而Redis还有一些在特定场景下比较好用的类型 Redis最关键的五个数据类型&#xff1a; 上面的类型是非常常用&#xff0c;很重要的类型。 除此之外的其他类型不常用&#xff0c;只是在特定的场景能够发挥用处&#…

澳鹏干货 | 大语言模型的上下文窗口 (Context Windows)

大语言模型&#xff08;LLMs&#xff09;极大地提升了人工智能在理解和生成文本方面的能力。其中一个影响其效用的重要方面是“上下文窗口”&#xff08;Context Windows&#xff09;—— 这个概念直接影响着模型接收和生成语言的有效性。 本期澳鹏干货将深入探讨上下文窗口对…

微软确认Word离奇Bug 命名不当会导致文件被删

微软近日确认Word应用中存在一个Bug&#xff0c;该漏洞可能导致用户在特定情况下错误地删除文件。该问题主要出现在文件命名过程中&#xff0c;如果用户在保存Word文件时采用特定的命名方式&#xff0c;文件可能会被移动到回收站。 根据微软支持中心的消息&#xff0c;如果用户…

MVS海康工业相机达不到标称最大帧率

文章目录 一、相机参数设置1、取消相机帧率限制2、修改相机图像格式3、调整相机曝光时间4、检查相机数据包大小&#xff08;网口相机特有参数&#xff09;5、 恢复相机默认参数6、 相机 ADC 输出位深调整 二、系统环境设置1、 网口相机设置2、 USB 相机设置 一、相机参数设置 …

java对接GPT 快速入门

统一对接GPT服务的Java说明 当前&#xff0c;OpenAI等GPT服务厂商主要提供HTTP接口&#xff0c;这使得大部分Java开发者在接入GPT时缺乏标准化的方法。 为解决这一问题&#xff0c;Spring团队推出了Spring AI &#xff0c;它提供了统一且标准化的接口来对接不同的AI服务提供商…

毕设分享 大数据用户画像分析系统(源码分享)

文章目录 0 前言2 用户画像分析概述2.1 用户画像构建的相关技术2.2 标签体系2.3 标签优先级 3 实站 - 百货商场用户画像描述与价值分析3.1 数据格式3.2 数据预处理3.3 会员年龄构成3.4 订单占比 消费画像3.5 季度偏好画像3.6 会员用户画像与特征3.6.1 构建会员用户业务特征标签…

Linux查看下nginx及使用的配置文件

1、查到nginx进程 ps -aef | grep nginx2、通过进行pid查到nginx路径 pwdx <pid>3、根据路径得到配置文件 path***/nginx -t如下&#xff1a;

Unity网络开发基础 —— 实践小项目

概述 接Unity网络开发基础 导入基础知识中的代码 需求分析 手动写Handler类 手动书写消息池 using GamePlayer; using System; using System.Collections; using System.Collections.Generic; using UnityEngine;/// <summary> /// 消息池中 主要是用于 注册 ID和消息类…

(五)Proteus仿真STM32单片机串口数据流收发

&#xff08;五&#xff09;Protues仿真STM32单片机串口数据流收发 – ARMFUN 1&#xff0c;打开STM32CubeMX&#xff0c;找到USART1,配置模式Asynchronous&#xff0c;此时PA9、PA10自动变成串口模式 串口默认参数:115200bps 8bit None 1stop 2&#xff0c;NVIC Settings使能…

Linux-Docker阿里云镜像仓库失效

写在前面&#xff0c;这个是我很早之前在VmWare安装的Linux7,通过yum 安装的docker&#xff0c;但是今天怎么都无法pull镜像&#xff0c;报错如下。 Error response from daemon: Get "https://registry-1.docker.io/v2/": net/http: request canceled while waitin…

在IDEA里用XDebug调试PHP,断点....

做程序开发,调试必不可少,这里最近用到了PHP,顺便写个关于PHP的调试安装使用: 1、首先是PHP先安装xdebug扩展(还有zend的),这个我的工具是IDEA,所以安装方法也相对简单,如果你是用VSCode等应该也是一样,如下图,找到这个PHP->DEBUG 2、直接点上面的Install XDebug 就可以帮你…

Unity网络开发 - C#开源网络通信库PESocket的使用

概述 在现代多人在线游戏中&#xff0c;稳定且高效的网络通信是确保游戏体验的关键。本文将探讨如何利用C#开源网络通信库PESocket来构建一个简单的Unity客户端与.NET控制台服务器之间的实时消息传递系统。通过本例&#xff0c;读者不仅能够了解PESocket的基本用法&#xff0c…

Windows11系统下Sentinel环境搭建教程

目录 前言Sentinel简介Sentinel下载安装Sentinel配置与启动总结 前言 本文为博主在项目环境搭建时记录的Sentinel安装流程&#xff0c;希望对大家能够有所帮助&#xff0c;不足之处欢迎批评指正&#x1f91d;&#x1f91d;&#x1f91d; Sentinel简介 github主页地址 &#x…

004、合并两个有序数组

0、题目描述 合并两个有序数组 1、法1 数组nums1有m个元素&#xff0c; 直接在下标为m的位置处追加nums2的元素。然后再qsort整体排序。 —— —— qsort函数&#xff0c;&#xff08;数组首元素地址&#xff0c;排序的个数&#xff0c;排序元素大小&#xff0c; 比较函数&…

Vue】Vue扫盲(四)组件化思想与简单应用

【Vue】Vue扫盲&#xff08;一&#xff09;事件标签、事件修饰符&#xff1a;click.prevent click.stop click.stop.prevent、按键修饰符、及常用指令 【Vue】Vue扫盲&#xff08;二&#xff09;指令&#xff1a;v-for 、v-if、v-else-if、v-else、v-show 【Vue】Vue扫盲&…

Ruby脚本:自动化网页图像下载的实践案例

随着互联网的快速发展&#xff0c;网页上的内容变得越来越丰富&#xff0c;尤其是图像资源。对于需要大量图像资源的设计师、内容创作者或数据分析师来说&#xff0c;手动下载这些图片不仅耗时耗力&#xff0c;而且效率低下。因此&#xff0c;自动化网页图像下载成为了一个迫切…