GoJS Brushes

A Brush holds color information and describes how to draw the inside of a Shape or the stroke of a shape or a TextBlock or the background of any GraphObject.

A Brush must not be modified once it has been assigned to a GraphObject, such as the Shape.fill or TextBlock.stroke or GraphObject.background. However, a Brush may be shared by multiple GraphObjects.

Solid Brushes

The simplest brushes are defined by a single solid color. Because they are so simple, anywhere you want a single-color brush you can subsitute a valid CSS color string.

  diagram.add($(go.Part,
      $(go.Shape, "Circle", {
        fill: $(go.Brush, { color: "palegreen" })
      })
    ));

  diagram.add($(go.Part,
      $(go.Shape, "Circle", {
        fill: "palegreen"
      })
    ));

Many CSS color strings are valid, including named colors, hex values, RGB values, and RGBA values.


  diagram.layout = $(go.GridLayout);

  diagram.add($(go.Part,
      $(go.Shape, "Circle", {
        fill: "#DFAD83"
      })
    ));

  diagram.add($(go.Part,
      $(go.Shape, "Circle", {
        fill: "rgba(0,255,0,.3)" // semi transparent green
      })
    ));

  diagram.add($(go.Part,
      $(go.Shape, "Circle", {
        fill: "rgba(0,255,0,.3)",
        stroke: '#DFBB00',
        strokeWidth: 4,
        background: 'coral'
      })
    ));

Gradient Brushes

Gradient brushes are defined by setting the type and adding a number of color stops to the Brush.


  // constructs a Linear gradient brush
  var brush = new go.Brush(go.Brush.Linear);
  brush.addColorStop(0, "blue");
  brush.addColorStop(1, "red");

To simplify the syntax, you can use go.GraphObject.make (see building objects):


  // constructs the same Brush
  var brush = $(go.Brush, "Linear", { 0.0: "blue", 1.0: "red" });

Some examples follow:


  diagram.add(
    $(go.Part, "Table",
      $(go.Shape, { row: 0, column: 0,
                    figure: "Circle", width: 100, height: 100, margin: 5,
                    // A linear gradient brush from blue to red, going from top to bottom (default)
                    fill: $(go.Brush, "Linear", { 0.0: "blue", 1.0: "red" })
                  }),

      $(go.Shape, { row: 0, column: 1,
                    figure: "Circle", width: 100, height: 100, margin: 5,
                    // A linear gradient brush from blue to red, going from bottom to top
                    // by defining start and end spots
                    fill: $(go.Brush, "Linear", { 0.0: "blue", 1.0: "red", start: go.Spot.Bottom, end: go.Spot.Top })
                  })
    ));

Brushes can have any number of color stops:


  diagram.add(
    $(go.Part, "Table",
      $(go.Shape, { row: 0, column: 0,
                    figure: "Rectangle", width: 100, height: 100, margin: 5,
                    // A rainbow linear gradient brush:
                    fill: $(go.Brush, "Linear", {
                      0.0: "rgba(255, 0, 0, 1)",
                      0.15: "rgba(255, 255, 0, 1)",
                      0.30: "rgba(0, 255, 0, 1)",
                      0.50: "rgba(0, 255, 255, 1)",
                      0.65: "rgba(0, 0, 255, 1)",
                      0.80: "rgba(255, 0, 255, 1)",
                      1: "rgba(255, 0, 0, 1)"
                    })
                  }),

      $(go.Shape, { row: 0, column: 1,
                    figure: "Rectangle", width: 100, height: 100, margin: 5,
                    // A rainbow radial gradient brush:
                    fill: $(go.Brush, "Radial", {
                      0.0: "rgba(255, 0, 0, 1)",
                      0.15: "rgba(255, 255, 0, 1)",
                      0.30: "rgba(0, 255, 0, 1)",
                      0.50: "rgba(0, 255, 255, 1)",
                      0.65: "rgba(0, 0, 255, 1)",
                      0.80: "rgba(255, 0, 255, 1)",
                      1: "rgba(255, 0, 0, 1)"
                    })
                  })
    ));

Radial gradient brushes can be controlled with Brush.startRadius and Brush.endRadius, which default to zero and NaN, respectively, meaning the gradient begins at the very center and goes to the farthest measured edge of the object.


  diagram.layout = $(go.GridLayout);

  diagram.add(
    $(go.Part,
      $(go.Shape, {
                    figure: "Rectangle", width: 100, height: 100, margin: 5,
                    // A rainbow radial gradient brush:
                    fill: $(go.Brush, "Radial", {
                      0.0: "red", 1: "black"
                    })
                  })
    ));

  diagram.add(
    $(go.Part,
      $(go.Shape, {
                    figure: "Rectangle", width: 100, height: 100, margin: 5,
                    // A rainbow radial gradient brush:
                    fill: $(go.Brush, "Radial", {
                      startRadius: 30, 0.0: "red", 1: "black"
                    })
                  })
    ));

  diagram.add(
    $(go.Part,
      $(go.Shape, {
                    figure: "Rectangle", width: 100, height: 100, margin: 5,
                    // A rainbow radial gradient brush:
                    fill: $(go.Brush, "Radial", {
                      startRadius: 30, endRadius: 40, 0.0: "red", 1: "black"
                    })
                  })
    ));

Several GraphObjects can share the same Brush:



  diagram.layout = $(go.GridLayout);

  // Create one brush for several GraphObjects to share:
  var rainbow = $(go.Brush, "Linear", {
                        0.0: "rgba(255, 0, 0, 1)",
                        0.15: "rgba(255, 255, 0, 1)",
                        0.30: "rgba(0, 255, 0, 1)",
                        0.50: "rgba(0, 255, 255, 1)",
                        0.65: "rgba(0, 0, 255, 1)",
                        0.80: "rgba(255, 0, 255, 1)",
                        1: "rgba(255, 0, 0, 1)"
                      });
  diagram.add(
    $(go.Part,
      $(go.Shape, { figure: "Rectangle", width: 100, height: 100, fill: rainbow })
    ));

  diagram.add(
    $(go.Part,
      $(go.Shape, { figure: "Fragile", width: 50, height: 50, angle: 45, fill: rainbow })
    ));


  diagram.add(
    $(go.Part, "Auto",
      $(go.Shape, { figure: "Rectangle", fill: rainbow }),
      $(go.TextBlock, "text", { font: 'bold 32pt sans-serif', stroke: rainbow, angle: 90 })
    ));

  diagram.add(
    $(go.Part,
      $(go.Shape, { figure: "Circle", width: 70, height: 70, angle: 180, fill: null, strokeWidth: 10, stroke: rainbow })
    ));

Pattern Brushes

The following example sets up two Pattern brushes, one using an HTML Canvas with content drawn to it, which looks like this:

The other Pattern Brush uses this image:



  // set up an 40x40 HTML Canvas and draw on it to create a repeating "tile" to use as a pattern
  function makePattern() {
    var patternCanvas = document.createElement('canvas');
    patternCanvas.width = 40;
    patternCanvas.height = 40;
    var pctx = patternCanvas.getContext('2d');

    // This creates a shape similar to a diamond leaf
    pctx.beginPath();
    pctx.moveTo(0.0, 40.0);
    pctx.lineTo(26.9, 36.0);
    pctx.bezierCurveTo(31.7, 36.0, 36.0, 32.1, 36.0, 27.3);
    pctx.lineTo(40.0, 0.0);
    pctx.lineTo(11.8, 3.0);
    pctx.bezierCurveTo(7.0, 3.0, 3.0, 6.9, 3.0, 11.7);
    pctx.lineTo(0.0, 40.0);
    pctx.closePath();
    pctx.fillStyle = "rgb(188, 222, 178)";
    pctx.fill();
    pctx.lineWidth = 0.8;
    pctx.strokeStyle = "rgb(0, 156, 86)";
    pctx.lineJoin = "miter";
    pctx.miterLimit = 4.0;
    pctx.stroke();

    return patternCanvas;
  }

  if (window.goSamples) goSamples();  // init for these samples -- you don't need to call this
  var $ = go.GraphObject.make;  // for conciseness in defining templates

  diagram.nodeTemplate =
    $(go.Node, "Spot",
      { resizable: true, resizeObjectName: 'SHAPE' },
      $(go.Shape, "Rectangle",
        { name: 'SHAPE', strokeWidth: 0, stroke: null },
        new go.Binding("fill")),
      $(go.TextBlock,
        { margin: 10, font: "bold 18px Verdana" },
        new go.Binding("text", "key"))
    );

  var img = new Image();
  img.src = 'images/pattern.jpg';

  // Use an image as a pattern
  var patternBrush = $(go.Brush, "Pattern", { pattern: img });
  // use a reference to an HTML Canvas (with renderings on it) as a pattern:
  var patternBrush2 = $(go.Brush, "Pattern", { pattern: makePattern() });


  diagram.model = new go.GraphLinksModel(
    [
      { key: "Alpha", fill: patternBrush },
      { key: "Beta",  fill: patternBrush2 }
    ],
    [
    ]);

