关于GoJs的总结及多功能实例

it2022-05-05  125

项目需要用到GoJs实现可视化,先说一下需求吧

1、实现可拖拽新建节点

2、点击节点可修改保存节点信息

3、可以手动新建节点之间的连线

4、点击连线可修改保存连线信息

5、节点鼠标右键菜单

网上的都是零零碎碎的,查了很多文档然后终于实现了上述的所有功能...

废话不多说,直接上代码:

<!DOCTYPE html> <html> <head>   <meta charset="UTF-8">   <title>dsDemo</title>   <meta name="description" content="A workflow diagram showing navigation between web pages, with an editable list of comments and to-dos." />   <meta name="viewport" content="width=device-width, initial-scale=1">   <!-- Copyright 1998-2019 by Northwoods Software Corporation. --> </head> <body> <div id="container">    <div style="width: 100%; display: flex; justify-content: space-between">       <div id="myPaletteDiv" style="width: 150px; margin-right: 2px; background-color: whitesmoke; border: solid 1px black"></div>       <div id="myDiagramDiv" style="flex-grow: 1; height: 600px; border: solid 1px black"></div>       <div id="nodeDetail"  style="width:200px; margin-right: 2px; background-color: whitesmoke; border: solid 1px black;padding:10px">         <p style="text-align: left">节点名称:<input type="text" v-model="selectNode.name"/></p>         <p style="text-align: left">节点描述:</p>         <textarea v-model="selectNode.description" style="width:98%;height:200px"></textarea>         <button id="SaveButton" @click="saveNode">保存</button>       </div>       <div id="linkDetail" style="width:200px; margin-right: 2px; background-color: whitesmoke; border: solid 1px black;padding:10px;display:none;">         <p style="text-align: left">连线名称:<input type="text" v-model="selectLink.name"/></p>         <p style="text-align: left">连线描述:</p>         <textarea v-model="selectLink.description" style="width:98%;height:200px"></textarea>         <button id="SaveButton" @click="saveLink">保存</button>       </div>     </div> </div> </body>  <script src="./go.js"></script>   <script src="./vue.min.js"></script>   <script id="code">    new Vue({         el:'#container',         data:{             selectNode:{                 name:'',                 description:''             },             selectLink:{                 name:'',                 description:''             }         },         methods:{             saveNode(){   //保存节点信息               this.myDiagram.model.updateTargetBindings(this.selectNode);             },             saveLink(){               this.myDiagram.model.updateTargetBindings(this.selectLink);             }         },         mounted(){             var mySelf = this;             const MAKE = go.GraphObject.make;             mySelf.myDiagram  = MAKE(go.Diagram, "myDiagramDiv",{                 "draggingTool.dragsLink": true,                 "undoManager.isEnabled": true ,// 支持 Ctrl-Z 和 Ctrl-Y 操作                 "toolManager.hoverDelay": 100,//tooltip提示显示延时                 "toolManager.toolTipDuration": 10000,//tooltip持续显示时间                 //isReadOnly:true,//只读                 // "grid.visible":true,//显示网格                 allowMove:true,//允许拖动                 // allowDragOut:true,                 allowDelete:false,                 allowCopy:false,                 allowClipboard:false,                 "toolManager.mouseWheelBehavior": go.ToolManager.WheelZoom,//有鼠标滚轮事件放大和缩小,而不是向上和向下滚动             });                          var that=this;             mySelf.myDiagram.addDiagramListener("ObjectSingleClicked",function (e) {                 if(e.subject.part.data.key == undefined){                     that.selectLink=e.subject.part.data;                     document.getElementById("nodeDetail").style.display="none";                     document.getElementById("linkDetail").style.display="block";                 }else{                     that.selectNode=e.subject.part.data;                     document.getElementById("nodeDetail").style.display="block";                     document.getElementById("linkDetail").style.display="none";                 }             });             mySelf.myDiagram.addModelChangedListener(function (evt) {               if (!evt.isTransactionFinished) return;               var txn = evt.object;               if (txn === null) return;               txn.changes.each(function(e) {                 if (e.modelChange !== "nodeDataArray") return;                 if (e.change === go.ChangedEvent.Insert) {                   that.selectNode=e.newValue;                 }               });             });             

            // 定义个简单的 Node 模板             mySelf.myDiagram.nodeTemplate =               MAKE(go.Node, "Auto",                 new go.Binding("location", "loc", go.Point.parse),                 MAKE(go.Shape, "RoundedRectangle",                   {                     fill: "#fff",stroke: '#289de9',strokeWidth:1                   }),                 MAKE(go.TextBlock, "new node",                   {                     margin: 8 ,                     font: "bold 14px Helvetica Neue",                   },                   new go.Binding("text", "name")));                                function makePort(name, align, spot, output, input) {                 var horizontal = align.equals(go.Spot.Top) || align.equals(go.Spot.Bottom);                 return MAKE(go.Shape,                   {                     fill: "transparent",  // changed to a color in the mouseEnter event handler                     strokeWidth: 0,  // no stroke                     width: horizontal ? NaN : 8,  // if not stretching horizontally, just 8 wide                     height: !horizontal ? NaN : 8,  // if not stretching vertically, just 8 tall                     alignment: align,  // align the port on the main Shape                     stretch: (horizontal ? go.GraphObject.Horizontal : go.GraphObject.Vertical),                     portId: name,  // declare this object to be a "port"                     fromSpot: spot,  // declare where links may connect at this port                     fromLinkable: output,  // declare whether the user may draw links from here                     toSpot: spot,  // declare where links may connect at this port                     toLinkable: input,  // declare whether the user may draw links to here                     cursor: "pointer",  // show a different cursor to indicate potential link point                     mouseEnter: function(e, port) {  // the PORT argument will be this Shape                       if (!e.diagram.isReadOnly) port.fill = "rgba(255,0,255,0.5)";                     },                     mouseLeave: function(e, port) {                       port.fill = "transparent";                     }                   });             }                      function textStyle() {                 return {                   font: "bold 11pt Helvetica, Arial, sans-serif",                   stroke: "whitesmoke"                 }             }             mySelf.myDiagram.nodeTemplateMap.add("",  // the default category                 MAKE(go.Node, "Auto",                  {                     contextMenu:     // define a context menu for each node                       MAKE("ContextMenu",  // that has one button                         MAKE("ContextMenuButton",                           MAKE(go.TextBlock, "Undo"),                             {                                 click: function(e, obj) {                                      console.log(1)                                 }                             },                       ))                     },                   MAKE(go.Panel, "Auto",                     MAKE(go.Shape, "RoundedRectangle",                        {                     fill: "#fff",stroke: '#289de9',strokeWidth:1                   }),                     MAKE(go.TextBlock, "new node",                       {                         margin: 8,                         font: "bold 14px Helvetica Neue",                       },                       new go.Binding("text","name").makeTwoWay())                   ),                   // four named ports, one on each side:                   makePort("T", go.Spot.Top, go.Spot.TopSide, false, true),                   makePort("L", go.Spot.Left, go.Spot.LeftSide, true, true),                   makePort("R", go.Spot.Right, go.Spot.RightSide, true, true),                   makePort("B", go.Spot.Bottom, go.Spot.BottomSide, true, false)                 ));                                                         //定义连线             var linkSelectionAdornmentTemplate =             MAKE(go.Adornment, "Link",               MAKE(go.Shape,                 // isPanelMain declares that this Shape shares the Link.geometry                 { isPanelMain: true, fill: null, stroke: "deepskyblue", strokeWidth: 0 })  // use selection object's strokeWidth             );             mySelf.myDiagram.linkTemplate =                 MAKE("Link",                   MAKE("Shape",                     { strokeWidth: 2,stroke: '#289de9'}),                   MAKE("Shape",                     { toArrow: "Standard", fill:"#289de9",stroke:null}),                   MAKE(go.TextBlock, "new link",                     {                       margin: 8,                       font: "bold 14px Helvetica Neue",                       segmentOffset: new go.Point(0, -10)                     },                     new go.Binding("text","name").makeTwoWay()),                 );

            var palette =               MAKE(go.Palette, "myPaletteDiv",  // create a new Palette in the HTML DIV element                 {                   // share the template map with the Palette                   nodeTemplateMap: mySelf.myDiagram.nodeTemplateMap,                   autoScale: go.Diagram.Uniform  // everything always fits in viewport                 });             palette.model.nodeDataArray = [               {}, // default node             ];

            let myModel = MAKE(go.GraphLinksModel);             myModel.nodeDataArray =               [                // {key:"1", name: "a",age:12,description:'我是a节点'},                 //{key:"2", parent:"1", name: "b",age:13 ,description:'我是b节点'},                 //{key:"3", parent:"1", name: "c",age:13 ,description:'我是b节点'},               ];             myModel.linkDataArray = [                //{from:"1",to:"2"},                //{from:"1",to:"3"},         //       {from:"1",to:"4"},         //       {from:"1",to:"5"},            ];             mySelf.myDiagram.model = myModel;         }     })   </script> </html>

 

关于GoJs的方法

(Ps:这里只写我觉得比较常用的,其他的请自行查阅其他文档,谢谢!)

1.更新数据

this.myDiagram.model.updateTargetBindings(this.selectNode);

参数是你当前编辑的数据,这里可以是节点信息也可以是连线信息

2.mySelf.myDiagram.addDiagramListener("ObjectSingleClicked",function (e) {                    console.log(e.subject.part.data);    });

监听点击事件,可以是点击节点也可以是连线,如果要区分,可以判断获取的数据里面是否有key属性,节点有key属性,连线有from,to属性。

if(e.subject.part.data.key == undefined){

.......

}

3.监听新拖拽到画布的节点

mySelf.myDiagram.addModelChangedListener(function (evt) {               if (!evt.isTransactionFinished) return;               var txn = evt.object;               if (txn === null) return;               txn.changes.each(function(e) {                 if (e.modelChange !== "nodeDataArray") return;                 if (e.change === go.ChangedEvent.Insert) {                   that.selectNode=e.newValue;                 }               });             });

4、通过key值去查找节点

mySelf.myDiagram.findNodeForKey(key).data

这里的key值是节点的key值


最新回复(0)