gojs 实用高级用法

2023-11-19

本文介绍的是在使用 gojs 制作图的过程中,你可能会碰到的问题的一些解决方案。

gojs 是一个非常强大的可视化关系的js库。

1. 取消更新动画

问题:更新数据的时候,会触发渲染,有渲染动画,用户体验不好。

方案:初始数据绘制,有动画;更新数据绘制,无动画。

代码实现:

// 后面所用到的 diagram 都是 gojs 创建的实例
// diagram_container 为图容器dom id
diagram = $(go.Diagram, 'diagram_container') 

方案一:

function updateData (nodeArr = [], linkArr = [], hasAnimation = true ) {
  if (hasAnimation) {
    diagram.model = new go.GraphLinksModel(nodeArr, linkArr);
  } else {
    diagram.model.nodeDataArray = nodeArr
    diagram.model.linkDataArray = linkArr
  }
}

// 初始化实例后处理,只用一次
diagram.animationManager.canStart = function(reason) {
  if (reason === 'Model') return false
  return true
}

方案二:

// 绑定数据至 diagram,绘制图
function updateData (nodeArr = [], linkArr = [], hasAnimation = true ) {
  if (hasAnimation) {
    diagram.model = new go.GraphLinksModel(nodeArr, linkArr);
  } else {
    diagram.model.nodeDataArray = nodeArr
    diagram.model.linkDataArray = linkArr
    diagram.animationManager.stopAnimation()
  }
}

方案三:

// 绑定数据至 diagram,绘制图
function updateData (nodeArr = [], linkArr = [], hasAnimation = true) {
  diagram.model = new go.GraphLinksModel(nodeArr, linkArr);
  if (diagram.animationManager) {
    // Default 有动画,None 没有动画
    diagram.animationManager.initialAnimationStyle = hasAnimation ? go.AnimationManager.Default : go.AnimationManager.None;
  }
}

2. 导出图(含可视区外的部分)

问题:导出图,利用原生 canvas 相关 api 实现的导出图片,只包含可视区内的

解决:利用 gojs 提供的 api 处理

背后原理:利用数据重新绘制一份图,所有数据节点都在的图可视区内,然后利用原生 canvas 相关 api 实现导出图片

代码实现:

function downloadImg = ({
  imgName = 'dag',
  bgColor = 'white',
  imgType = 'image/png'
}= {}) {
  diagram.makeImageData({
    scale: 2,
    padding: new go.Margin(50, 70),
    maxSize: new go.Size(Infinity, Infinity),
    background: bgColor,
    type: imgType,
    returnType: 'blob',
    callback: (blob: any) => {
      const url = window.URL.createObjectURL(blob)
      const fileName = imgName + '.png'
      const aEl = document.createElement('a')
      aEl.style.display = 'none'
      aEl.href = url
      aEl.download = fileName

      // IE 11
      if (window.navigator.msSaveBlob !== undefined) {
        window.navigator.msSaveBlob(blob, fileName)
        return
      }

      document.body.appendChild(aEl)
      requestAnimationFrame(function() {
        aEl.click()
        window.URL.revokeObjectURL(url)
        document.body.removeChild(aEl)
      })
    }
  })
}

3. 禁用 ctrl 相关快捷键

// 禁用 ctl 相关操作
diagram.commandHandler.doKeyDown = function() {
  const e = diagram.lastInput
  const control = e.control || e.meta
  const key = e.key

  // 取消 Ctrl+A/Z/Y/G  A-全选、Z-撤销、Y-重做、G-分组
  if (control && ['A', 'Z', 'Y', 'G'].includes(key)) return
  // 取消 Del/Backspace 删除键
  if (key === 'Del' || key === 'Backspace') return

  go.CommandHandler.prototype.doKeyDown.call(this)
}

4. 画布滚动模式,无限滚动 or 局部滚动

问题:mac 上 触摸键能左滑右滑控制浏览器页面前进后退,很容易触发

方案:开启无限滚动,避免用户不小心触发了浏览器的前进后退

代码实现:

function infiniteScroll = (infiniteScroll) {
  this.diagram.scrollMode = infiniteScroll ? go.Diagram.InfiniteScroll : go.Diagram.DocumentScroll
}

5. 展开收起多层嵌套的组

问题:组多层嵌套,全部展开后,点击单个组收起第一次无效,第二次点击才生效

代码实现:

方式一:nodeArr 没有绑定 展开收起 属性