The result:

Brush Functions

There are some functions available for generating different colors or modifying Brush colors:

In the following example, parts use the lighten and darken functions to get suitable colors for their stroke/fill.


  diagram.layout = $(go.GridLayout);
  var color1 = "rgb(80, 130, 210)";
  var color2 = go.Brush.randomColor(192, 224);
  var gradBrush = $(go.Brush, "Linear", { 0: color1, 1: color2 });
  function shapeStyle() {
    return [ "Ellipse", { width: 120, height: 80, strokeWidth: 4 } ];
  }

  // static Brush methods
  diagram.add($(go.Part, "Auto",
      $(go.Shape, shapeStyle(),
        { fill: color1, stroke: go.Brush.darken(color1) }),
      $(go.TextBlock, "dark stroke")));

  diagram.add($(go.Part, "Auto",
      $(go.Shape, shapeStyle(),
        { fill: color1, stroke: go.Brush.darkenBy(color1, .4) }),
      $(go.TextBlock, "darker stroke")));

  diagram.add($(go.Part, "Auto",
      $(go.Shape, shapeStyle(),
        { fill: go.Brush.lighten(color1), stroke: color1 }),
      $(go.TextBlock, "light fill")));

  diagram.add($(go.Part, "Auto",
      $(go.Shape, shapeStyle(),
        { fill: go.Brush.lightenBy(color1, .4), stroke: color1 }),
      $(go.TextBlock, "lighter fill")));

  // instance Brush methods
  diagram.add($(go.Part, "Auto",
      $(go.Shape, shapeStyle(),
        { fill: gradBrush.copy().lightenBy(.2) }),
      $(go.TextBlock, "lighter")));

  diagram.add($(go.Part, "Auto",
      $(go.Shape, shapeStyle(),
        { fill: gradBrush }),
      $(go.TextBlock, "normal")));

  diagram.add($(go.Part, "Auto",
      $(go.Shape, shapeStyle(),
        { fill: gradBrush.copy().darkenBy(.2) }),
      $(go.TextBlock, "darker")));

In the following example, the color of text is determined by whether the background shape is dark.


  diagram.layout = $(go.GridLayout);

  diagram.nodeTemplate =
    $(go.Node, "Auto",
      { desiredSize: new go.Size(80, 40) },
      $(go.Shape, "RoundedRectangle", { strokeWidth: 0 },
        new go.Binding("fill", "color")),
      $(go.TextBlock, { margin: 8 },
        new go.Binding("stroke", "color",
              // dark nodes use white text, light nodes use dark text
              function (c) { return go.Brush.isDark(c) ? "white" : "black"; }),
        new go.Binding("text", "key")
      )
    );

  diagram.model = new go.Model(
    [
      { key: "Alpha", color: "white" },
      { key: "Beta", color: "black" },
      { key: "Gamma", color: "darkblue" },
      { key: "Delta", color: "lightblue" },
      { key: "Epsilon", color: "darkgreen" },
      { key: "Zeta", color: "lightgreen" },
      { key: "Eta", color: "darkred" },
      { key: "Theta", color: "lightcoral" }
    ]
  )

GoJS