gojs 实用高级用法
Posted ESnail
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了gojs 实用高级用法相关的知识,希望对你有一定的参考价值。
大家,新年好!
历史文章:
本文介绍的是在使用 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 ));
希望对你有帮助,如果有帮助,请点个攒,谢谢!
以上是关于gojs 实用高级用法的主要内容,如果未能解决你的问题,请参考以下文章