// groupIds 为所有 group 的ids,从外到内。 一开始遍历组装数据的时候就收集好
// groupIdsReverse 为所有 group 的ids,从内到外
// 全部展开,从外到内
// 全部收起,从内到外
function setExpandCollapse (isExpand, groupIds, groupIdsReverse) {
  // 展开和折叠需要从两个方向处理,再次展开折叠交互才正常,否则第一次点无效,需要点第二次材有限
  let arr = isExpand ? groupIds : groupIdsReverse;
  let group;

  arr.forEach(id => {
    group = diagram.findNodeForKey(id);
    group.isSubGraphExpanded = isExpand;
  })
},

方式二:nodeArr 绑定 展开收起 属性 isExpanded

function setExpandCollapse (isExpand) {
  const { nodeDataArray, linkDataArray } = diagram.model
  const newNodeArr = nodeDataArray.map(v => {
    if (v.isGroup) {
      return {...v, isExpanded: isExpand}
    }
    return v
  })

  // 上面的方法
  updateData(newNodeArr, linkArr, false)
}

6. 给图元素加动画

  • 虚线动画
  • icon loading 旋转动画

代码实现:

function loop = () {
  const animationTimer = setTimeout(() => {
    clearTimeout(animationTimer)
    const oldskips = diagram.skipsUndoManager;
    diagram.skipsUndoManager = true;

    // 虚线动画
    diagram.links.each((link: any) => {
      const dashedLinkShape = link.findObject("dashedLink");
      if (dashedLinkShape) {
        const off = dashedLinkShape.strokeDashOffset - 3;
        // 设置(移动)笔划划动画
        dashedLinkShape.strokeDashOffset = (off <= 0) ? 60 : off;
      }
    });

    // loading 旋转
    diagram.nodes.each((node: any) => {
      const loadingShape = node.findObject("loading");
      if (loadingShape) {
        const angle = loadingShape.angle + 20;
        // 设置(移动)笔划划动画
        loadingShape.angle = (angle == 0) ? 360 : angle;
      }
    });

    diagram.skipsUndoManager = oldskips;
    loop();
  }, 180);
}
loop()

7. 修改框选的样式

问题:框选样式:默认是红色的,和自定义的图颜色不匹配

diagram.toolManager.dragSelectingTool.box = $(go.Part,
  { layerName: "Tool", selectable: false },
  $(go.Shape,
    { name: "SHAPE", fill: 'rgba(104, 129, 255, 0.2)', stroke: 'rgba(104, 129, 255, 0.5)', strokeWidth: 2 }));

希望对你有帮助,如果有帮助,请点个赞,谢谢!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

