gojs一些实用的高级用法
程序员文章站
2022-06-24 18:06:30
目录1. 取消更新动画2. 导出图(含可视区外的部分)3. 禁用 ctrl 相关快捷键4. 画布滚动模式,无限滚动 or 局部滚动5. 展开收起多层嵌套的组6. 给图元素加动画7. 修改框选的样式1....
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一些实用的高级用法,希望对大家有所帮助。在此也非常感谢大家对网站的支持!
下一篇: react解决多级页面刷新时样式失效问题