# 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 Brsuh.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:

- Brush,randomColor - returns a random hexadecimal color value
- Brush,lightenBy and Brush,darkenBy - return lightened or darkened colors/brushes; there are both instance and static versions
- Brush,lighten and Brush,darken - convenience static functions which return lightened or darkened colors
- Brush,mix - mixes two colors together
- Brush,isDark - determines whether a color is dark, often used in bindings; there are both instance and static versions

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