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. 给图元素加动画
代码实现:
- 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一些实用的高级用法,希望对大家有所帮助。在此也非常感谢大家对w3xue网站的支持!