GOJS使用--前端拓撲圖
1.基礎版:
-
引入go.jsjavascript
<script src="./js/go.js" type="text/javascript"></script>
-
定義html標籤css
<!--每一個go.js圖都包含在html元素中,咱們須要給出一個顯示的大小--> <div id="myDiagramDiv" style="width:400px; height:150px;background-color: #DAE4E4"></div>
-
jshtml
<script> // make構建gojs對象,使$縮寫go.GraphObject var $ = go.GraphObject.make; // JS中,繪製圖標時須要傳遞html標籤的ID var myDiagram = $(go.Diagram, "myDiagramDiv", { "undoManager.isEnabled": true //啓動ctrl+z撤銷 和 ctrk+y 重作 } ); // 在模型數據中,每一個節點都由一個JavaScript對象表示 var Mymodel = $(go.Model); Mymodel.nodeDataArray = [ {key: "Alpha"}, {key: "Beta"}, {key: "Gamma"}, ]; myDiagram.model = Mymodel </script>
-
效果以下顯示:能夠在go.js圖的範圍內任意拖動三個模塊,可是不難發現html上多了幾行水印:前端
-
去除水印方式:vue
在go.js搜索7eba17a4ca3b1a8346 # 註釋掉該行 a.zr = b.V[Ra("7eba17a4ca3b1a8346")][Ra("78a118b7")](b.V, Ik, 4, 4); # 下一行添加 a.zr = function(){return true;}
2.拓撲圖模塊添置圖片
-
jsjava
<script> // make構建gojs對象,使$縮寫go.GraphObject var $ = go.GraphObject.make; // JS中,繪製圖標時須要傳遞html標籤的ID var myDiagram = $(go.Diagram, "myDiagramDiv", { "undoManager.isEnabled": true //啓動ctrl+z撤銷 和 ctrk+y 重作 } ); // 定義node myDiagram.nodeTemplate = $(go.Node, "Horizontal", // 添加北京顏色 此爲當前節點對象 {background:"#44CCFF"}, $(go.Picture, // 圖片的寬高,包括圖片背景(在未設置狀況下顯示) {margin:10,width:50,height:50,background:"red"}, // Picture.source 綁定模型數據source屬性的數據 new go.Binding("source") ), $(go.TextBlock, // TextBlock.text初始值 "默認值..", // 文本一些樣式設置字體顏色,字體大小。。。 {margin:12,stroke:"white",font:"bold 16px sans-serif"}, // TextBlock.text 是綁定到模型數據的 name屬性的數據 new go.Binding("text","name") ) ); // 在模型數據中,每一個節點都由一個JavaScript對象表示 var Mymodel = $(go.Model); Mymodel.nodeDataArray = [ {name: "Alpha", "source":"img/cat1.png"}, {name: "Beta", "source":"img/cat2.png"}, {name: "Gamma", "source":"img/cat2.png"}, {/* Emoty node data */} ]; myDiagram.model = Mymodel </script>
-
顯示效果:
node
3.添置鏈接線
-
只須要將Model模型改爲TreeModel.並將定義每條數據key和parent來肯定每一個節點之間關係。git
// key 和oarent來肯定每一個節點之間關係 var Mymodel = $(go.TreeModel); Mymodel.nodeDataArray = [ {name: "Alpha", "source":"img/cat1.png", key:"1"}, {name: "Beta", "source":"img/cat2.png", key:"2", parent:"1"}, {name: "Gamma", "source":"img/cat2.png", key:"3",parent:"1"}, ];
-
顯示效果github
4.圖標佈局 樹形結構先彷佛
-
須要定義layout.來構建樹形結構json
<script> // make構建gojs對象,使$縮寫go.GraphObject var $ = go.GraphObject.make; // JS中,繪製圖標時須要傳遞html標籤的ID var myDiagram = $(go.Diagram, "myDiagramDiv", { "undoManager.isEnabled": true, //啓動ctrl+z撤銷 和 ctrk+y 重作 // 指定一個樹形結構:從上到下 // TreeLayout 默認未從左到右流動,當設置90從上到下,當設置180,從右向左,當設置270表示從下到上 // layerSpacing 實行結構每一層的間距 layout: $(go.TreeLayout, {angle:90,layerSpacing:50} ) } ); // 定義node myDiagram.nodeTemplate = $(go.Node, "Horizontal", // 添加北京顏色 此爲當前節點對象 {background:"#44CCFF"}, $(go.Picture, // 圖片的寬高,包括圖片背景(在未設置狀況下顯示) {margin:10,width:50,height:50,background:"red"}, // Picture.source 綁定模型數據source屬性的數據 new go.Binding("source") ), $(go.TextBlock, // TextBlock.text初始值 "默認值..", // 文本一些樣式設置字體顏色,字體大小。。。 {margin:12,stroke:"white",font:"bold 16px sans-serif"}, // TextBlock.text 是綁定到模型數據的 name屬性的數據 new go.Binding("text","name") ) ); // 在模型數據中,每一個節點都由一個JavaScript對象表示 var Mymodel = $(go.TreeModel); Mymodel.nodeDataArray = [ {name: "Alpha", "source":"img/cat1.png", key:"1"}, {name: "Beta", "source":"img/cat2.png", key:"2", parent:"1"}, {name: "Gamma", "source":"img/cat3.png", key:"3",parent:"1"}, {name: "Jellylorum", "source":"img/cat4.png", key:"4",parent:"3"}, {name: "Alonzo", "source":"img/cat5.png", key:"5",parent:"3"}, {name: "Munkustrap", "source":"img/cat6.png", key:"6",parent:"2"}, ]; myDiagram.model = Mymodel </script>
-
顯示效果
5.連接模式
-
須要定義路線模板和箭頭模板
<script> // make構建gojs對象,使$縮寫go.GraphObject var $ = go.GraphObject.make; // JS中,繪製圖標時須要傳遞html標籤的ID var myDiagram = $(go.Diagram, "myDiagramDiv", { "undoManager.isEnabled": true, //啓動ctrl+z撤銷 和 ctrk+y 重作 // 指定一個樹形結構:從上到下 // TreeLayout 默認未從左到右流動,當設置90從上到下,當設置180,從右向左,當設置270表示從下到上 // layerSpacing 實行結構每一層的間距 layout: $(go.TreeLayout, {angle:90,layerSpacing:50} ) } ); // 定義node myDiagram.nodeTemplate = $(go.Node, "Horizontal", // 添加北京顏色 此爲當前節點對象 {background:"#44CCFF"}, $(go.Picture, // 圖片的寬高,包括圖片背景(在未設置狀況下顯示) {margin:10,width:50,height:50,background:"red"}, // Picture.source 綁定模型數據source屬性的數據 new go.Binding("source") ), $(go.TextBlock, // TextBlock.text初始值 "默認值..", // 文本一些樣式設置字體顏色,字體大小。。。 {margin:12,stroke:"white",font:"bold 16px sans-serif"}, // TextBlock.text 是綁定到模型數據的 name屬性的數據 new go.Binding("text","name") ) ); // 定義一個有箭頭路線模板 myDiagram.linkTemplate = $(go.Link, // routing默認未go.Link.Normal // corner 爲轉角值,就是線置交轉交的弧度 {routing:go.Link.Orthogonal, corner:5}, // strokeWidth 線的粗細,stroke 線的顏色 $(go.Shape,{strokeWidth:3, stroke: "#555"}), // 生成箭頭模板toArrow:Standard,OpenTriangle... stroke爲箭頭顏色 $(go.Shape,{toArrow:"Standard",stroke:null}) ); // 在模型數據中,每一個節點都由一個JavaScript對象表示 var Mymodel = $(go.TreeModel); Mymodel.nodeDataArray = [ {name: "Alpha", "source":"img/cat1.png", key:"1"}, {name: "Beta", "source":"img/cat2.png", key:"2", parent:"1"}, {name: "Gamma", "source":"img/cat3.png", key:"3",parent:"1"}, {name: "Jellylorum", "source":"img/cat4.png", key:"4",parent:"3"}, {name: "Alonzo", "source":"img/cat5.png", key:"5",parent:"3"}, {name: "Munkustrap", "source":"img/cat6.png", key:"6",parent:"2"}, ]; myDiagram.model = Mymodel </script>
-
顯示效果:
6.自定義:
-
js版本:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Flowchart</title> <meta name="description" content="Interactive flowchart diagram implemented by GoJS in JavaScript for HTML."/> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- Copyright 1998-2020 by Northwoods Software Corporation. --> <script src="./js/go.js"></script> <link href='https://fonts.googleapis.com/css?family=Lato:300,400,700' rel='stylesheet' type='text/css'> <!--<script src="../assets/js/goSamples.js"></script> <!– this is only for the GoJS Samples framework –>--> <script id="code"> function init() { // 初始化示例 // if (window.goSamples) goSamples(); // init for these samples -- you don't need to call this // make構建模板 var $ = go.GraphObject.make; // for conciseness in defining templates myDiagram = $(go.Diagram, document.getElementById("myDiagramDiv"), // must name or refer to the DIV HTML element { // 每次畫線後調用的事件:爲條件連線加上標籤 "LinkDrawn": showLinkLabel, // this DiagramEvent listener is defined below // 每次重畫線後調用的事件 "LinkRelinked": showLinkLabel, // 啓用Ctrl-Z和Ctrl-Y撤銷重作功能 "undoManager.isEnabled": true, // enable undo & redo // 居中顯示內容 initialContentAlignment: go.Spot.Center, // 是否容許從Palette面板拖入元素 allowDrop: true, }); // 當圖有改動時,在頁面標題後加*,且啓動保存按鈕 myDiagram.addDiagramListener("Modified", function (e) { var button = document.getElementById("SaveButton"); if (button) button.disabled = !myDiagram.isModified; var idx = document.title.indexOf("*"); if (myDiagram.isModified) { if (idx < 0) document.title += "*"; } else { if (idx >= 0) document.title = document.title.substr(0, idx); } }); // 設置節點位置風格,並與模型"loc"屬性綁定,該方法會在初始化各類節點模板時使用 function nodeStyle() { return [ // 將節點位置信息 Node.location 同節點模型數據中 "loc" 屬性綁定: // 節點位置信息從 節點模型 "loc" 屬性獲取, 並由靜態方法 Point.parse 解析. // 若是節點位置改變了, 會自動更新節點模型中"loc"屬性, 並由 Point.stringify 方法轉化爲字符串 new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify), { // 節點位置 Node.location 定位在節點的中心 locationSpot: go.Spot.Center } ]; } // 建立"port"方法,"port"是一個透明的長方形細長圖塊,在每一個節點的四個邊界上,若是鼠標移到節點某個邊界上,它會高亮 // "name": "port" ID,即GraphObject.portId, // "align": 決定"port" 屬於節點4條邊的哪條 // "spot": 控制連線連入/連出的位置,如go.Spot.Top指, go.Spot.TopSide // "output" / "input": 布爾型,指定是否容許連線今後"port"連入或連出 function makePort(name, align, spot, output, input) { // 表示若是是上,下,邊界則是水平的"port" var horizontal = align.equals(go.Spot.Top) || align.equals(go.Spot.Bottom); return $(go.Shape, { fill: "transparent", // 默認透明不現實 strokeWidth: 0, // 無邊框 width: horizontal ? NaN : 8, // 垂直"port"則8像素寬 height: !horizontal ? NaN : 8, // 水平"port"則8像素 alignment: align, // 同其節點對齊 stretch: (horizontal ? go.GraphObject.Horizontal : go.GraphObject.Vertical),//自動同其節點一同伸縮 portId: name, // 聲明ID fromSpot: spot, // 聲明連線頭連出此"port"的位置 fromLinkable: output, // 布爾型,是否容許連線今後"port"連出 toSpot: spot, // 聲明連線尾連入此"port"的位置 toLinkable: input, // 布爾型,是否容許連線今後"port"連出 cursor: "pointer", // 鼠標由指針改成手指,表示此處可點擊生成連線 mouseEnter: function (e, port) { //鼠標移到"port"位置後,高亮 if (!e.diagram.isReadOnly) port.fill = "rgba(255,0,255,0.5)"; }, mouseLeave: function (e, port) {// 鼠標移出"port"位置後,透明 port.fill = "transparent"; } }); } // 定義圖形上的文字風格 function textStyle() { return { font: "bold 11pt Lato, Helvetica, Arial, sans-serif", stroke: "#F8F8F8" } } // 定義步驟(默認類型)節點的模板 myDiagram.nodeTemplateMap.add("", // the default category $(go.Node, "Table", nodeStyle(), // 步驟節點是一個包含可編輯文字塊的長方形圖塊 $(go.Panel, "Auto", $(go.Shape, "Rectangle", {fill: "#282c34", stroke: "#00A9C9", strokeWidth: 3.5}, new go.Binding("figure", "figure")), $(go.TextBlock, textStyle(), { margin: 8, maxSize: new go.Size(160, NaN), wrap: go.TextBlock.WrapFit,// 尺寸自適應 editable: true// 文字可編輯 }, new go.Binding("text").makeTwoWay())// 雙向綁定模型中"text"屬性 ), // 上、左、右能夠入,左、右、下能夠出 // "Top"表示中心,"TopSide"表示上方任一位置,自動選擇 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) )); // 定義條件節點的模板 myDiagram.nodeTemplateMap.add("Conditional", $(go.Node, "Table", nodeStyle(), // 條件節點是一個包含可編輯文字塊的菱形圖塊 $(go.Panel, "Auto", $(go.Shape, "Diamond", {fill: "#282c34", stroke: "#00A9C9", strokeWidth: 3.5}, new go.Binding("figure", "figure")), $(go.TextBlock, textStyle(), { margin: 8, maxSize: new go.Size(160, NaN), wrap: go.TextBlock.WrapFit, editable: true }, new go.Binding("text").makeTwoWay()) ), // 上、左、右能夠入,左、右、下能夠出 makePort("T", go.Spot.Top, go.Spot.Top, false, 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, false) )); // 定義開始節點的模板 myDiagram.nodeTemplateMap.add("Start", $(go.Node, "Table", nodeStyle(), $(go.Panel, "Spot", $(go.Shape, "Circle", {desiredSize: new go.Size(70, 70), fill: "#282c34", stroke: "#09d3ac", strokeWidth: 3.5}), $(go.TextBlock, "Start", textStyle(), new go.Binding("text")) ), // 左、右、下能夠出,但都不可入 makePort("L", go.Spot.Left, go.Spot.Left, true, false), makePort("R", go.Spot.Right, go.Spot.Right, true, false), makePort("B", go.Spot.Bottom, go.Spot.Bottom, true, false) )); // 定義結束節點的模板 myDiagram.nodeTemplateMap.add("End", $(go.Node, "Table", nodeStyle(), // 結束節點是一個圓形圖塊,文字不可編輯 $(go.Panel, "Spot", $(go.Shape, "Circle", {desiredSize: new go.Size(60, 60), fill: "#282c34", stroke: "#DC3C00", strokeWidth: 3.5}), $(go.TextBlock, "End", textStyle(), new go.Binding("text")) ), // 上、左、右能夠入,但都不可出 makePort("T", go.Spot.Top, go.Spot.Top, false, true), makePort("L", go.Spot.Left, go.Spot.Left, false, true), makePort("R", go.Spot.Right, go.Spot.Right, 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, .75 * w, 0)); fig.add(new go.PathSegment(go.PathSegment.Line, w, .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(.75 * w, 0, false); geo.add(fig2); // The Fold fig2.add(new go.PathSegment(go.PathSegment.Line, .75 * w, .25 * h)); fig2.add(new go.PathSegment(go.PathSegment.Line, w, .25 * h)); geo.spot1 = new go.Spot(0, .25); geo.spot2 = go.Spot.BottomRight; return geo; }); // 定義註釋節點的模板 myDiagram.nodeTemplateMap.add("Comment", // 註釋節點是一個包含可編輯文字塊的文件圖塊 $(go.Node, "Auto", nodeStyle(), $(go.Shape, "File", {fill: "#282c34", stroke: "#DEE0A3", strokeWidth: 3}), $(go.TextBlock, textStyle(), { margin: 8, maxSize: new go.Size(200, NaN), wrap: go.TextBlock.WrapFit,// 尺寸自適應 textAlign: "center", editable: true// 文字可編輯 }, new go.Binding("text").makeTwoWay()) // 不支持連線入和出 )); // 初始化鏈接線的模板 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(), // 雙向綁定模型中"points"數組屬性 $(go.Shape, // 隱藏的連線形狀,8個像素粗細,當鼠標移上後顯示 {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(),// 雙向綁定模型中"visible"屬性 $(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()) // 雙向綁定模型中"text"屬性 ) ); // 此事件方法由整個畫板的LinkDrawn和LinkRelinked事件觸發 // 若是連線是從"conditional"條件節點出發,則將連線上的標籤顯示出來 function showLinkLabel(e) { var label = e.subject.findObject("LABEL"); if (label !== null) label.visible = (e.subject.fromNode.data.category === "Conditional"); } // 臨時的連線(還在畫圖中),包括重連的連線,都保持直角 myDiagram.toolManager.linkingTool.temporaryLink.routing = go.Link.Orthogonal; myDiagram.toolManager.relinkingTool.temporaryLink.routing = go.Link.Orthogonal; load(); // load an initial diagram from some JSON text // 在圖形頁面的左邊初始化圖例Palette面板 myPalette = $(go.Palette, "myPaletteDiv", // 必須同HTML中Div元素id一致 { // Instead of the default animation, use a custom fade-down "animationManager.initialAnimationStyle": go.AnimationManager.None, "InitialAnimationStarting": animateFadeDown, // 使用此函數設置動畫 nodeTemplateMap: myDiagram.nodeTemplateMap, // 同myDiagram公用一種node節點模板 model: new go.GraphLinksModel([ // 初始化Palette面板裏的內容 {category: "Start", text: "Start"}, {text: "Step"}, {category: "Conditional", text: "???"}, {category: "End", text: "End"}, {category: "Comment", text: "Comment"} ]) }); // 動畫效果 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(); } } // end init // 將go模型以JSon格式保存在文本框內 function save() { document.getElementById("mySavedModel").value = myDiagram.model.toJson(); myDiagram.isModified = false; } // 初始化模型範例 function load() { myDiagram.model = go.Model.fromJson(document.getElementById("mySavedModel").value); } // 在新窗口中將圖形轉化爲SVG,並分頁打印 function printDiagram() { var svgWindow = window.open(); if (!svgWindow) return; // failure to open a new Window var printSize = new go.Size(700, 960); var bnds = myDiagram.documentBounds; var x = bnds.x; var y = bnds.y; while (y < bnds.bottom) { while (x < bnds.right) { var svg = myDiagram.makeSVG({scale: 1.0, position: new go.Point(x, y), size: printSize}); svgWindow.document.body.appendChild(svg); x += printSize.width; } x = bnds.x; y += printSize.height; } setTimeout(function () { svgWindow.print(); }, 1); } </script> </head> <body onload="init()"> <div id="sample"> <div style="width: 100%; display: flex; justify-content: space-between"> <div id="myPaletteDiv" style="width: 100px; margin-right: 2px; background-color: #282c34;"></div> <div id="myDiagramDiv" style="flex-grow: 1; height: 750px; background-color: #282c34;"></div> </div> <button id="SaveButton" onclick="save()">Save</button> <button onclick="load()">Load</button> Diagram Model saved in JSON format: <textarea id="mySavedModel" style="width:100%;height:300px"> { "class": "go.GraphLinksModel", "linkFromPortIdProperty": "fromPort", "linkToPortIdProperty": "toPort", "nodeDataArray": [ ], "linkDataArray": [ ]} </textarea> <button onclick="printDiagram()">Print Diagram Using SVG</button> </div> </body> </html>
-
vue版
<template> <el-card> <my-bread level1='拓撲圖' level2='拓撲圖繪製'></my-bread> <div id='sample'> <div style='width: 100%; display: flex; justify-content: space-between'> <div ref='myPaletteDiv' style='width: 100px; margin-right: 2px; background-color: #282c34;'></div> <div ref='myDiagramDiv' style='flex-grow: 1; height: 750px; background-color: #282c34;'></div> </div> <button id='SaveButton' @click='save()'>Save</button> <button @click='load()'>Load</button> Diagram Model saved in JSON format: <textarea ref='mySavedModel' style='width:100%;height:300px'> {{this.diagramData}} </textarea> <button @click='printDiagram()'>Print Diagram Using SVG</button> </div> </el-card> <!-- <button @click='init()'></button>--> </template> <script> import go from 'gojs' let $ = go.GraphObject.make export default { data () { return { diagramData : { 'class': 'go.GraphLinksModel', 'linkFromPortIdProperty': 'fromPort', 'linkToPortIdProperty': 'toPort', 'nodeDataArray': [ ], 'linkDataArray': [ ]}, myDiagram: null, myPalette: null } }, mounted () { this.myDiagram = $(go.Diagram, this.$refs.myDiagramDiv, { // 每次畫線後調用的事件:爲條件連線加上標籤 'LinkDrawn': this.showLinkLabel, // 每次重畫線後調用的事件 'LinkRelinked': this.showLinkLabel, // 啓用Ctrl-Z和Ctrl-Y撤銷重作功能 'undoManager.isEnabled': true, // 居中顯示內容 initialContentAlignment: go.Spot.Center, // 是否容許從Palette面板拖入元素 allowDrop: true, }) // console.log(this.$refs.SaveButton) // 當圖有改動時,在頁面標題後加*,且啓動保存按鈕 // this.myDiagram.addDiagramListener('Modified', function (e) { // // var button = this.$refs.SaveButton // var button = document.getElementById('SaveButton') // if (button) button.disabled =! this.myDiagram.isModified // var idx = document.title.indexOf('*') // if (this.myDiagram.isModified) { // if (idx < 0) document.title += '*' // } else { // if (idx >= 0) document.title = document.title.substr(0, idx) // } // }) // 定義步驟(默認類型)節點的模板 this.myDiagram.nodeTemplateMap.add('', $(go.Node, 'Table', this.nodeStyle(), // 步驟節點是一個包含可編輯文字塊的長方形圖塊 $(go.Panel, 'Auto', $(go.Shape, 'Rectangle', {fill: '#282c34', stroke: '#00A9C9', strokeWidth: 3.5}, new go.Binding('figure', 'figure')), $(go.TextBlock, this.textStyle(), { margin: 8, maxSize: new go.Size(160, NaN), wrap: go.TextBlock.WrapFit,// 尺寸自適應 editable: true// 文字可編輯 }, new go.Binding('text').makeTwoWay())// 雙向綁定模型中'text'屬性 ), // 上、左、右能夠入,左、右、下能夠出 // 'Top'表示中心,'TopSide'表示上方任一位置,自動選擇 this.makePort('T', go.Spot.Top, go.Spot.TopSide, false, true), this.makePort('L', go.Spot.Left, go.Spot.LeftSide, true, true), this.makePort('R', go.Spot.Right, go.Spot.RightSide, true, true), this.makePort('B', go.Spot.Bottom, go.Spot.BottomSide, true, false) )) // 定義條件節點的模板 this.myDiagram.nodeTemplateMap.add('Conditional', $(go.Node, 'Table', this.nodeStyle(), // 條件節點是一個包含可編輯文字塊的菱形圖塊 $(go.Panel, 'Auto', $(go.Shape, 'Diamond', {fill: '#282c34', stroke: '#00A9C9', strokeWidth: 3.5}, new go.Binding('figure', 'figure')), $(go.TextBlock, this.textStyle(), { margin: 8, maxSize: new go.Size(160, NaN), wrap: go.TextBlock.WrapFit, editable: true }, new go.Binding('text').makeTwoWay()) ), // 上、左、右能夠入,左、右、下能夠出 this.makePort('T', go.Spot.Top, go.Spot.Top, false, true), this.makePort('L', go.Spot.Left, go.Spot.Left, true, true), this.makePort('R', go.Spot.Right, go.Spot.Right, true, true), this.makePort('B', go.Spot.Bottom, go.Spot.Bottom, true, false) )) // 定義開始節點的模板 this.myDiagram.nodeTemplateMap.add('Start', $(go.Node, 'Table', this.nodeStyle(), $(go.Panel, 'Spot', $(go.Shape, 'Circle', {desiredSize: new go.Size(70, 70), fill: '#282c34', stroke: '#09d3ac', strokeWidth: 3.5}), $(go.TextBlock, 'Start', this.textStyle(), new go.Binding('text')) ), // 左、右、下能夠出,但都不可入 this.makePort('L', go.Spot.Left, go.Spot.Left, true, false), this.makePort('R', go.Spot.Right, go.Spot.Right, true, false), this.makePort('B', go.Spot.Bottom, go.Spot.Bottom, true, false) )) // 定義結束節點的模板 this.myDiagram.nodeTemplateMap.add('End', $(go.Node, 'Table', this.nodeStyle(), // 結束節點是一個圓形圖塊,文字不可編輯 $(go.Panel, 'Spot', $(go.Shape, 'Circle', {desiredSize: new go.Size(60, 60), fill: '#282c34', stroke: '#DC3C00', strokeWidth: 3.5}), $(go.TextBlock, 'End', this.textStyle(), new go.Binding('text')) ), // 上、左、右能夠入,但都不可出 this.makePort('T', go.Spot.Top, go.Spot.Top, false, true), this.makePort('L', go.Spot.Left, go.Spot.Left, false, true), this.makePort('R', go.Spot.Right, go.Spot.Right, false, true) )); // taken from 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, .75 * w, 0)); fig.add(new go.PathSegment(go.PathSegment.Line, w, .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(.75 * w, 0, false); geo.add(fig2); // The Fold fig2.add(new go.PathSegment(go.PathSegment.Line, .75 * w, .25 * h)); fig2.add(new go.PathSegment(go.PathSegment.Line, w, .25 * h)); geo.spot1 = new go.Spot(0, .25); geo.spot2 = go.Spot.BottomRight; return geo; }) // 定義註釋節點的模板 this.myDiagram.nodeTemplateMap.add('Comment', // 註釋節點是一個包含可編輯文字塊的文件圖塊 $(go.Node, 'Auto', this.nodeStyle(), $(go.Shape, 'File', {fill: '#282c34', stroke: '#DEE0A3', strokeWidth: 3}), $(go.TextBlock, this.textStyle(), { margin: 8, maxSize: new go.Size(200, NaN), wrap: go.TextBlock.WrapFit,// 尺寸自適應 textAlign: 'center', editable: true// 文字可編輯 }, new go.Binding('text').makeTwoWay()) // 不支持連線入和出 )) // 初始化鏈接線的模板 this.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(), // 雙向綁定模型中'points'數組屬性 $(go.Shape, // 隱藏的連線形狀,8個像素粗細,當鼠標移上後顯示 {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(),// 雙向綁定模型中'visible'屬性 $(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()) // 雙向綁定模型中'text'屬性 ) ); // 臨時的連線(還在畫圖中),包括重連的連線,都保持直角 this.myDiagram.toolManager.linkingTool.temporaryLink.routing = go.Link.Orthogonal; this.myDiagram.toolManager.relinkingTool.temporaryLink.routing = go.Link.Orthogonal; // 讀取json數據 this.load() // 在圖形頁面的左邊初始化圖例Palette面板 this.myPalette = $(go.Palette, this.$refs.myPaletteDiv, // 必須同HTML中Div元素id一致 { // Instead of the default animation, use a custom fade-down 'animationManager.initialAnimationStyle': go.AnimationManager.None, 'InitialAnimationStarting': this.animateFadeDown, // 使用此函數設置動畫 nodeTemplateMap: this.myDiagram.nodeTemplateMap, // 同myDiagram公用一種node節點模板 model: new go.GraphLinksModel([ // 初始化Palette面板裏的內容 {category: 'Start', text: '開始'}, {text: '步驟'}, {category: 'Conditional', text: '選擇'}, {category: 'End', text: '結束'}, {category: 'Comment', text: '標識'} ]) }) }, methods : { showLinkLabel (e) { var label = e.subject.findObject('LABEL') if (label !== null) label.visible = (e.subject.fromNode.data.category === 'Conditional') }, // 設置節點位置風格,並與模型'loc'屬性綁定,該方法會在初始化各類節點模板時使用 nodeStyle () { return [ // 將節點位置信息 Node.location 同節點模型數據中 'loc' 屬性綁定: // 節點位置信息從 節點模型 'loc' 屬性獲取, 並由靜態方法 Point.parse 解析. // 若是節點位置改變了, 會自動更新節點模型中'loc'屬性, 並由 Point.stringify 方法轉化爲字符串 new go.Binding('location', 'loc', go.Point.parse).makeTwoWay(go.Point.stringify), { // 節點位置 Node.location 定位在節點的中心 locationSpot: go.Spot.Center } ] }, // 建立'port'方法,'port'是一個透明的長方形細長圖塊,在每一個節點的四個邊界上,若是鼠標移到節點某個邊界上,它會高亮 // 'name': 'port' ID,即GraphObject.portId, // 'align': 決定'port' 屬於節點4條邊的哪條 // 'spot': 控制連線連入/連出的位置,如go.Spot.Top指, go.Spot.TopSide // 'output' / 'input': 布爾型,指定是否容許連線今後'port'連入或連出 makePort (name, align, spot, output, input) { // 表示若是是上,下,邊界則是水平的'port' var horizontal = align.equals(go.Spot.Top) || align.equals(go.Spot.Bottom); return $(go.Shape, { fill: 'transparent', // 默認透明不現實 strokeWidth: 0, // 無邊框 width: horizontal ? NaN : 8, // 垂直'port'則8像素寬 height: !horizontal ? NaN : 8, // 水平'port'則8像素 alignment: align, // 同其節點對齊 stretch: (horizontal ? go.GraphObject.Horizontal : go.GraphObject.Vertical),//自動同其節點一同伸縮 portId: name, // 聲明ID fromSpot: spot, // 聲明連線頭連出此'port'的位置 fromLinkable: output, // 布爾型,是否容許連線今後'port'連出 toSpot: spot, // 聲明連線尾連入此'port'的位置 toLinkable: input, // 布爾型,是否容許連線今後'port'連出 cursor: 'pointer', // 鼠標由指針改成手指,表示此處可點擊生成連線 mouseEnter: function (e, port) { //鼠標移到'port'位置後,高亮 if (!e.diagram.isReadOnly) port.fill = 'rgba(255,0,255,0.5)'; }, mouseLeave: function (e, port) {// 鼠標移出'port'位置後,透明 port.fill = 'transparent'; } }) }, // 定義圖形上的文字風格 textStyle() { return { font: 'bold 11pt Lato, Helvetica, Arial, sans-serif', stroke: '#F8F8F8' } }, load () { this.myDiagram.model = go.Model.fromJson(this.$refs.mySavedModel.value) // console.log(this.$refs.mySavedModel.value) }, 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(); }, // 初始化模型範例 save () { this.$refs.mySavedModel.value = this.myDiagram.model.toJson() this.myDiagram.isModified = false }, // 在新窗口中將圖形轉化爲SVG,並分頁打印 printDiagram() { var svgWindow = window.open(); if (!svgWindow) return; // failure to open a new Window var printSize = new go.Size(700, 960); var bnds = this.myDiagram.documentBounds; var x = bnds.x; var y = bnds.y; while (y < bnds.bottom) { while (x < bnds.right) { var svg = this.myDiagram.makeSVG({scale: 1.0, position: new go.Point(x, y), size: printSize}); svgWindow.document.body.appendChild(svg); x += printSize.width; } x = bnds.x; y += printSize.height; } setTimeout(function () { svgWindow.print(); }, 1); } } } </script> <style scoped> </style>
-
參考文件: