相关文章推荐
叛逆的青蛙  ·  Defining your ...·  9 月前    · 
机灵的木耳  ·  探究 | ...·  1 年前    · 

记录一下项目中的需求完成流程图示例,使用的是使用vue-cli搭建的项目,配合gojs来实现的,附上截图一份:(gojs版本如果更迭可能会影响使用,如需达到下图效果,可以联系我留言或者邮箱:lihai987789@qq,com)

保存之后是JSON格式的数据 , 便于保存:

由于没有中文文档,所以也摸索了一天的时间,终于是完成了需求:

第一步:引入GOJS(官方文档上下载的有水印,我用的是破解版本的,需要的可以找我拿一下QQ:1013218132)

话不多说,直接上代码:      gojs的引入和echarts有点类似,也是画布完成的,都是根据ID值获取页面节点去渲染标签的

  1 <template>
  2     <div class="modelingBox">
  3         <div class="modelingHead">
  4             <el-button id="SaveButton" @click="save">保存</el-button>
  5             <el-button @click="load">清空</el-button>
  6             <textarea id="mySavedModel" style="width:100%;height:300px;">{ "class": "go.GraphLinksModel",
  7                 "linkFromPortIdProperty": "fromPort",
  8                 "linkToPortIdProperty": "toPort",
  9                 "nodeDataArray": [
 11                ],
 12                 "linkDataArray": [
 13                ]}
 14                 </textarea>
 15             <div class="msg_">
 16                 <p>流程</p>
 17                 <el-select v-model="valueOptions" @change="selectChange" filterable placeholder="请选择">
 18                     <el-option v-for="item in options"
 19                                :key="item.value"
 20                                :label="item.label"
 21                                :value="item.value"></el-option>
 22                 </el-select>
 23             </div>
 24         </div>    
 25         <div id="sample">
 26             <div style="width: 100%;height:100%; display: flex; justify-content: space-between">
 27                 <div id="PaletteDiv" style="width: 200px; margin-right: 2px; background-color: #fafafa;"></div>
 28                 <div id="DiagramDiv" style="flex-grow: 1; height: 100%; background-color: #fafafa;"></div>
 29             </div>
 31         </div>
 33         <el-dialog title="开始节点" :visible.sync="StartShow" width="30%" :before-close="handleClose">
 34             <span>这是一段信息</span>
 35             <span slot="footer" class="dialog-footer">
 36                 <el-button @click="StartShow = false">取 消</el-button>
 37                 <el-button type="primary" @click="StartShow = false">确 定</el-button>
 38             </span>
 39         </el-dialog>
 40         <el-dialog title="审批节点" :visible.sync="ActivityShow" width="30%" :before-close="handleClose">
 41             <span>这是一段信息</span>
 42             <span slot="footer" class="dialog-footer">
 43                 <el-button @click="ActivityShow = false">取 消</el-button>
 44                 <el-button type="primary" @click="ActivityShow = false">确 定</el-button>
 45             </span>
 46         </el-dialog>
 47     </div>
 48 </template>
 49 <script>
 50     // import { init } from "./test";
 51     import go from "./gojs/go-cracked";
 52     export default {
 53         data() {
 54             return {
 55                 StartShow: false,
 56                 ActivityShow: false,
 57                 options: [
 58                     {
 59                         value: '0',
 60                         label:'选项一'
 61                     },
 62                     {
 63                         value: '1',
 64                         label: '选项二'
 65                     }
 66                 ],
 67                 valueOptions:''
 68             };
 69         },
 70         methods: {
 71             selectChange() {
 72                 console.log(this.valueOptions,'select')
 73             },
 74             handleClose() {
 75                 this.StartShow = false
 76                 this.ActivityShow = false
 77             },
 78             nodeDoubleClick(e, node) {
 79                 console.log(e, node.part.data.category);
 80                 if (node.part.data.category == "Start") {
 81                     this.StartShow = true;
 82                 } else if (node.part.data.category == "Activity") {
 83                     this.ActivityShow = true;
 84                 }
 85             },
 86             nodeStyle() {
 87                 var this_ = this;
 88                 return [
 89                     {
 90                         locationSpot: go.Spot.Center,
 91                         isShadowed: false,
 92                         doubleClick: function (e, node) {
 93                             if (!e.diagram) return;
 94                             if (!e.diagram.allowLink) return;
 95                             var nCategory = node.part.data.category;
 96                             if (nCategory != "Activity" && nCategory != "Start") return;
 97                             this_.nodeDoubleClick(e, node);
 98                         },
100                         //鼠标悬停时显示node上的点
101                         mouseEnter: function (e, obj) {
102                             // this.displayNodePorts(obj.part, true);
103                             var diagram = obj.part.diagram;
104                             if (!diagram || diagram.isReadOnly || !diagram.allowLink) return;
105                             obj.part.ports.each(function (port) {
106                                 port.stroke = true ? "white" : null;
107                             });
108                         },
109                         mouseLeave: function (e, obj) {
110                             // this.displayNodePorts(obj.part, false);
111                             var diagram = obj.part.diagram;
112                             if (!diagram || diagram.isReadOnly || !diagram.allowLink) return;
113                             obj.part.ports.each(function (port) {
114                                 port.stroke = false ? "white" : null;
115                             });
116                         },
117                     },
118                     new go.Binding("location", "loc", go.Point.parse).makeTwoWay(
119                         go.Point.stringify
120                     ),
121                 ];
122             },
123             // displayNodePorts(node, show) {
124             //   var diagram = node.diagram;
125             //   if (!diagram || diagram.isReadOnly || !diagram.allowLink) return;
126             //   node.ports.each(function (port) {
127             //     port.stroke = show ? "white" : null;
128             //   });
129             // },
130             load() {
131                 this.myDiagram.model = go.Model.fromJson(
132                     document.getElementById("mySavedModel").value
133                 );
134             },
135             //   Show the diagram's model in JSON format that the user may edit    点击生产JSON
136             save() {
137                 document.getElementById(
138                     "mySavedModel"
139                 ).value = this.myDiagram.model.toJson();
140                 this.myDiagram.isModified = false;
141                 console.log(this.myDiagram.model.toJson(), "this.myDiagram");
142             },
143         },
144         mounted() {
145             var mySelf = this;
146             //  if (window.goSamples) goSamples();  // init for these samples -- you don't need to call this
147             var $ = go.GraphObject.make; // for conciseness in defining templates
149             mySelf.myDiagram = $(go.Diagram, "myDiagramDiv", {
150                 initialContentAlignment: go.Spot.Center, // 居中显示
154                 "undoManager.isEnabled": true, // 支持 Ctrl-Z 和 Ctrl-Y 操作
157                 "animationManager.isEnabled": true,
172             }); //构建gojs对象
174             var tbFontNormal = "normal normal normal 14px 'Microsoft YaHei',Arial";
175             var tbFontBold = "normal normal bold 14px 'Microsoft YaHei',Arial";
228             //创建node上的点,默认透明,悬停后显示白色
229             function makeNodePort(name, spot, output, input) {
230                 return $(go.Shape, "Circle", {
231                     fill: "transparent",
232                     stroke: null,
233                     desiredSize: new go.Size(8, 8),
234                     cursor: "pointer",
235                     portId: name,239                     toSpot: spot,
240                     fromLinkable: output,
241                     toLinkable: input,
242                 });
243             }
245             function textStyle() {
246                 return {
247                     font: "bold 11pt Lato, Helvetica, Arial, sans-serif",
248                     stroke: "#F8F8F8",
249                 };
250             }
252             // // define the Node templates for regular nodes
253             //审批节点
254             mySelf.myDiagram.nodeTemplateMap.add(
255                 "Activity",
256                 $(
257                     go.Node,
258                     "Spot",
259                     mySelf.nodeStyle(),
260                     $(
261                         go.Panel,
262                         "Auto",
263                         $(go.Shape, "Rectangle", {
264                             desiredSize: new go.Size(80, 40),
265                             minSize: new go.Size(20, 10),268                         }),
269                         $(
270                             go.TextBlock,
271                             "上级审批",
272                             {
273                                 stroke: "#FFFFFF",
274                                 font: tbFontNormal,
275                                 textAlign: "center",
276                                 margin: new go.Margin(7, 5, 5, 5),
277                                 maxSize: new go.Size(50, 20),
278                             },
279                             new go.Binding("text").makeTwoWay()
280                         )
281                     ),
282                     makeNodePort("T", go.Spot.Top, false, true),
283                     makeNodePort("R", go.Spot.Right, true, true),
284                     makeNodePort("B", go.Spot.Bottom, true, false),
285                     makeNodePort("L", go.Spot.Left, true, true)
286                 )
287             );
288             mySelf.myDiagram.nodeTemplateMap.add(
289                 "Conditional",
290                 $(
291                     go.Node,
292                     "Spot",
293                     mySelf.nodeStyle(),
294                     // the main object is a Panel that surrounds a TextBlock with a rectangular Shape
295                     $(
296                         go.Panel,
297                         "Auto",
298                         $(
299                             go.Shape,
300                             "Terminator",
301                             {
302                                 minSize: new go.Size(120, 38),
303                                 fill: "#4AAA4A",
304                                 stroke: "#4AAA4A",
305                                 strokeWidth: 3.5,
306                             },
307                             new go.Binding("figure", "figure")
308                         ),
309                         $(
310                             go.TextBlock,
311                             // textStyle(),
312                             {
313                                 stroke: "#FFFFFF",316                                 margin: new go.Margin(7, 5, 5, 5),
317                                 maxSize: new go.Size(160, NaN),
318                             },
319                             new go.Binding("text").makeTwoWay()
320                         )
321                     ),
322                     // four named ports, one on each side:
323                     makeNodePort("T", go.Spot.Top, false, true),
324                     makeNodePort("R", go.Spot.Right, false, true),
325                     makeNodePort("L", go.Spot.Left, false, true)
326                 )
327             );
329             mySelf.myDiagram.nodeTemplateMap.add(
330                 "Start",
331                 $(
332                     go.Node,
333                     "Spot",
334                     mySelf.nodeStyle(),
335                     $(
336                         go.Panel,
337                         "Auto",
338                         $(go.Shape, "Terminator", {
339                             // desiredSize: new go.Size(80, 40),
340                             minSize: new go.Size(120, 38),
341                             fill: "#1E90FF",
342                             stroke: "#1E90FF",
343                             strokeWidth: 3,
344                         }),
345                         $(go.TextBlock, "Start", textStyle(), new go.Binding("text"))
346                     ),
347                     // three named ports, one on each side except the top, all output only:
348                     makeNodePort("T", go.Spot.Top, false, true),351                     makeNodePort("L", go.Spot.Left, true, true)
352                 )
353             );
355             mySelf.myDiagram.nodeTemplateMap.add(
356                 "End",
357                 $(
358                     go.Node,
359                     "Auto",
360                     mySelf.nodeStyle(),
361                     // $(
362                     //   go.Panel,
363                     //   "Auto",
364                     $(go.Shape, "StopSign", {
365                         desiredSize: new go.Size(43, 43),
366                         // minSize: new go.Size(43, 43),
367                         fill: "#F37B1D",
368                         stroke: null,
369                         strokeWidth: 3,
370                     }),
371                     $(
372                         go.TextBlock,
373                         "End",
374                         { stroke: "#FFFFFF", font: tbFontNormal, textAlign: "center" },
375                         new go.Binding("text")
376                     ),
377                     // ),
378                     // three named ports, one on each side except the bottom, all input only:
379                     makeNodePort("T", go.Spot.Top, false, true),
380                     makeNodePort("R", go.Spot.Right, false, true),
381                     makeNodePort("B", go.Spot.Bottom, false, true),
382                     makeNodePort("L", go.Spot.Left, false, true)
383                 )
384             );
386             // taken from ../extensions/Figures.js:
387             go.Shape.defineFigureGenerator("File", function (shape, w, h) {
388                 var geo = new go.Geometry();
389                 var fig = new go.PathFigure(0, 0, true); // starting point
390                 geo.add(fig);
391                 fig.add(new go.PathSegment(go.PathSegment.Line, 0.75 * w, 0));394                 fig.add(new go.PathSegment(go.PathSegment.Line, 0, h).close());
395                 var fig2 = new go.PathFigure(0.75 * w, 0, false);
396                 geo.add(fig2);
397                 // The Fold
398                 fig2.add(new go.PathSegment(go.PathSegment.Line, 0.75 * w, 0.25 * h));
399                 fig2.add(new go.PathSegment(go.PathSegment.Line, w, 0.25 * h));
400                 geo.spot1 = new go.Spot(0, 0.25);
401                 geo.spot2 = go.Spot.BottomRight;
402                 return geo;
403             });
405             mySelf.myDiagram.nodeTemplateMap.add(
406                 "Comment",
407                 $(
408                     go.Node,
409                     "Auto",
410                     mySelf.nodeStyle(),
411                     $(go.Shape, "File", {
412                         minSize: new go.Size(80, 38),
413                         fill: "#F8EBBF",
414                         stroke: "#E1C76F",
415                         strokeWidth: 0,
416                     }),
417                     $(
418                         go.TextBlock,
419                         textStyle(),
420                         {
421                             stroke: "#555555",
422                             font: tbFontNormal,425                             maxSize: new go.Size(200, NaN),
426                             editable: true,
427                         },
428                         new go.Binding("text").makeTwoWay()
429                     )
430                     // no ports, because no links are allowed to connect with a comment
431                 )
432             );
434             // // replace the default Link template in the linkTemplateMap
435             mySelf.myDiagram.linkTemplate = $(
436                 go.Link, // the whole link panel
437                 {
438                     routing: go.Link.AvoidsNodes,
439                     curve: go.Link.JumpOver,
440                     corner: 2,
441                     fromShortLength: 1,
442                     toShortLength: 2,
443                     relinkableFrom: true,
444                     relinkableTo: true,
445                     reshapable: true,
446                     resegmentable: true,
447                     mouseEnter: function (e, link) {
448                         link.findObject("HIGHLIGHT").stroke = "rgba(30,144,255,0.5)";
449                     },
450                     mouseLeave: function (e, link) {
451                         link.findObject("HIGHLIGHT").stroke = "transparent";
452                     },
453                     // selectionAdorned: false,
454                     doubleClick: function (e, link) {
455                         if (!e.diagram) return;
456                         if (!e.diagram.allowLink) return;459                 },
460                 new go.Binding("points").makeTwoWay(),
461                 $(
462                     go.Shape, // the highlight shape, normally transparent
463                     {
464                         isPanelMain: true,
465                         strokeWidth: 8,
466                         stroke: "transparent",
467                         name: "HIGHLIGHT",
468                     }
469                 ),
470                 $(
471                     go.Shape, // the link path shape
472                     { isPanelMain: true, stroke: "gray", strokeWidth: 2 },
473                     new go.Binding("stroke", "isSelected", function (sel) {
474                         return sel ? "dodgerblue" : "gray";
475                     }).ofObject()
476                 ),
477                 $(
478                     go.Shape, // the arrowhead
479                     { toArrow: "standard", strokeWidth: 0, fill: "gray" }
480                 ),
481                 $(
482                     go.Panel,
483                     "Auto", // the link label, normally not visible
484                     {
485                         visible: false,
486                         name: "LABEL",
487                         segmentIndex: 2,
488                         segmentFraction: 0.5,
489                     },
490                     new go.Binding("visible", "visible").makeTwoWay(),
491                     $(
492                         go.Shape,
493                         "RoundedRectangle", // the label shape
494                         { fill: "#F8F8F8", strokeWidth: 0 }
495 497                         go.TextBlock,
498                         "Yes", // the label
499                         {
500                             textAlign: "center",
501                             font: "10pt helvetica, arial, sans-serif",
502                             stroke: "#333333",
503                             editable: true,
504                         },
505                         new go.Binding("text").makeTwoWay()
506                     )
507                 )
508             );
510             // Make link labels visible if coming out of a "conditional" node.
511             // This listener is called by the "LinkDrawn" and "LinkRelinked" DiagramEvents.
512             function showLinkLabel(e) {
513                 var label = e.subject.findObject("LABEL");
514                 if (label !== null)
515                     label.visible = e.subject.fromNode.data.category === "Conditional";
516             }
518             // temporary links used by LinkingTool and RelinkingTool are also orthogonal:
519             mySelf.myDiagram.toolManager.linkingTool.temporaryLink.routing =
520                 go.Link.Orthogonal;
521             mySelf.myDiagram.toolManager.relinkingTool.temporaryLink.routing =
522                 go.Link.Orthogonal;
524             mySelf.load(); // load an initial diagram from some JSON text
526             // initialize the Palette that is on the left side of the page
527             mySelf.myPalette = $(
528                 go.Palette,
529                 "myPaletteDiv", // must name or refer to the DIV HTML element
530                 {
531                     // Instead of the default animation, use a custom fade-down
532                     //   "animationManager.initialAnimationStyle": go.AnimationManager.None,
533                     //   "InitialAnimationStarting": animateFadeDown, // Instead, animate with this function
535                     nodeTemplateMap: mySelf.myDiagram.nodeTemplateMap, // share the templates used by myDiagram
536                     model: new go.GraphLinksModel([
537                         // specify the contents of the Palette
538                         { category: "Start", text: "开始" },
539                         { category: "Activity", text: "审批" },
540                         { category: "Conditional", text: "完成" },
541                         { category: "End", text: "撤销" },
542                         { category: "Comment", text: "备注" },
543                     ]),
544                 }
545             );
547             // This is a re-implementation of the default animation, except it fades in from downwards, instead of upwards.
548             function animateFadeDown(e) {
549                 var diagram = e.diagram;
550                 var animation = new go.Animation();
551                 animation.isViewportUnconstrained = true; // So Diagram positioning rules let the animation start off-screen
552                 animation.easing = go.Animation.EaseOutExpo;
553                 animation.duration = 900;
554                 // Fade "down", in other words, fade in from above
555                 animation.add(
556                     diagram,
557                     "position",
558                     diagram.position.copy().offset(0, 200),
559                     diagram.position
560                 );
561                 animation.add(diagram, "opacity", 0, 1);
562                 animation.start();
563             }
564         },
565     };
566 </script>
568 <style lang="less" scoped>
569     .modelingBox{
570         width:100%;
571         height:96%;
572     }
573     .modelingHead{
574         height:40px;
575         line-height:40px;
576         .msg_ {
577     float: right;
578     position: relative;
579     p {
580       display: inline;
581       margin-right: 15px;
582       position: absolute;
583       top: 2px;
584       left: -40px;
585     }
586   }
587     }
588     #sample {
589         width: 100%;
590         height: calc(100% - 40px);
591     }
592 </style>

需要转载的请表明出处,非本人同意禁止商业用途

1013218132