Shapes

Use the Shape class to paint a geometrical figure. You can control what kind of shape is drawn and how it is stroked and filled.

Figures

You can set the Shape.figure property to commonly named kinds of shapes. When using GraphObject.make, you can pass the figure name as a string argument. You may also need to set the GraphObject.desiredSize or GraphObject.width and GraphObject.height properties, although it is also common to have the size determined by the Panel that the shape is in.

In these simplistic demonstrations, the code programmatically creates a Part and adds it to the Diagram. Once you learn about models and data binding you will generally not create parts (nodes or links) programmatically.

Here are several of the most often used Shape figures:

  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, "Triangle",
                  { width: 40, height: 60, margin: 4, fill: null }),
      $(go.Shape, "Diamond",
                  { width: 40, height: 60, margin: 4, fill: null })
    ));

You can see all of the named geometrical figures in the shapes sample.

Fill and Strokes

The Shape.stroke property specifies the brush used to draw the shape's outline. The Shape.fill property specifies the brush used to fill the shape's outline. Additional "stroke..." properties also control how the shape's outline is drawn. The most common such property 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" })
    ));

The Shape.stroke and Shape.fill properties take Brushes but most often are given a CSS color string to denote solid color brushes. These two properties default to a solid black brush. However it is common to assign one of them to be either null or "transparent". A null brush means that nothing is drawn for that stroke or fill. A transparent brush produces the same appearance but different hit-testing behavior. A shape with a null Shape.fill produces a "hollow" shape -- clicking inside the shape will not "hit" that shape and thus not select the Node that that shape is in. But a shape with a transparent fill produces a "filled" shape -- a mouse event inside the shape will "hit" that shape.

  diagram.add(
    $(go.Part, "Table",
      $(go.Shape, { row: 0, column: 0, figure: "Club", width: 40, height: 40, margin: 4,
                    fill: "green" }),
      $(go.TextBlock, "green", { row: 1, column: 0 }),
      $(go.Shape, { row: 0, column: 1, figure: "Club", width: 40, height: 40, margin: 4,
                    fill: "white" }),
      $(go.TextBlock, "white", { row: 1, column: 1 }),
      $(go.Shape, { row: 0, column: 2, figure: "Club", width: 40, height: 40, margin: 4,
                    fill: "transparent" }),
      $(go.TextBlock, "transparent", { row: 1, column: 2 }),
      $(go.Shape, { row: 0, column: 3, figure: "Club", width: 40, height: 40, margin: 4,
                    fill: null }),
      $(go.TextBlock, "null", { row: 1, column: 3 })
    ));

Try clicking inside each of the shapes to see which ones will respond to the click and cause the whole panel to be selected. Only the last one, with a null fill, is truly "hollow".

Geometry

Every Shape gets its "shape" from the Geometry that it uses. A Geometry is just a saved description of how to draw some lines given a set of points. Setting Shape.figure uses a named predefined geometry.

If you want something different from all of the predefined figures in GoJS, you can construct your own Geometry and set Shape.geometry. One way of building your own Geometry is by building PathFigures consisting of PathSegments. But an easier way to create geometries is by calling Geometry.parse to read a string that has a geometry-defining path expression, or to set Shape.geometryString to such a string. These expressions have commands for moving an imaginary "pen". The syntax for geometry paths is documented in the Geometry Path Strings page.

This example creates a Geometry that looks like the letter "W" and uses it in several Shape objects with different stroke characteristics. Geometry objects may be shared by multiple Shapes. Note that there may be no need to specify the GraphObject.desiredSize or GraphObject.width and GraphObject.height, because the Geometry defines its own sizes. If the size is set or imposed by the containing Panel, the effective geometry is determined by the Shape.geometryStretch property.

  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] })
    ));

Angle and Scale

Besides setting the GraphObject.desiredSize or GraphObject.width and GraphObject.height to declare the size of a Shape, you can also 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 })
    ));

The Shape.fill and GraphObject.background brushes scale and rotate along with the shape. The GraphObject.areaBackground is drawn in the containing panel's coordinates, so it is not affected by the object's scale or angle.

The following shapes each use three separate linear gradient brushes, one for each of the three properties. Note the unrotated shape on the left. Because its GraphObject.background brush is opaque, you cannot see the GraphObject.areaBackground brush that fills the same area behind it.

  diagram.add(
    $(go.Part, "Table",
      $(go.Shape, { row: 0, column: 0,
                    figure: "Club", width: 40, height: 40, angle: 0, scale: 1.5,
                    fill: $(go.Brush, go.Brush.Linear, { 0.0: "blue", 1.0: "red" }),
                    background: $(go.Brush, go.Brush.Linear, { 0.0: "yellow", 1.0: "green" }),
                    areaBackground: $(go.Brush, go.Brush.Linear, { 0.0: "gray", 1.0: "lightgray" }) }),
      $(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: $(go.Brush, go.Brush.Linear, { 0.0: "blue", 1.0: "red" }),
                    background: $(go.Brush, go.Brush.Linear, { 0.0: "yellow", 1.0: "green" }),
                    areaBackground: $(go.Brush, go.Brush.Linear, { 0.0: "black", 1.0: "lightgray" }) })
    ));