记录一下项目中的需求完成流程图示例,使用的是使用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