gojs 实用高级用法 的相关文章

  • 【编程题】——求链表的中间节点

    题目 求链表的中间结点 如果链表中结点总数为奇数 返回中间结点 如果结点总数是偶数 返回中间两个结点的任意一个 思路 定义两个指针 一个指针一次走一步 另一个指针一次走两步 当走得快的指针到达链表末尾的时候 走得慢的指针刚好达到链表的中间节
  • 文件管理系统(操作系统)——9张思维导图

    文件管理系统 1 文件管理 1 1 一个文件的逻辑结构 比如一个文本txt文件 又或者Excel文件 在我们用户看来 它是长什么样的 这个就是逻辑结构 几个概念 逻辑结构 就是指在用户看来 单个文件内部的数据应该是如何组织起来的 物理结构
  • 黑马SpringBoot笔记

    基础篇 把Tomcat服务器更换成Jetty服务器 排除Tomcat依赖更换为Jetty
  • 【Java面试题汇总】Redis篇(2023版)

    导航 黑马Java笔记 踩坑汇总 JavaSE JavaWeb SSM SpringBoot 瑞吉外卖 SpringCloud 黑马旅游 谷粒商城 学成在线 牛客面试题 目录 1 说说你对Redis的了解 2 说说Redis的单线程架构 3
  • 7.java类中的方法

    1 类中的方法 1 实例方法 格式 访问限制修饰符 方法的返回值数据类型 方法名称 参数列表 方法体 解释 访问限制修饰符 public 缺省的 方法的返回值数据类型 就是方法的执行结果类型 有返回值时 方法的返回值数据类型一定是方法执行结
  • FPGA硬件工程师Verilog面试题(基础篇二)

    作者简介 大家好我是 嵌入式基地 是一名嵌入式工程师 希望一起努力 一起进步 个人主页 嵌入式基地 系列专栏 FPGA Verilog 习题专栏 微信公众号 嵌入式基地 FPGA硬件工程师Verilog面试题 二 习题一 多功能数据处理器
  • 大数据hive篇--常用操作

    文章目录 hive常用操作 一 建表 1 自定义分隔符 2 JSON分隔符 3 正则分隔符 将查询的结果导入新表 表的类别 外部表 内部表 分区表 导入数据 使用分区表 声明存储格式 二 常用函数 开窗函数 开窗函数常用的函数 炸裂函数 列
  • Android RecyclerView最全使用详解

    本文目录 RecyclerView概述 RecyclerView使用 基础篇 第一步 添加RecyclerView 第二步 添加布局文件 第三步 添加逻辑代码 运行效果 RecyclerView使用 进阶篇 布局管理器 线性布局管理器 网格
  • Go语言学习4-数组类型

    数组类型 引言 1 数组 1 1 类型表示法 1 2 值表示法 1 3 属性和基本操作 总结 引言 上篇我们了解 Go语言的基本数据类型 现在开始介绍数组类型 主要如下 1 数组 在Go语言中 数组被称为Array 就是一个由若干相同类型的
  • 2020-10-24 大数据面试问题

    上周面试数据开发职位主要从公司的视角讲一下记录下面试流水 1 三面技术一轮hr 面到了cto 整体来看是这一周技术含量最高信息量最大的一个 1到4轮过了4个小时 技术上的问题主要问的对数据分层的理解 1 一面自我介绍 目前团队的规模多大 2
  • IDEA 启动失败(因为修改了vmoptions后无法启动)

    本人亲历 找过好多方法 才解决的 包括但不限于 找 vmoption文件的时候 说是在C盘 死活找不到 不过已经解决了 也成功了 还成功添加了破解码 后面出文 想添加破解码 要修改vmpotion 结果直接启动不了了 然后重启IDEA的时候
  • Gstreamer的编译以及配置要点[初次总结]

    前言 Gstreamer是一个与ffmpeg齐名的音视频处理库 不过国内一般用的是ffmpeg 其实 gstreamer也蛮好用的 这篇文章主要说明一下如何编译gstreamer以及安装配置插件 起码不会报 插件not found的错误吧
  • 安装mysql8.0以上版本,java配置需要注意

    1 驱动使用8 0以上版本 https mvnrepository com artifact mysql mysql connector java 8 0 27

