項目需求
實作可拖拽,可連結,自定義流程圖,輕按兩下可修改文字
項目效果截圖

vue引入GoJS
1.安裝
npm install --save gojs
2.全局引入——在main.js中引入
import gojs from ‘gojs’
Vue.prototype.go = gojs
3.單頁面引入
import go from ‘gojs’
drawFlow.vue頁面元素
<template>
<div class="o-hidden">
<!--拖拽區域-->
<div id="myPaletteDiv" class="fl"></div>
<!--畫布區域-->
<div id="myDiagramDiv" class="fl"></div>
<Button type="info" class="btnSave" @click="save()">儲存</Button>
</div>
</template>
封裝公共節點綁定樣式函數
function nodeStyle() {
return [
new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
{locationSpot: go.Spot.Center}
];
}
封裝文字綁定樣式函數
function textStyle() {
return {
font: "bold 11pt Helvetica, Arial, sans-serif",
stroke: "whitesmoke",
editable: true,
margin: 3
}
}
封裝連接配接點端口函數
function makePort(name, align, spot, output, input) {
var horizontal = align.equals(go.Spot.Top) || align.equals(go.Spot.Bottom);
return $(go.Shape,
{
fill: "transparent",
strokeWidth: 0,
width: horizontal ? NaN : 8,
height: !horizontal ? NaN : 8,
alignment: align,
stretch: (horizontal ? go.GraphObject.Horizontal : go.GraphObject.Vertical),
portId: name,
fromSpot: spot,
fromLinkable: output,
toSpot: spot,
toLinkable: input,
cursor: "pointer",
mouseEnter: function (e, port) {
if (!e.diagram.isReadOnly) port.fill = "rgba(255,0,255,0.5)";
},
mouseLeave: function (e, port) {
port.fill = "transparent";
}
});
}
拖拽區域palette設定
_this.configData.myPalette =
$(go.Palette, "myPaletteDiv",
{
scrollsPageOnFocus: false,
//節點模闆是畫布區域的模闆
nodeTemplateMap: _this.configData.myDiagram.nodeTemplateMap,
model: new go.GraphLinksModel([
{category: "Start", text: "Start"},
{text: "Step"},
{category: "Conditional", text: "???"},
{category: "End", text: "End"}
])
});
點選儲存按鈕,浏覽器下載下傳json檔案,可供以後導入使用
this.configData.mySaveModel = this.configData.myDiagram.model.toJson();
exportRaw('drawFlow.json', this.configData.mySaveModel);
//生成json
function fakeClick(obj) {
var ev = document.createEvent("MouseEvents");
ev.initMouseEvent("click", true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
obj.dispatchEvent(ev);
}
function exportRaw(name, data) {
var urlObject = window.URL || window.webkitURL || window;
var export_blob = new Blob([data]);
var save_link = document.createElementNS("http://www.w3.org/1999/xhtml", "a");
save_link.href = urlObject.createObjectURL(export_blob);
save_link.download = name;
fakeClick(save_link);
}
附上具體代碼
(需要注意的是this指向問題)
<template>
<div class="o-hidden">
<div id="myPaletteDiv" class="fl"></div>
<div id="myDiagramDiv" class="fl"></div>
<Button type="info" class="btnSave" @click="save()">儲存</Button>
</div>
</template>
<script>
import go from 'gojs';
export default {
name: "drawFlow",
created() {
this.configData.myDiagram.div = null;
this.$axios({
method: 'get',
url: '@/../static/json/drawFlow.json'
})
.then((res) => {
this.configData.mySaveModel = res.data;
this.init();
})
},
data() {
return {
configData: {
myDiagram: {},//組态模闆
myPalette: {},
mySaveModel: ''
},
}
},
methods: {
save() {
this.configData.mySaveModel = this.configData.myDiagram.model.toJson();
exportRaw('drawFlow.json', this.configData.mySaveModel);
//生成json
function fakeClick(obj) {
var ev = document.createEvent("MouseEvents");
ev.initMouseEvent("click", true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
obj.dispatchEvent(ev);
}
function exportRaw(name, data) {
var urlObject = window.URL || window.webkitURL || window;
var export_blob = new Blob([data]);
var save_link = document.createElementNS("http://www.w3.org/1999/xhtml", "a");
save_link.href = urlObject.createObjectURL(export_blob);
save_link.download = name;
fakeClick(save_link);
}
},
init() {
var $ = go.GraphObject.make;
let _this = this;
_this.configData.myDiagram =
$(go.Diagram, "myDiagramDiv",
{
initialContentAlignment: go.Spot.Center,
allowDrop: true,
"LinkDrawn": showLinkLabel,
"LinkRelinked": showLinkLabel,
scrollsPageOnFocus: false,
"undoManager.isEnabled": true,
autoScale: go.Diagram.Uniform
});
function nodeStyle() {
return [
new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
{locationSpot: go.Spot.Center}
];
}
function makePort(name, align, spot, output, input) {
var horizontal = align.equals(go.Spot.Top) || align.equals(go.Spot.Bottom);
return $(go.Shape,
{
fill: "transparent",
strokeWidth: 0,
width: horizontal ? NaN : 8,
height: !horizontal ? NaN : 8,
alignment: align,
stretch: (horizontal ? go.GraphObject.Horizontal : go.GraphObject.Vertical),
portId: name,
fromSpot: spot,
fromLinkable: output,
toSpot: spot,
toLinkable: input,
cursor: "pointer",
mouseEnter: function (e, port) {
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",
editable: true,
margin: 3
}
}
_this.configData.myDiagram.nodeTemplateMap.add("",
$(go.Node, "Table", nodeStyle(),
$(go.Panel, "Auto",
$(go.Shape, "Rectangle",
{fill: "#729FDC", maxSize: new go.Size(150, 140)},
new go.Binding("figure", "figure")),
$(go.TextBlock, textStyle(),
{
maxSize: new go.Size(140, NaN),
wrap: go.TextBlock.WrapFit,
editable: true,
margin: 5,
},
new go.Binding("text").makeTwoWay())
),
makePort("T", go.Spot.Top, go.Spot.TopSide, true, 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, true)
));
_this.configData.myDiagram.nodeTemplateMap.add("Conditional",
$(go.Node, "Table", nodeStyle(),
$(go.Panel, "Auto",
$(go.Shape, "Diamond",
{fill: "#729FDC"},
new go.Binding("figure", "figure")),
$(go.TextBlock, textStyle(),
{
maxSize: new go.Size(160, NaN),
wrap: go.TextBlock.WrapFit,
editable: true,
margin: new go.Margin(5, 2, 5, 2),
},
new go.Binding("text").makeTwoWay())
),
makePort("T", go.Spot.Top, go.Spot.Top, true, true),
makePort("L", go.Spot.Left, go.Spot.Left, true, true),
makePort("R", go.Spot.Right, go.Spot.Right, true, true),
makePort("B", go.Spot.Bottom, go.Spot.Bottom, true, true)
));
_this.configData.myDiagram.nodeTemplateMap.add("Start",
$(go.Node, "Table", nodeStyle(),
$(go.Panel, "Auto",
$(go.Shape, "Circle",
{minSize: new go.Size(40, 40), fill: "#729FDC"}),
$(go.TextBlock, "Start", textStyle(),
new go.Binding("text"))
),
makePort("L", go.Spot.Left, go.Spot.Left, true, true),
makePort("R", go.Spot.Right, go.Spot.Right, true, true),
makePort("B", go.Spot.Bottom, go.Spot.Bottom, true, true)
));
_this.configData.myDiagram.nodeTemplateMap.add("End",
$(go.Node, "Table", nodeStyle(),
$(go.Panel, "Auto",
$(go.Shape, "Circle",
{minSize: new go.Size(40, 40), fill: "#729FDC"}),
$(go.TextBlock, "End", textStyle(),
new go.Binding("text"))
),
makePort("L", go.Spot.Left, go.Spot.Left, true, true),
makePort("R", go.Spot.Right, go.Spot.Right, true, true),
// makePort("B", go.Spot.Bottom, go.Spot.Bottom, true, true)
makePort("T", go.Spot.Top, go.Spot.Top, true, true)
));
_this.configData.myDiagram.linkTemplate =
$(go.Link,
{
routing: go.Link.AvoidsNodes,
curve: go.Link.JumpOver,
corner: 5, toShortLength: 4,
relinkableFrom: true,
relinkableTo: true,
reshapable: true,
resegmentable: true,
mouseEnter: function (e, link) {
link.findObject("HIGHLIGHT").stroke = "rgba(30,144,255,0.2)";
},
mouseLeave: function (e, link) {
link.findObject("HIGHLIGHT").stroke = "transparent";
},
selectionAdorned: false
},
new go.Binding("points").makeTwoWay(),
$(go.Shape,
{isPanelMain: true, strokeWidth: 8, stroke: "transparent", name: "HIGHLIGHT"}),
$(go.Shape,
{isPanelMain: true, stroke: "gray", strokeWidth: 2},
new go.Binding("stroke", "isSelected", function (sel) {
return sel ? "dodgerblue" : "gray";
}).ofObject()),
$(go.Shape,
{toArrow: "standard", strokeWidth: 0, fill: "gray"}),
$(go.Panel, "Auto",
{visible: false, name: "LABEL", segmentIndex: 2, segmentFraction: 0.5},
new go.Binding("visible", "visible").makeTwoWay(),
$(go.Shape, "RoundedRectangle",
{fill: "#F8F8F8", strokeWidth: 0}),
$(go.TextBlock, "Yes",
{
textAlign: "center",
font: "10pt helvetica, arial, sans-serif",
stroke: "#333333",
editable: true
},
new go.Binding("text").makeTwoWay())
)
);
function showLinkLabel(e) {
var label = e.subject.findObject("LABEL");
if (label !== null) label.visible = (e.subject.fromNode.data.category === "Conditional");
}
_this.configData.myDiagram.toolManager.linkingTool.temporaryLink.routing = go.Link.Orthogonal;
_this.configData.myDiagram.toolManager.relinkingTool.temporaryLink.routing = go.Link.Orthogonal;
_this.configData.myPalette =
$(go.Palette, "myPaletteDiv",
{
scrollsPageOnFocus: false,
nodeTemplateMap: _this.configData.myDiagram.nodeTemplateMap,
model: new go.GraphLinksModel([
{category: "Start", text: "Start"},
{text: "Step"},
{category: "Conditional", text: "???"},
{category: "End", text: "End"}
])
});
_this.configData.myDiagram.model = go.Model.fromJson(_this.configData.mySaveModel);
}
}
}
</script>
<style scoped>
#myPaletteDiv{
width: 100px;
height: 680px;
margin-right: 2px;
background-color: whitesmoke;
border: 1px solid black
}
#myDiagramDiv{
width: 1010px;
height: 680px;
border: 1px solid black;
}
.btnSave{
clear: both;
margin:20px auto;
display: block;
font-size: 14px;
position: relative;
top:20px;
width:150px;
}
.o-hidden{
width: 1112px;
margin: 20px auto;
}
</style>