GoJS is a powerful, fast and lightweight flowchart control that helps you create flowcharts in JavaScript and HTML5 Canvas applications and greatly simplifies your JavaScript/Canvas applications.
Use the Shape class to draw geometry. You can control the shape you draw and how you stroke and fill.
Shapes, such as TextBlock and Picture, are “atomic” objects – they cannot contain any other objects. Therefore, Shape will never draw some text or images.
In these simple demonstrations, the code programmatically creates a Part and adds it to the Diagram. Once you understand the model and data binding, parts (nodes or links) are usually not created programmatically.
data
You can set the shape. figure property to a common Shape type. With graphobject. make, you can pass the graph name as a string parameter. You may also need to set the graphobject. desiredSize or graphobject. width and graphobject. height properties, although it is usually up to the Panel to determine the size of the shape.
Here are some of the most commonly used Shape data:
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 }) ));Copy the code
You can see all the named geometry in the shape sample. Some of the most commonly used numbers are predefined in the GoJS library. But most numbers are defined in the figures.js file in the Extensions directory.
Fill and Stroke
The shape. stroke property specifies the outline brush to draw the graph. The shape. fill property specifies the outline brush to use to fill the Shape. Extra “strokes…” Property also controls how the shape outline is drawn. The most common such attribute is 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"})));Copy the code
The shape. stroke and shape. fill properties take a brush ES but in most cases get a CSS color string to represent a solid color brush. These two properties default to a solid black brush. However, it is common to specify either null or “transparent” for one of them. An empty brush indicates that nothing has been drawn for the stroke or fill. Transparent brushes produce the same appearance but different hit test behavior. Shapes with NULL shape.fill produce “hollow” shapes – clicking inside the Shape will not “hit” the Shape, so the node on which the Shape is located will not be selected. But shapes with transparent fill produce “fill” shapes – mouse events within the shape will “hit”
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 }) ));Copy the code
Try clicking within each shape to see which shapes will respond to the click and cause the entire panel to be selected. Note that with the “transparent” fill, you can see the chart background, but when you click on it, you “click” the shape. Only the last one, filled with nothing, is truly “empty”. Clicking the last shape will only result in a click on the background of the diagram unless you click the stroke outline.
The geometric
Each Shape gets its “Shape” from the Geometry it uses. The geometry is just a saved description of how to draw some lines given a set of points. Set shape. figure to use parameterized named predefined geometry. In general, it is most effective to give a Shape a Geometry instead of a number.
If you want something different from all the predefined shapes in GoJS, you can build your own geometry and set Shape.geometry. One way to build your own geometry is to build a PathFigure consisting of pathsegments. This is often required when building computation points based on some data.
However, an easier way to create constant Geometry is to call Geometry.parse to read a string with a geometrically defined path expression, or to set Shape.geometryString to such a string. These expressions have commands to move imaginary pens. The geometry path syntax is documented on the Geometry Path String page.
This example creates a Geometry that looks like the letter “W” and uses it in multiple Shape objects with different stroke characteristics. Geometric objects can be shared by multiple shapes. Note that it may not be necessary to specify graphobject. desiredSize or graphobject. width and graphobject. height, because Geometry defines its own size. If the size is set or imposed by an include Panel, the valid geometry is determined by the shape. geometryStretch property. Depending on the value of the geometryStretch property, this can result in additional white space or clipping shapes.
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] }) ));Copy the code
Angle and proportion
In addition to setting graphobject. desiredSize or graphobject. width and graphobject. height to declare the size of your Shape, you can set other properties to affect the appearance. For example, you can set the graphobject. Angle and graphobject. scale properties.
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}));Copy the code
The shape. fill and graphobject. background brush scales and rotates with the Shape. Described GraphObject. AreaBackground drawn in the panel, the coordinates of so it won’t scale by the object or point of view.
The following two shapes use three separate linear gradient brushes, one for each of the three properties. Note the unrotated shape on the left. Due to its GraphObject background brush is not transparent, so you can’t see behind the same area filling GraphObject. AreaBackground brush.
var bluered = $(go.Brush, "Linear"{0.0:"blue"And 1.0:"red" }); var yellowgreen = $(go.Brush, "Linear"{0.0:"yellow"And 1.0:"green" }); var grays = $(go.Brush, "Linear"{0.0:"black"And 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", height: 40, Angle: 45, scale: 1.5, fill: bluered, background: yellowgreen, areaBackground: grays}));Copy the code
Custom numbers
As shown above, custom shapes can be easily created by simply setting Shape.geometry or Shape.geometryString. This is very handy when importing SVG. However, other named shapes can also be defined, which is handy when you want to easily specify or change the geometry of an existing Shape by setting or data-binding the Shape.figure property.
Static function Shape. DefineFigureGenerator name can be used to define the new graphics. The second argument is a function called with Shape and the expected width and height to generate and return geometry. This allows you to parameterize geometry based on the Shape’s attributes and expected size. In particular, the shape.parameter1 and shape.parameter2 attributes can be considered when generating Geometry in addition to width and height. To be effective, the generated geometric boundaries must be equal to or less than the width and height provided.
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"Spot1 = new go.Spot(0, 0, 0.3 * p1, 0.3 * p1); spot1 = new go.Spot(0, 0, 0.3 * p1); Spot2 = new go.Spot(1, 1, -0.3 * p1, 0); 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"Spot1 = new go.Spot(0, 0, 0.3 * p1, 0); Spot2 = new go.Spot(1, 1, -0.3 * p1, -0.3 * p1); 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", {1.0, 0.0: "white", "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 } ]);Copy the code
Note how the Shape.parameter1 property (the data bound to the “P1” property) controls the rounding of angles. The definition of each figure limits roundness to the actual size of the geometry. You can see the effect by resizing the last shape – if the shape is larger, the curve on the shape p1 == 250 May be large.