在vue中使用gojs实现流程图功能

记录一下项目中的需求完成流程图示例,使用的是使用vue-cli搭建的项目,配合gojs来实现的,附上截图一份:


完成保存,清空等功能

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

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

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

<template>

    <div class="modelingBox">

        <div class="modelingHead">

            <el-button id="SaveButton" @click="save">保存</el-button>

            <el-button @click="load">清空</el-button>

            <textarea id="mySavedModel" style="width:100%;height:300px;display:none">                 { "class": "go.GraphLinksModel",                "linkFromPortIdProperty": "fromPort",                "linkToPortIdProperty": "toPort",                "nodeDataArray": [               ],                "linkDataArray": [               ]}               

 </textarea>            

<div class="msg_">                

<p>流程</p>                

<el-select v-model="valueOptions" @change="selectChange" filterable placeholder="请选择">

                    <el-option v-for="item in options"                               :key="item.value"                               :label="item.label"                               :value="item.value"></el-option>                

</el-select>            

</div>        

</div>            

<div id="sample">           

 <div style="width: 100%;height:100%; display: flex; justify-content: space-between">                

<div id="myPaletteDiv" style="width: 200px; margin-right: 2px; background-color: #fafafa;"></div>                

<div id="myDiagramDiv" style="flex-grow: 1; height: 100%; background-color: #fafafa;"></div>           

 </div>                  

</div>       

 <el-dialog title="开始节点" :visible.sync="StartShow" width="30%" :before-close="handleClose">

            <span>这是一段信息</span>            <span slot="footer" class="dialog-footer">                

<el-button @click="StartShow = false">取 消</el-button>                

<el-button type="primary" @click="StartShow = false">确 定</el-button>            </span>        

</el-dialog>        

<el-dialog title="审批节点" :visible.sync="ActivityShow" width="30%" :before-close="handleClose">           

 <span>这是一段信息</span>            <span slot="footer" class="dialog-footer">                

<el-button @click="ActivityShow = false">取 消</el-button>               

 <el-button type="primary" @click="ActivityShow = false">确 定</el-button>            </span>        

</el-dialog>    

</div>

</template>

js:

