流程圖控件GoJS教程:鏈接(下)
GoJS是一款功能強(qiáng)大,快速且輕量級(jí)的流程圖控件,可幫助你在JavaScript 和HTML5 Canvas程序中創(chuàng)建流程圖,且極大地簡(jiǎn)化您的JavaScript / Canvas 程序。
GoJS現(xiàn)已更新至最新版本2.0.17發(fā)布,修復(fù)了一些bug,增強(qiáng)用戶(hù)體驗(yàn),趕快下載試試吧~
曲線,彎曲度,轉(zhuǎn)角
一旦Link.routing確定了鏈接采用的路線(即點(diǎn)的順序),其他屬性將控制有關(guān)鏈接形狀如何獲取其路徑幾何的詳細(xì)信息。第一個(gè)這樣的屬性是Link.curve,它控制鏈接形狀是基本上是直線段還是大曲線。
為默認(rèn)值Link.curve是Link,None,產(chǎn)生鏈接的形狀有直線段正如你看到的上面。
Link,Bezier的值會(huì)為鏈接形狀生成自然彎曲的路徑。
diagram.nodeTemplate = $(go.Node, "Auto", new go.Binding("location", "loc", go.Point.parse), $(go.Shape, "RoundedRectangle", { fill: "lightgray" }), $(go.TextBlock, { margin: 5 }, new go.Binding("text", "key")) ); diagram.linkTemplate = $(go.Link, { curve: go.Link.Bezier }, // Bezier curve $(go.Shape), $(go.Shape, { toArrow: "Standard" }) ); var nodeDataArray = [ { key: "Alpha", loc: "0 0" }, { key: "Beta", loc: "100 50" } ]; var linkDataArray = [ { from: "Alpha", to: "Beta" } ]; diagram.model = new go.GraphLinksModel(nodeDataArray, linkDataArray);
您可以通過(guò)設(shè)置Link.curviness屬性來(lái)控制其彎曲程度。默認(rèn)情況下會(huì)產(chǎn)生一條輕微的曲線。
如果有多個(gè)鏈接,除非您明確分配Link.curviness,否則它將自動(dòng)為每個(gè)鏈接的曲線計(jì)算合理的值。
diagram.nodeTemplate = $(go.Node, "Auto", new go.Binding("location", "loc", go.Point.parse), $(go.Shape, "RoundedRectangle", { fill: "lightgray" }), $(go.TextBlock, { margin: 5 }, new go.Binding("text", "key")) ); diagram.linkTemplate = $(go.Link, { curve: go.Link.Bezier }, $(go.Shape), $(go.Shape, { toArrow: "Standard" }) ); var nodeDataArray = [ { key: "Alpha", loc: "0 0" }, { key: "Beta", loc: "100 50" } ]; var linkDataArray = [ { from: "Alpha", to: "Beta" }, // multiple links between the same nodes { from: "Alpha", to: "Beta" }, { from: "Alpha", to: "Beta" }, { from: "Alpha", to: "Beta" } ]; diagram.model = new go.GraphLinksModel(nodeDataArray, linkDataArray);
當(dāng)Link.routing為“正交”或“避免節(jié)點(diǎn)” 時(shí),另一種彎曲來(lái)自圓角。
diagram.nodeTemplate = $(go.Node, "Auto", new go.Binding("location", "loc", go.Point.parse), $(go.Shape, "RoundedRectangle", { fill: "lightgray" }), $(go.TextBlock, { margin: 5 }, new go.Binding("text", "key")) ); diagram.linkTemplate = $(go.Link, { routing: go.Link.AvoidsNodes, corner: 10 }, // rounded corners $(go.Shape), $(go.Shape, { toArrow: "Standard" }) ); var nodeDataArray = [ { key: "Alpha", loc: "0 0" }, { key: "Beta", loc: "250 40" }, { key: "Gamma", loc: "100 0" }, { key: "Delta", loc: "75 50" }, { key: "Epsilon", loc: "150 30" } ]; var linkDataArray = [ { from: "Alpha", to: "Beta" } ]; diagram.model = new go.GraphLinksModel(nodeDataArray, linkDataArray);
另一種彎曲來(lái)自將Link.curve設(shè)置為L(zhǎng)ink,JumpOver。這會(huì)在與另一個(gè)也具有JumpOver曲線的正交鏈接交叉的正交鏈接的路徑中引起很少的“跳躍”。
diagram.nodeTemplate = $(go.Node, "Auto", { locationSpot: go.Spot.Center }, new go.Binding("location", "loc", go.Point.parse), $(go.Shape, "RoundedRectangle", { fill: "lightgray" }), $(go.TextBlock, { margin: 5 }, new go.Binding("text", "key")) ); diagram.linkTemplate = $(go.Link, { routing: go.Link.Orthogonal, // may be either Orthogonal or AvoidsNodes curve: go.Link.JumpOver }, $(go.Shape), $(go.Shape, { toArrow: "Standard" }) ); var nodeDataArray = [ { key: "Alpha", loc: "0 50" }, { key: "Beta", loc: "100 50" }, { key: "Alpha2", loc: "50 0" }, { key: "Beta2", loc: "50 100" } ]; var linkDataArray = [ { from: "Alpha", to: "Beta" }, // these two links will cross { from: "Alpha2", to: "Beta2" } ]; diagram.model = new go.GraphLinksModel(nodeDataArray, linkDataArray);
請(qǐng)注意,鏈接跳躍的使用明顯比普通鏈接慢,因?yàn)楸仨氂?jì)算所有交叉點(diǎn),并且鏈接形狀的幾何形狀將更加復(fù)雜。
另一種彎曲(或?qū)嶋H上缺乏彎曲)來(lái)自將Link.curve設(shè)置為L(zhǎng)ink,JumpGap。這會(huì)在與另一個(gè)也具有JumpGap曲線的正交鏈接交叉的正交鏈接的路徑中引起很小的“間隙”。
diagram.nodeTemplate = $(go.Node, "Auto", { locationSpot: go.Spot.Center }, new go.Binding("location", "loc", go.Point.parse), $(go.Shape, "RoundedRectangle", { fill: "lightgray" }), $(go.TextBlock, { margin: 5 }, new go.Binding("text", "key")) ); diagram.linkTemplate = $(go.Link, { routing: go.Link.Orthogonal, // may be either Orthogonal or AvoidsNodes curve: go.Link.JumpGap }, $(go.Shape), $(go.Shape, { toArrow: "Standard" }) ); var nodeDataArray = [ { key: "Alpha", loc: "0 50" }, { key: "Beta", loc: "100 50" }, { key: "Alpha2", loc: "50 0" }, { key: "Beta2", loc: "50 100" } ]; var linkDataArray = [ { from: "Alpha", to: "Beta" }, // these two links will cross { from: "Alpha2", to: "Beta2" } ]; diagram.model = new go.GraphLinksModel(nodeDataArray, linkDataArray);
輕松點(diǎn)擊鏈接
用戶(hù)可能會(huì)注意到的一個(gè)問(wèn)題是,尤其是在使用手指以及鼠標(biāo)的情況下,單擊具有較薄Link.path的鏈接可能很困難。可以將Shape.strokeWidth設(shè)置為較大的值,例如8,但是您可能不希望這種外觀。
diagram.nodeTemplate = $(go.Node, "Auto", new go.Binding("location", "loc", go.Point.parse), $(go.Shape, "RoundedRectangle", { fill: "lightgray" }), $(go.TextBlock, { margin: 5 }, new go.Binding("text", "key")) ); diagram.linkTemplate = $(go.Link, $(go.Shape, { strokeWidth: 8 }), // thick path $(go.Shape, { toArrow: "Standard" }) ); var nodeDataArray = [ { key: "Alpha", loc: "0 0" }, { key: "Beta", loc: "100 50" } ]; var linkDataArray = [ { from: "Alpha", to: "Beta" } ]; diagram.model = new go.GraphLinksModel(nodeDataArray, linkDataArray);
解決方案是添加粗路徑Shape,但不繪制任何東西。設(shè)置即可輕松完成{ stroke: "transparent", strokeWidth: 8 }。但是,如果要保留原始路徑Shape,則需要通過(guò)將GraphObject.isPanelMain設(shè)置為true ,將兩個(gè) Shape 都聲明為L(zhǎng)ink的“主要”元素。“鏈接”面板知道所有此類(lèi)形狀都應(yīng)為鏈接路徑獲得相同的計(jì)算幾何形狀。
diagram.nodeTemplate = $(go.Node, "Auto", new go.Binding("location", "loc", go.Point.parse), $(go.Shape, "RoundedRectangle", { fill: "lightgray" }), $(go.TextBlock, { margin: 5 }, new go.Binding("text", "key")) ); diagram.linkTemplate = $(go.Link, $(go.Shape, { isPanelMain: true, stroke: "transparent", strokeWidth: 8 }), // thick undrawn path $(go.Shape, { isPanelMain: true }), // default stroke === "black", strokeWidth === 1 $(go.Shape, { toArrow: "Standard" }) ); var nodeDataArray = [ { key: "Alpha", loc: "0 0" }, { key: "Beta", loc: "100 50" } ]; var linkDataArray = [ { from: "Alpha", to: "Beta" } ]; diagram.model = new go.GraphLinksModel(nodeDataArray, linkDataArray);
在此示例中,您將發(fā)現(xiàn)選擇鏈接比沒(méi)有第二個(gè)透明鏈接路徑形狀更容易。
透明形狀也可以用于突出顯示目的。例如,要實(shí)現(xiàn)在鼠標(biāo)經(jīng)過(guò)鏈接時(shí)突出顯示鏈接的效果,請(qǐng)?zhí)砑覩raphObject.mouseEnter和GraphObject.mouseLeave事件處理程序:
diagram.nodeTemplate = $(go.Node, "Auto", new go.Binding("location", "loc", go.Point.parse), $(go.Shape, "RoundedRectangle", { fill: "lightgray" }), $(go.TextBlock, { margin: 5 }, new go.Binding("text", "key")) ); diagram.linkTemplate = $(go.Link, $(go.Shape, { isPanelMain: true, stroke: "transparent", strokeWidth: 8 }), // thick undrawn path $(go.Shape, { isPanelMain: true }), // default stroke === "black", strokeWidth === 1 $(go.Shape, { toArrow: "Standard" }), { // a mouse-over highlights the link by changing the first main path shape's stroke: mouseEnter: function(e, link) { link.elt(0).stroke = "rgba(0,90,156,0.3)"; }, mouseLeave: function(e, link) { link.elt(0).stroke = "transparent"; } } ); var nodeDataArray = [ { key: "Alpha", loc: "0 0" }, { key: "Beta", loc: "100 50" } ]; var linkDataArray = [ { from: "Alpha", to: "Beta" } ]; diagram.model = new go.GraphLinksModel(nodeDataArray, linkDataArray);
將鼠標(biāo)移到鏈接上可以查看效果。這樣的反饋還有助于用戶(hù)單擊或上下文單擊鏈接。
短長(zhǎng)度
請(qǐng)注意,在上面的示例中,黑色路徑形狀較粗,箭頭似乎由于鏈接路徑的厚度而消失了??梢酝ㄟ^(guò)將箭頭的GraphObject.scale增加到2來(lái)避免該問(wèn)題。
diagram.nodeTemplate = $(go.Node, "Auto", new go.Binding("location", "loc", go.Point.parse), $(go.Shape, "RoundedRectangle", { fill: "lightgray" }), $(go.TextBlock, { margin: 5 }, new go.Binding("text", "key")) ); diagram.linkTemplate = $(go.Link, $(go.Shape, { strokeWidth: 8 }), // thick path $(go.Shape, { toArrow: "Standard", scale: 2 }) // bigger arrowhead ); var nodeDataArray = [ { key: "Alpha", loc: "0 0" }, { key: "Beta", loc: "100 50" } ]; var linkDataArray = [ { from: "Alpha", to: "Beta" } ]; diagram.model = new go.GraphLinksModel(nodeDataArray, linkDataArray);
現(xiàn)在箭頭清晰可見(jiàn)。但是,這又表明箭頭在鏈接路徑的最末端仍然被遮蓋,因?yàn)樗珜挾鵁o(wú)法顯示箭頭的點(diǎn)。通過(guò)將Link.toShortLength設(shè)置為諸如8的值(取決于所用箭頭的類(lèi)型)可以避免該問(wèn)題。路徑幾何形狀將縮短該距離,以使鏈接路徑不會(huì)干擾箭頭。
diagram.nodeTemplate = $(go.Node, "Auto", new go.Binding("location", "loc", go.Point.parse), $(go.Shape, "RoundedRectangle", { fill: "lightgray" }), $(go.TextBlock, { margin: 5 }, new go.Binding("text", "key")) ); diagram.linkTemplate = $(go.Link, { toShortLength: 8 }, // shortens path to avoid interfering with arrowhead $(go.Shape, { strokeWidth: 8 }), // thick path $(go.Shape, { toArrow: "Standard", scale: 2 }) // bigger arrowhead ); var nodeDataArray = [ { key: "Alpha", loc: "0 0" }, { key: "Beta", loc: "100 50" } ]; var linkDataArray = [ { from: "Alpha", to: "Beta" } ]; diagram.model = new go.GraphLinksModel(nodeDataArray, linkDataArray);
還有一個(gè)Link.fromShortLength屬性,用于控制繪制鏈接路徑的“ from”端的距離。如果存在一個(gè)結(jié)束段,則可以縮短的距離限于相應(yīng)的 Link.toEndSegmentLength或Link.fromEndSegmentLength。還要注意,短長(zhǎng)度可能為負(fù),這會(huì)導(dǎo)致鏈接路徑被拉長(zhǎng)-進(jìn)入鏈接所連接的端口。
斷開(kāi)鏈接
通常的期望是,除非將兩個(gè)節(jié)點(diǎn)連接在一起,否則就無(wú)法建立鏈接關(guān)系。但是,GoJS確實(shí)支持創(chuàng)建和操作具有null值的Link.fromNode和Link.toNode屬性之一或全部的鏈接。Draggable Link示例演示了這一點(diǎn)。
鏈路的兩端必須連接到節(jié)點(diǎn),以便標(biāo)準(zhǔn)鏈路路由能夠運(yùn)行。如果鏈接不知道從哪里開(kāi)始或在哪里結(jié)束,則不能計(jì)算該鏈接的路線或位置。但是,可以通過(guò)將Link.points設(shè)置或綁定到兩個(gè)或多個(gè)Points的列表來(lái)提供路線。這將自動(dòng)為鏈接指定位置,以便可以在圖中看到它。
鏈接工具LinkingTool和RelinkingTool通常不允許創(chuàng)建或重新連接以“ nothing”連接的鏈接。但是,您可以將LinkingBaseTool.isUnconnectedLinkValid設(shè)置為true以允許用戶(hù)這樣做,如Draggable Link示例所示。
除非鏈接是包含連接節(jié)點(diǎn)的集合的一部分,否則通常無(wú)法拖動(dòng)鏈接。但是,您可以將DraggingTool.dragsLink設(shè)置為true,以允許用戶(hù)拖動(dòng)單獨(dú)的Link。此模式允許用戶(hù)通過(guò)將鏈接拖離其所連接的節(jié)點(diǎn)/端口來(lái)斷開(kāi)鏈接。它還允許用戶(hù)通過(guò)斷開(kāi)鏈接來(lái)重新連接鏈接的一端或兩端,以使該端位于有效端口上。Draggable Link示例也證明了這一點(diǎn)。
=====================================================
想要購(gòu)買(mǎi)GoJS正版授權(quán)的朋友可以咨詢(xún)慧都官方客服。
更多精彩內(nèi)容,歡迎關(guān)注下方的微信公眾號(hào),及時(shí)獲取產(chǎn)品最新資訊▼▼▼