随机推荐

  • Redis连接池参数配置

    转载自 http www cnblogs com softidea p 5759457 html redis之如何配置jedisPool参数 JedisPool的配置参数很大程度上依赖于实际应用需求 软硬件能力 JedisPool的配置参数
  • 准确率(Accuracy)、精确率(Precision)、召回率(Recall)、F值(F-Measure)、AUC、ROC的理解

    一 准确率 精确率 召回率和 F 值 是选出目标的重要评价指标 不妨看看这些指标的定义先 1 若一个实例是正类 但是被预测成为正类 即为真正类 True Postive TP 2 若一个实例是负类 但是被预测成为负类 即为真负类 True
  • Win11微软账号登录不上?Win11登录Microsoft账户出错的解决方法

    Win11微软账号登录不上 近期有部分Win11用户反映在登录微软账号会出现一直转圈 无法登录的情况 这样导致部分功能都不能正常使用了 为此十分令人头疼 那么对于这一情况 有没有什么方法可以有效的解决呢 下面小编教给大家操作方法 大家可以去
  • 谷歌I/O大会重磅发布:Bard编码能力优化后仍不支持中文,开发者选择CodeGeeX更佳

    谷歌I O大会今天凌晨发布 打出系列AI组合拳 除了发布升级版语言模型PaLM2之外 Bard能力也要起飞 凭借改进的数学 逻辑和推理技能 Bard 现在可以帮助生成 解释和调试 20 多种编程语言的代码 开发者们需要输入prompt 来得
  • 总结Altium PCB中更改线宽的技巧

    总结Altium PCB中更改线宽的技巧 1 设置altium designer的默认pcb线宽 在布线前直接在设计规则中设置 Design Rules Routing Width 修改这个里面的Preferred Width即可 还可以进
  • [C++11 std::thread] 使用C++11 编写 Linux 多线程程序

    From http www ibm com developerworks cn linux 1412 zhupx thread index html 本文讲述了如何使用 C 11 编写 Linux 下的多线程程序 如何使用锁 以及相关的注意
  • 多线程快速处理List集合(结合线程池的使用)

    有一个大List集合 遍历进行一些耗时操作 不能达到性能要求 查询日志 单个任务虽然有不少数据库和第三方API请求 比较耗时 但返回效率尚可 所以优先采用多线程方式进行处理并行请求数据库和第三方API 因为处理完还要对list所属的数据进行
  • 51单片机入学第三课——数码管静态与动态显示

    文章目录 数码管的应用 数码管显示的原理 静态与动态显示 静态显示 动态显示 锁存器工作原理 实践编程 静态显示 动态显示 总结 补充 数码管的应用 来自百度 数码管 也称作辉光管 是一种可以显示数字和其他信息的电子设备 玻璃管中包括一个金
  • elementui table 动态表头表格(根据后台返回显示动态数据)

    让后台返回的数据格式 tabledData tableNmae 姓名 tableCode name tableNmae 性别 tableCode Gender tableNmae a tableCode a tableNmae b tabl
  • 炒期权的资金门槛是多少 ?

    期权是一种合约 买方向卖方支付一定费用后有权利在特定的时间 以特定的价格买入或卖出一定数量的特定资产 卖方需履行相应义务 期权开户支持线上和零门槛开头 下文介绍炒期权的资金门槛是多少 本文来自 期权酱 一 期权一般投入多少钱 其实在期权市场
  • 分享20个高匿代理IP

    49 88 114 117 22001 60 169 62 244 25008 106 116 64 162 22024 42 177 70 145 22019 180 108 97 22 22014 27 157 129 62 29003
  • C#中String类型转换为Vector3类型

    俗话说的好 基础不牢地动山摇 本人今天做服务器和客户端通信 需要将服务器转发的String类型转换为Vector类型 做了半天才做好 我在想这不是最基础的内容吗 当时学基础这么学的 哈哈哈 接下来实现从String到Vector3类型的转换
  • nginx日志报错:No such file or directory

    2023 04 01 17 15 02 error 2832 2832 6 open usr local openresty nginx html api item 1001 failed 2 No such file or directo
  • [转]如何解决下载的CHM文件无法显…

    如何解决下载的CHM文件无法显示网页问题 问题症状 打开CHM文件 左边目录齐全 可右边边框里却是无法显示网页 解决方法 方法一 修改注册表 1 新建一个文本文件 2 添加如下内容 REGEDIT4 HKEY LOCAL MACHINE S
  • 使用jupyter notebook连接服务器中docker container

    服务器中 新起容器 docker run it p 服务器端口 8888 name 容器名 v 服务器地址 容器地址 如果用gpu这里加上 device IMAGE REPOSITORY IMAGE TAG 查看本地镜像 docker im
  • 51单片机——舵机的原理及应用

    一 舵机介绍 舵机是一种位置伺服的驱动器 适用那些需要角度不断变换并能够保持的控制系统 如果我们想要完成遥控转头风扇这么一个项目 那么转头的工作由舵机来实现就最好不过了 二 舵机的工作原理 标准的舵机有三条引线 分别是电源线Vcc 地线GN
  • leetcode算法面试题:对称二叉树、对链表进行插入排序、多数元素

    对称二叉树问题 给定一个二叉树 检查它是否是镜像对称的 例如 二叉树 1 2 2 3 4 4 3 是对称的 1 2 2 3 4 4 3 但是下面这个 1 2 2 null 3 null 3 则不是镜像对称的 1 2 2 3 3 参考答案 c
  • 视频质量诊断&&视频质量分析

    一 随着平安城市 大安防的发展 监控摄像机数量的不断增加 给监控系统的维护工作带来了新的挑战 如何及时了解前端视频设备的运行情况 发现故障并检测恶意遮挡与破坏的不法行为已成为视频监控系统运行的首要迫切问题 对于成千上万个监控摄像机 依靠人工
  • MySQL根据某一个或者多个字段查找重复数据,并且保留某字段值最大的记录

    问题场景 当系统没有处理好并发操作的情况下 操作人员同时操作一张表的情况下 数据库有可能被插入相同记录 这些会带来隐藏的bug 解决思路一 解决并发操作的冲突 解决思路二 对数据库 MySQL 某张表去重 首先确定你的业务是否允许重复 不允
  • gojs 实用高级用法

    本文介绍的是在使用 gojs 制作图的过程中 你可能会碰到的问题的一些解决方案 gojs 是一个非常强大的可视化关系的js库 1 取消更新动画 问题 更新数据的时候 会触发渲染 有渲染动画 用户体验不好 方案 初始数据绘制 有动画 更新数据