<script>    // import { init } from "./test";    import go from "./gojs/go-cracked";    export default {        data() {            return {                StartShow: false,                ActivityShow: false,                options: [                    {                        value: '0',                        label:'路段管理单位发文流程(1.0)'                    },                    {                        value: '1',                        label: '支队收文流程(1.0)'                    }                ],                valueOptions:''            };        },        methods: {            selectChange() {                console.log(this.valueOptions,'select')            },            handleClose() {                this.StartShow = false                this.ActivityShow = false            },            nodeDoubleClick(e, node) {                console.log(e, node.part.data.category);                if (node.part.data.category == "Start") {                    this.StartShow = true;                } else if (node.part.data.category == "Activity") {                    this.ActivityShow = true;                }            },            nodeStyle() {                var this_ = this;                return [                    {                        locationSpot: go.Spot.Center,                        isShadowed: false,                        doubleClick: function (e, node) {                            if (!e.diagram) return;                            if (!e.diagram.allowLink) return;                            var nCategory = node.part.data.category;                            if (nCategory != "Activity" && nCategory != "Start") return;                            this_.nodeDoubleClick(e, node);                        },                        //鼠标悬停时显示node上的点                        mouseEnter: function (e, obj) {                            // this.displayNodePorts(obj.part, true);                            var diagram = obj.part.diagram;                            if (!diagram || diagram.isReadOnly || !diagram.allowLink) return;                            obj.part.ports.each(function (port) {                                port.stroke = true ? "white" : null;                            });                        },                        mouseLeave: function (e, obj) {                            // this.displayNodePorts(obj.part, false);                            var diagram = obj.part.diagram;                            if (!diagram || diagram.isReadOnly || !diagram.allowLink) return;                            obj.part.ports.each(function (port) {                                port.stroke = false ? "white" : null;                            });                        },                    },                    new go.Binding("location", "loc", go.Point.parse).makeTwoWay(                        go.Point.stringify                    ),                ];            },            // displayNodePorts(node, show) {            //   var diagram = node.diagram;            //   if (!diagram || diagram.isReadOnly || !diagram.allowLink) return;            //   node.ports.each(function (port) {            //     port.stroke = show ? "white" : null;            //   });            // },            load() {                this.myDiagram.model = go.Model.fromJson(                    document.getElementById("mySavedModel").value                );            },            //   Show the diagram's model in JSON format that the user may edit    点击生产JSON            save() {                document.getElementById(                    "mySavedModel"                ).value = this.myDiagram.model.toJson();                this.myDiagram.isModified = false;                console.log(this.myDiagram.model.toJson(), "this.myDiagram");            },        },        mounted() {            var mySelf = this;            //  if (window.goSamples) goSamples();  // init for these samples -- you don't need to call this            var $ = go.GraphObject.make; // for conciseness in defining templates            mySelf.myDiagram = $(go.Diagram, "myDiagramDiv", {                initialContentAlignment: go.Spot.Center, // 居中显示                allowDrop: true,                isReadOnly: false,                "undoManager.isEnabled": true, // 支持 Ctrl-Z 和 Ctrl-Y 操作                //   "toolManager.hoverDelay": 100, //tooltip提示显示延时                //   "toolManager.toolTipDuration": 10000, //tooltip持续显示时间                "animationManager.isEnabled": true,                "animationManager.duration": 500,                //isReadOnly:true,//只读                "grid.visible": true, //显示网格                //   allowMove: true, //允许拖动                //   allowDragOut: true,                //   allowDelete: true,                //   allowCopy: true,                // allowClipboard: false,                //   "toolManager.mouseWheelBehavior": go.ToolManager.WheelZoom, //有鼠标滚轮事件放大和缩小,而不是向上和向下滚动                //拖动后自动排列位置                //   layout: $(go.TreeLayout, {                //     angle: 0,                //     layerSpacing: 35,                //   }),            }); //构建gojs对象            var tbFontNormal = "normal normal normal 14px 'Microsoft YaHei',Arial";            var tbFontBold = "normal normal bold 14px 'Microsoft YaHei',Arial";            // // when the document is modified, add a "*" to the title and enable the "Save" button            // mySelf.myDiagram.addDiagramListener("Modified", (e) => {            //   var button = document.getElementById("SaveButton");            //   if (button) button.disabled = !mySelf.myDiagram.isModified;            //   var idx = document.title.indexOf("*");            //   if (mySelf.myDiagram.isModified) {            //     if (idx < 0) document.title += "*";            //   } else {            //     if (idx >= 0) document.title = document.title.substr(0, idx);            //   }            // });            // // helper definitions for node templates            // mySelf.nodeStyle();            // Define a function for creating a "port" that is normally transparent.            // The "name" is used as the GraphObject.portId,            // the "align" is used to determine where to position the port relative to the body of the node,            // the "spot" is used to control how links connect with the port and whether the port            // stretches along the side of the node,            // and the boolean "output" and "input" arguments control whether the user can draw links from or to the port.            //  mySelf.makePort(name, align, spot, output, input)            // function makePort(name, align, spot, output, input) {            //   var horizontal =            //     align.equals(go.Spot.Top) || align.equals(go.Spot.Bottom);            //   // the port is basically just a transparent rectangle that stretches along the side of the node,            //   // and becomes colored when the mouse passes over it            //   return $(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: (e, port) => {            //       port.fill = "transparent";            //     },            //   });            // }            //创建node上的点,默认透明,悬停后显示白色            function makeNodePort(name, spot, output, input) {                return $(go.Shape, "Circle", {                    fill: "transparent",                    stroke: null,                    desiredSize: new go.Size(8, 8),                    cursor: "pointer",                    portId: name,                    alignment: spot,                    alignmentFocus: spot,                    fromSpot: spot,                    toSpot: spot,                    fromLinkable: output,                    toLinkable: input,                });            }            function textStyle() {                return {                    font: "bold 11pt Lato, Helvetica, Arial, sans-serif",                    stroke: "#F8F8F8",                };            }            // // define the Node templates for regular nodes            //审批节点            mySelf.myDiagram.nodeTemplateMap.add(                "Activity",                $(                    go.Node,                    "Spot",                    mySelf.nodeStyle(),                    $(                        go.Panel,                        "Auto",                        $(go.Shape, "Rectangle", {                            desiredSize: new go.Size(80, 40),                            minSize: new go.Size(20, 10),                            fill: "#1E90FF",                            stroke: "#1E90FF",                        }),                        $(                            go.TextBlock,                            "上级审批",                            {                                stroke: "#FFFFFF",                                font: tbFontNormal,                                textAlign: "center",                                margin: new go.Margin(7, 5, 5, 5),                                maxSize: new go.Size(50, 20),                            },                            new go.Binding("text").makeTwoWay()                        )                    ),                    makeNodePort("T", go.Spot.Top, false, true),                    makeNodePort("R", go.Spot.Right, true, true),                    makeNodePort("B", go.Spot.Bottom, true, false),                    makeNodePort("L", go.Spot.Left, true, true)                )            );            mySelf.myDiagram.nodeTemplateMap.add(                "Conditional",                $(                    go.Node,                    "Spot",                    mySelf.nodeStyle(),                    // the main object is a Panel that surrounds a TextBlock with a rectangular Shape                    $(                        go.Panel,                        "Auto",                        $(                            go.Shape,                            "Terminator",                            {                                minSize: new go.Size(120, 38),                                fill: "#4AAA4A",                                stroke: "#4AAA4A",                                strokeWidth: 3.5,                            },                            new go.Binding("figure", "figure")                        ),                        $(                            go.TextBlock,                            // textStyle(),                            {                                stroke: "#FFFFFF",                                font: tbFontBold,                                textAlign: "center",                                margin: new go.Margin(7, 5, 5, 5),                                maxSize: new go.Size(160, NaN),                            },                            new go.Binding("text").makeTwoWay()                        )                    ),                    // four named ports, one on each side:                    makeNodePort("T", go.Spot.Top, false, true),                    makeNodePort("R", go.Spot.Right, false, true),                    makeNodePort("L", go.Spot.Left, false, true)                )            );            mySelf.myDiagram.nodeTemplateMap.add(                "Start",                $(                    go.Node,                    "Spot",                    mySelf.nodeStyle(),                    $(                        go.Panel,                        "Auto",                        $(go.Shape, "Terminator", {                            // desiredSize: new go.Size(80, 40),                            minSize: new go.Size(120, 38),                            fill: "#1E90FF",                            stroke: "#1E90FF",                            strokeWidth: 3,                        }),                        $(go.TextBlock, "Start", textStyle(), new go.Binding("text"))                    ),                    // three named ports, one on each side except the top, all output only:                    makeNodePort("T", go.Spot.Top, false, true),                    makeNodePort("R", go.Spot.Right, true, true),                    makeNodePort("B", go.Spot.Bottom, true, false),                    makeNodePort("L", go.Spot.Left, true, true)                )            );            mySelf.myDiagram.nodeTemplateMap.add(                "End",                $(                    go.Node,                    "Auto",                    mySelf.nodeStyle(),                    // $(                    //   go.Panel,                    //   "Auto",                    $(go.Shape, "StopSign", {                        desiredSize: new go.Size(43, 43),                        // minSize: new go.Size(43, 43),                        fill: "#F37B1D",                        stroke: null,                        strokeWidth: 3,                    }),                    $(                        go.TextBlock,                        "End",                        { stroke: "#FFFFFF", font: tbFontNormal, textAlign: "center" },                        new go.Binding("text")                    ),                    // ),                    // three named ports, one on each side except the bottom, all input only:                    makeNodePort("T", go.Spot.Top, false, true),                    makeNodePort("R", go.Spot.Right, false, true),                    makeNodePort("B", go.Spot.Bottom, false, true),                    makeNodePort("L", go.Spot.Left, false, true)                )            );            // taken from ../extensions/Figures.js:            go.Shape.defineFigureGenerator("File", function (shape, w, h) {                var geo = new go.Geometry();                var fig = new go.PathFigure(0, 0, true); // starting point                geo.add(fig);                fig.add(new go.PathSegment(go.PathSegment.Line, 0.75 * w, 0));                fig.add(new go.PathSegment(go.PathSegment.Line, w, 0.25 * h));                fig.add(new go.PathSegment(go.PathSegment.Line, w, h));                fig.add(new go.PathSegment(go.PathSegment.Line, 0, h).close());                var fig2 = new go.PathFigure(0.75 * w, 0, false);                geo.add(fig2);                // The Fold                fig2.add(new go.PathSegment(go.PathSegment.Line, 0.75 * w, 0.25 * h));                fig2.add(new go.PathSegment(go.PathSegment.Line, w, 0.25 * h));                geo.spot1 = new go.Spot(0, 0.25);                geo.spot2 = go.Spot.BottomRight;                return geo;            });            mySelf.myDiagram.nodeTemplateMap.add(                "Comment",                $(                    go.Node,                    "Auto",                    mySelf.nodeStyle(),                    $(go.Shape, "File", {                        minSize: new go.Size(80, 38),                        fill: "#F8EBBF",                        stroke: "#E1C76F",                        strokeWidth: 0,                    }),                    $(                        go.TextBlock,                        textStyle(),                        {                            stroke: "#555555",                            font: tbFontNormal,                            wrap: go.TextBlock.WrapFit,                            margin: new go.Margin(4, 5, 5, 5),                            maxSize: new go.Size(200, NaN),                            editable: true,                        },                        new go.Binding("text").makeTwoWay()                    )                    // no ports, because no links are allowed to connect with a comment                )            );            // // replace the default Link template in the linkTemplateMap            mySelf.myDiagram.linkTemplate = $(                go.Link, // the whole link panel                {                    routing: go.Link.AvoidsNodes,                    curve: go.Link.JumpOver,                    corner: 2,                    fromShortLength: 1,                    toShortLength: 2,                    relinkableFrom: true,                    relinkableTo: true,                    reshapable: true,                    resegmentable: true,                    mouseEnter: function (e, link) {                        link.findObject("HIGHLIGHT").stroke = "rgba(30,144,255,0.5)";                    },                    mouseLeave: function (e, link) {                        link.findObject("HIGHLIGHT").stroke = "transparent";                    },                    // selectionAdorned: false,                    doubleClick: function (e, link) {                        if (!e.diagram) return;                        if (!e.diagram.allowLink) return;                        linkDoubleClick(e, link);                    },                },                new go.Binding("points").makeTwoWay(),                $(                    go.Shape, // the highlight shape, normally transparent                    {                        isPanelMain: true,                        strokeWidth: 8,                        stroke: "transparent",                        name: "HIGHLIGHT",                    }                ),                $(                    go.Shape, // the link path shape                    { isPanelMain: true, stroke: "gray", strokeWidth: 2 },                    new go.Binding("stroke", "isSelected", function (sel) {                        return sel ? "dodgerblue" : "gray";                    }).ofObject()                ),                $(                    go.Shape, // the arrowhead                    { toArrow: "standard", strokeWidth: 0, fill: "gray" }                ),                $(                    go.Panel,                    "Auto", // the link label, normally not visible                    {                        visible: false,                        name: "LABEL",                        segmentIndex: 2,                        segmentFraction: 0.5,                    },                    new go.Binding("visible", "visible").makeTwoWay(),                    $(                        go.Shape,                        "RoundedRectangle", // the label shape                        { fill: "#F8F8F8", strokeWidth: 0 }                    ),                    $(                        go.TextBlock,                        "Yes", // the label                        {                            textAlign: "center",                            font: "10pt helvetica, arial, sans-serif",                            stroke: "#333333",                            editable: true,                        },                        new go.Binding("text").makeTwoWay()                    )                )            );            // Make link labels visible if coming out of a "conditional" node.            // This listener is called by the "LinkDrawn" and "LinkRelinked" DiagramEvents.            function showLinkLabel(e) {                var label = e.subject.findObject("LABEL");                if (label !== null)                    label.visible = e.subject.fromNode.data.category === "Conditional";            }            // temporary links used by LinkingTool and RelinkingTool are also orthogonal:            mySelf.myDiagram.toolManager.linkingTool.temporaryLink.routing =                go.Link.Orthogonal;            mySelf.myDiagram.toolManager.relinkingTool.temporaryLink.routing =                go.Link.Orthogonal;            mySelf.load(); // load an initial diagram from some JSON text            // initialize the Palette that is on the left side of the page            mySelf.myPalette = $(                go.Palette,                "myPaletteDiv", // must name or refer to the DIV HTML element                {                    // Instead of the default animation, use a custom fade-down                    //   "animationManager.initialAnimationStyle": go.AnimationManager.None,                    //   "InitialAnimationStarting": animateFadeDown, // Instead, animate with this function                    nodeTemplateMap: mySelf.myDiagram.nodeTemplateMap, // share the templates used by myDiagram                    model: new go.GraphLinksModel([                        // specify the contents of the Palette                        { category: "Start", text: "开始" },                        { category: "Activity", text: "审批" },                        { category: "Conditional", text: "完成" },                        { category: "End", text: "撤销" },                        { category: "Comment", text: "备注" },                    ]),                }            );            // This is a re-implementation of the default animation, except it fades in from downwards, instead of upwards.            function animateFadeDown(e) {                var diagram = e.diagram;                var animation = new go.Animation();                animation.isViewportUnconstrained = true; // So Diagram positioning rules let the animation start off-screen                animation.easing = go.Animation.EaseOutExpo;                animation.duration = 900;                // Fade "down", in other words, fade in from above                animation.add(                    diagram,                    "position",                    diagram.position.copy().offset(0, 200),                    diagram.position                );                animation.add(diagram, "opacity", 0, 1);                animation.start();            }        },    };</script>

css"

<style lang="less" scoped>    .modelingBox{        width:100%;        height:96%;    }    .modelingHead{        height:40px;        line-height:40px;        .msg_ {    float: right;    position: relative;    p {      display: inline;      margin-right: 15px;      position: absolute;      top: 2px;      left: -40px;    }  }    }    #sample {        width: 100%;        height: calc(100% - 40px);    }</style>



简书代码不知道如何格式化,有需要的可以去我博客园看看:

https://www.cnblogs.com/kqlhp520/

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343