流程圖控件GoJS教程:使用Shape類繪制幾何圖形
GoJS是一款功能強(qiáng)大,快速且輕量級的流程圖控件,可幫助你在JavaScript 和HTML5 Canvas程序中創(chuàng)建流程圖,且極大地簡化您的JavaScript / Canvas 程序。
使用Shape類繪制幾何圖形。您可以控制繪制的形狀以及如何描邊和填充。
形狀,如TextBlock和Picture,是“原子”對象 - 它們不能包含任何其他對象。因此,Shape永遠(yuǎn)不會繪制一些文本或圖像。
在這些簡單的演示中,代碼以編程方式創(chuàng)建一個Part并將其添加到Diagram中。了解模型和數(shù)據(jù)綁定后,通常不會以編程方式創(chuàng)建部件(節(jié)點(diǎn)或鏈接)。
數(shù)據(jù)
您可以將Shape.figure屬性設(shè)置為常用的形狀類型。使用GraphObject.make時,可以將圖形名稱作為字符串參數(shù)傳遞。您可能還需要設(shè)置GraphObject.desiredSize或GraphObject.width和GraphObject.height屬性,盡管通常由Panel確定形狀所在的大小。
以下是幾種最常用的Shape數(shù)據(jù):
diagram.add( $(go.Part, "Horizontal", $(go.Shape, "Rectangle", { width: 40, height: 60, margin: 4, fill: null }), $(go.Shape, "RoundedRectangle", { width: 40, height: 60, margin: 4, fill: null }), $(go.Shape, "Ellipse", { width: 40, height: 60, margin: 4, fill: null }), $(go.Shape, "Diamond", { width: 40, height: 60, margin: 4, fill: null }), $(go.Shape, "TriangleRight", { width: 40, height: 60, margin: 4, fill: null }), $(go.Shape, "TriangleDown", { width: 40, height: 60, margin: 4, fill: null }), $(go.Shape, "TriangleLeft", { width: 40, height: 60, margin: 4, fill: null }), $(go.Shape, "TriangleUp", { width: 40, height: 60, margin: 4, fill: null }), $(go.Shape, "MinusLine", { width: 40, height: 60, margin: 4, fill: null }), $(go.Shape, "PlusLine", { width: 40, height: 60, margin: 4, fill: null }), $(go.Shape, "XLine", { width: 40, height: 60, margin: 4, fill: null }) ));
您可以在形狀樣本中看到所有已命名的幾何圖形 。一些最常用的數(shù)字是在GoJS庫中預(yù)定義的。但是大多數(shù)數(shù)字都在extensions目錄的Figures.js文件中定義。
填充和描邊
該Shape.stroke屬性指定用于繪制圖形的輪廓刷。該Shape.fill屬性指定用于填充形狀的輪廓刷。額外的“筆劃...”屬性還控制繪制形狀輪廓的方式。最常見的此類屬性是Shape.strokeWidth。
diagram.add( $(go.Part, "Horizontal", $(go.Shape, { figure: "Club", width: 40, height: 40, margin: 4 }), // default fill and stroke are "black" $(go.Shape, { figure: "Club", width: 40, height: 40, margin: 4, fill: "green" }), $(go.Shape, { figure: "Club", width: 40, height: 40, margin: 4, fill: "green", stroke: null }), $(go.Shape, { figure: "Club", width: 40, height: 40, margin: 4, fill: null, stroke: "green" }), $(go.Shape, { figure: "Club", width: 40, height: 40, margin: 4, fill: null, stroke: "green", strokeWidth: 3 }), $(go.Shape, { figure: "Club", width: 40, height: 40, margin: 4, fill: null, stroke: "green", strokeWidth: 6 }), $(go.Shape, { figure: "Club", width: 40, height: 40, margin: 4, fill: "green", background: "orange" }) ));
該Shape.stroke和Shape.fill性質(zhì)采取刷ES但大多數(shù)情況下都獲得了CSS顏色字符串來表示純色畫筆。這兩個屬性默認(rèn)為純黑色畫筆。但是,將它們中的一個指定為null或“透明”是很常見的??账⒆颖硎緵]有為該筆劃或填充繪制任何內(nèi)容。透明刷子產(chǎn)生相同的外觀但不同的擊中測試行為。具有null Shape.fill的形狀會產(chǎn)生“空心”形狀 - 在形狀內(nèi)部單擊將不會“擊中”該形狀,因此不會選擇該形狀所在的節(jié)點(diǎn)。但是具有透明填充的形狀會產(chǎn)生“填充” “形狀 - 形狀內(nèi)的鼠標(biāo)事件將”擊中“
diagram.div.style.background = "lightgray"; diagram.add( $(go.Part, "Table", $(go.Shape, { row: 0, column: 0, figure: "Club", width: 60, height: 60, margin: 4, fill: "green" }), $(go.TextBlock, "green", { row: 1, column: 0 }), $(go.Shape, { row: 0, column: 1, figure: "Club", width: 60, height: 60, margin: 4, fill: "white" }), $(go.TextBlock, "white", { row: 1, column: 1 }), $(go.Shape, { row: 0, column: 2, figure: "Club", width: 60, height: 60, margin: 4, fill: "transparent" }), $(go.TextBlock, "transparent", { row: 1, column: 2 }), $(go.Shape, { row: 0, column: 3, figure: "Club", width: 60, height: 60, margin: 4, fill: null }), $(go.TextBlock, "null", { row: 1, column: 3 }) ));
嘗試在每個形狀內(nèi)單擊以查看哪些形狀將響應(yīng)單擊并導(dǎo)致選擇整個面板。請注意,使用“透明”填充,您可以看到圖表背景,但是當(dāng)您單擊它時,您會“點(diǎn)擊”形狀。只有最后一個,填充為空,才真正“空洞”。單擊最后一個形狀只會導(dǎo)致圖表背景上的單擊,除非您單擊筆劃輪廓。
幾何
每個Shape都從它使用的Geometry中獲得“形狀” 。幾何圖形只是一個保存的描述,說明如何在給定一組點(diǎn)的情況下繪制一些線條。設(shè)置Shape.figure使用可以參數(shù)化的命名預(yù)定義幾何。通常,給Shape一個Geometry而不是給它一個數(shù)字是最有效的。
如果你想要一些與GoJS中所有預(yù)定義圖形不同的東西,你可以構(gòu)建自己的幾何圖形并設(shè)置Shape.geometry。構(gòu)建自己的幾何體的一種方法是構(gòu)建由PathSegment組成的PathFigure。在構(gòu)建基于某些數(shù)據(jù)計(jì)算點(diǎn)的幾何時,通常需要這樣做。
但是,創(chuàng)建常量幾何的更簡單方法是調(diào)用Geometry.parse來讀取具有幾何定義路徑表達(dá)式的字符串,或者將Shape.geometryString設(shè)置為這樣的字符串。這些表達(dá)式具有移動假想“筆”的命令。幾何路徑的語法記錄在“ 幾何路徑字符串”頁面中。
此示例創(chuàng)建一個看起來像字母“W”的Geometry,并在具有不同筆觸特征的多個Shape對象中使用它。幾何對象可以由多個形狀共享。請注意,可能不需要指定GraphObject.desiredSize或GraphObject.width和GraphObject.height,因?yàn)镚eometry定義了自己的大小。如果設(shè)置了大小或由包含Panel強(qiáng)加,則有效幾何由Shape.geometryStretch屬性確定。根據(jù)geometryStretch屬性的值,這可能會導(dǎo)致額外的空白空間或剪裁形狀。
var W_geometry = go.Geometry.parse("M 0,0 L 10,50 20,10 30,50 40,0", false); diagram.add( $(go.Part, "Horizontal", $(go.Shape, { geometry: W_geometry, strokeWidth: 2 }), $(go.Shape, { geometry: W_geometry, stroke: "blue", strokeWidth: 10, strokeJoin: "miter", strokeCap: "butt" }), $(go.Shape, { geometry: W_geometry, stroke: "blue", strokeWidth: 10, strokeJoin: "miter", strokeCap: "round" }), $(go.Shape, { geometry: W_geometry, stroke: "blue", strokeWidth: 10, strokeJoin: "miter", strokeCap: "square" }), $(go.Shape, { geometry: W_geometry, stroke: "green", strokeWidth: 10, strokeJoin: "bevel", strokeCap: "butt" }), $(go.Shape, { geometry: W_geometry, stroke: "green", strokeWidth: 10, strokeJoin: "bevel", strokeCap: "round" }), $(go.Shape, { geometry: W_geometry, stroke: "green", strokeWidth: 10, strokeJoin: "bevel", strokeCap: "square" }), $(go.Shape, { geometry: W_geometry, stroke: "red", strokeWidth: 10, strokeJoin: "round", strokeCap: "butt" }), $(go.Shape, { geometry: W_geometry, stroke: "red", strokeWidth: 10, strokeJoin: "round", strokeCap: "round" }), $(go.Shape, { geometry: W_geometry, stroke: "red", strokeWidth: 10, strokeJoin: "round", strokeCap: "square" }), $(go.Shape, { geometry: W_geometry, stroke: "purple", strokeWidth: 2, strokeDashArray: [4, 2] }), $(go.Shape, { geometry: W_geometry, stroke: "purple", strokeWidth: 2, strokeDashArray: [6, 6, 2, 2] }) ));
角度和比例
除了設(shè)置GraphObject.desiredSize或GraphObject.width和GraphObject.height以聲明Shape的大小外,還可以設(shè)置其他屬性以影響外觀。例如,您可以設(shè)置GraphObject.angle和GraphObject.scale屬性。
diagram.add( $(go.Part, "Table", $(go.Shape, { row: 0, column: 1, figure: "Club", fill: "green", width: 40, height: 40, }), // default angle is zero; default scale is one $(go.Shape, { row: 0, column: 2, figure: "Club", fill: "green", width: 40, height: 40, angle: 30 }), $(go.Shape, { row: 0, column: 3, figure: "Club", fill: "green", width: 40, height: 40, scale: 1.5 }), $(go.Shape, { row: 0, column: 4, figure: "Club", fill: "green", width: 40, height: 40, angle: 30, scale: 1.5 }) ));
該Shape.fill和GraphObject.background刷規(guī)模,并與形狀一起轉(zhuǎn)動。所述GraphObject.areaBackground繪制在含面板的坐標(biāo),所以它不會受該對象的標(biāo)度或角度。
以下兩個形狀各自使用三個單獨(dú)的線性漸變畫筆,三個屬性各一個。請注意左側(cè)未旋轉(zhuǎn)的形狀。由于其GraphObject.background畫筆是不透明的,因此您無法看到填充其后面相同區(qū)域的GraphObject.areaBackground畫筆。
var bluered = $(go.Brush, "Linear", { 0.0: "blue", 1.0: "red" }); var yellowgreen = $(go.Brush, "Linear", { 0.0: "yellow", 1.0: "green" }); var grays = $(go.Brush, "Linear", { 0.0: "black", 1.0: "lightgray" }); diagram.add( $(go.Part, "Table", $(go.Shape, { row: 0, column: 0, figure: "Club", width: 40, height: 40, angle: 0, scale: 1.5, fill: bluered, background: yellowgreen, areaBackground: grays }), $(go.Shape, { row: 0, column: 1, width: 10, fill: null, stroke: null }), $(go.Shape, { row: 0, column: 2, figure: "Club", width: 40, height: 40, angle: 45, scale: 1.5, fill: bluered, background: yellowgreen, areaBackground: grays }) ));
自定義數(shù)字
如上所示,只需設(shè)置Shape.geometry或Shape.geometryString即可輕松創(chuàng)建自定義形狀。導(dǎo)入SVG時這非常方便。但是,也可以定義其他命名圖形,當(dāng)您希望通過設(shè)置或數(shù)據(jù)綁定Shape.figure屬性來輕松指定或更改現(xiàn)有Shape的幾何圖形時,這很方便。
靜態(tài)函數(shù)Shape.defineFigureGenerator可用于定義新的圖形名稱。第二個參數(shù)是一個函數(shù),它使用Shape和預(yù)期的寬度和高度調(diào)用,以生成并返回幾何。這允許基于Shape的屬性和預(yù)期大小來參數(shù)化幾何。特別是,除了寬度和高度之外,還可以在生成Geometry時考慮Shape.parameter1和Shape.parameter2屬性。為了有效,生成的幾何邊界必須等于或小于提供的寬度和高度。
go.Shape.defineFigureGenerator("RoundedTopRectangle", function(shape, w, h) { // this figure takes one parameter, the size of the corner var p1 = 5; // default corner size if (shape !== null) { var param1 = shape.parameter1; if (!isNaN(param1) && param1 >= 0) p1 = param1; // can't be negative or NaN } p1 = Math.min(p1, w / 2); p1 = Math.min(p1, h / 2); // limit by whole height or by half height? var geo = new go.Geometry(); // a single figure consisting of straight lines and quarter-circle arcs geo.add(new go.PathFigure(0, p1) .add(new go.PathSegment(go.PathSegment.Arc, 180, 90, p1, p1, p1, p1)) .add(new go.PathSegment(go.PathSegment.Line, w - p1, 0)) .add(new go.PathSegment(go.PathSegment.Arc, 270, 90, w - p1, p1, p1, p1)) .add(new go.PathSegment(go.PathSegment.Line, w, h)) .add(new go.PathSegment(go.PathSegment.Line, 0, h).close())); // don't intersect with two top corners when used in an "Auto" Panel geo.spot1 = new go.Spot(0, 0, 0.3 * p1, 0.3 * p1); geo.spot2 = new go.Spot(1, 1, -0.3 * p1, 0); return geo; }); go.Shape.defineFigureGenerator("RoundedBottomRectangle", function(shape, w, h) { // this figure takes one parameter, the size of the corner var p1 = 5; // default corner size if (shape !== null) { var param1 = shape.parameter1; if (!isNaN(param1) && param1 >= 0) p1 = param1; // can't be negative or NaN } p1 = Math.min(p1, w / 2); p1 = Math.min(p1, h / 2); // limit by whole height or by half height? var geo = new go.Geometry(); // a single figure consisting of straight lines and quarter-circle arcs geo.add(new go.PathFigure(0, 0) .add(new go.PathSegment(go.PathSegment.Line, w, 0)) .add(new go.PathSegment(go.PathSegment.Line, w, h - p1)) .add(new go.PathSegment(go.PathSegment.Arc, 0, 90, w - p1, h - p1, p1, p1)) .add(new go.PathSegment(go.PathSegment.Line, p1, h)) .add(new go.PathSegment(go.PathSegment.Arc, 90, 90, p1, h - p1, p1, p1).close())); // don't intersect with two bottom corners when used in an "Auto" Panel geo.spot1 = new go.Spot(0, 0, 0.3 * p1, 0); geo.spot2 = new go.Spot(1, 1, -0.3 * p1, -0.3 * p1); return geo; }); diagram.nodeTemplate = $(go.Part, "Spot", { selectionAdorned: false, // don't show the standard selection handle resizable: true, resizeObjectName: "SHAPE", // user can resize the Shape rotatable: true, rotateObjectName: "SHAPE", // user can rotate the Shape // without rotating the label }, $(go.Shape, { name: "SHAPE", fill: $(go.Brush, "Linear", { 0.0: "white", 1.0: "gray" }), desiredSize: new go.Size(100, 50) }, new go.Binding("figure", "fig"), new go.Binding("parameter1", "p1")), $(go.Panel, "Vertical", $(go.TextBlock, new go.Binding("text", "fig")), $(go.TextBlock, { stroke: "blue" }, new go.Binding("text", "parameter1", function(p1) { return p1; }).ofObject("SHAPE")) ) ); diagram.model = new go.Model([ { fig: "RoundedTopRectangle" }, { fig: "RoundedTopRectangle", p1: 0 }, { fig: "RoundedTopRectangle", p1: 3 }, { fig: "RoundedTopRectangle", p1: 10 }, { fig: "RoundedTopRectangle", p1: 50 }, { fig: "RoundedTopRectangle", p1: 250 }, { fig: "RoundedBottomRectangle" }, { fig: "RoundedBottomRectangle", p1: 0 }, { fig: "RoundedBottomRectangle", p1: 3 }, { fig: "RoundedBottomRectangle", p1: 10 }, { fig: "RoundedBottomRectangle", p1: 50 }, { fig: "RoundedBottomRectangle", p1: 250 } ]);
請注意Shape.parameter1屬性(綁定到“p1”屬性的數(shù)據(jù))如何控制角的舍入程度。每個圖形的定義根據(jù)幾何體的實(shí)際大小限制圓度。您可以通過調(diào)整最后一個形狀的大小來查看效果 - 如果形狀變大,則p1 == 250的形狀上的曲線可能很大。
=====================================================
更多GoJS相關(guān)教程,視頻,資源請點(diǎn)擊此處了解~
想要購買GoJS正版授權(quán)的朋友可以咨詢慧都官方客服。
更多精彩內(nèi)容,敬請關(guān)注下方的微信公眾號,及時獲取產(chǎn)品最新資訊▼▼▼