Adding watermarks to charts

This tutorial will show how your can brand your charts using different kinds of watermarking techniques.

Prerequisites

Containers and patterns

This tutorial will rely on two amCharts 4 concepts: Containers and Patterns.

Containers will are used to add and arrange stuff to various parts of the chart. We'll use them to add watermarks. Make sure you read up on the concept in our "Working with Containers" article.

We're also be using patterns to apply patterned watermark fills to our charts. Read all about it in our "Patterns" section of our article about colors.

Base chart

We're going to use a very simple chart as a guinea pig here:

See the Pen amCharts 4: Watermarking charts (1) by amCharts (@amcharts) on CodePen.24419

Brand labels

I know you haven't read the Containers article we asked you to read because you're lazy coder, just like we are, but if you would have, you would know that almost everything on the chart is a "Container", which can have any number of elements we call "Sprites".

Since Container itself is a Sprite, you can add virtually any element to a Container, nest them in any way you can. It will just work.

This is what we will be doing in this section of the article: creating textual label Sprites and image Sprites and adding them to various containers of the chart.

Adding text label

Let's start wit a text label.

A label in amCharts 4 is represented by an object of type Label.

To add a textual label to the chart, we would just need to create an instance of Label then just push() it to children of our target container.

Let's try that:

let watermark = new am4core.Label();
watermark.text = "My awesome chart © 2018 Myself";
chart.children.push(watermark);
var watermark = new am4core.Label();
watermark.text = "My awesome chart © 2018 Myself";
chart.children.push(watermark);
{
  // ...
  "children": [{
    "type": "Label",
    "text": "My awesome chart © 2018 Myself"
  }]
}

This alone will add the "My awesome chart © 2018 Myself" as a label to the chart.

See the Pen amCharts 4: Watermarking charts (2) by amCharts (@amcharts) on CodePen.24419

You'll notice that the label is not positioned nicely, and that the chart itself was shrunk to accommodate the label. We'd also like to to be less prominent.

We'll get to that shortly.

Positioning

In previous section we simply added our label to a chart, which is a Container of course. Since it has specific layout rules set, our label was positioned and aligned according to those rules, affecting other elements such as the chart itself.

We're now going to let you in on a secret: there are a lot of other containers that we can use. Since we don't want to meddle with layout of our chart, we can use chart.tooltipContainer.

Another great candidate is chart.plotContainer. While tooltipContainer covered the whole area of the chart, plotContainer covers the actual plot area - an area that graphs are drawn on.

Depending on your requirements, you might choose one or another.

Using tooltipContainer
Using plotContainer

Both are suitable containers for our watermarks for a number of reasons:

  1. It's available on all charts;
  2. It covers all of the chart or plot area;
  3. It has "absolute" layout so we can position our watermark element the way we want.

This all means we can rewrite our above example to use different container, as well as use label's "align" properties (align and valign) to position it. Let's use plotContainer:

let watermark = new am4core.Label();
watermark.text = "My awesome chart © 2018 Myself";
chart.plotContainer.children.push(watermark);
watermark.align = "right";
watermark.valign = "bottom";
var watermark = new am4core.Label();
watermark.text = "My awesome chart © 2018 Myself";
chart.plotContainer.children.push(watermark);
watermark.align = "right";
watermark.valign = "bottom";
{
  // ...
  "plotContainer": {
    "children": [{
      "type": "Label",
      "text": "My awesome chart © 2018 Myself",
      "align": "right",
      "valign": "bottom"
    }]
  }
}

Let's see how that worked:

See the Pen amCharts 4: Watermarking charts (3) by amCharts (@amcharts) on CodePen.24419

Better. It is not positioned in a less intrusive way and does not affect chart layout.

MORE INFO For more information on chart built-in containers, visit "Pre-defined chart containers".

Now let's see how we can tweak it further.

Sizing and dimming

Let's make it a more like watermark. That means making it larger, but also dimmed out so it does not get in the way but is still visible.

watermark.fontSize = 30;
watermark.opacity = 0.2;
watermark.marginRight = 10;
watermark.marginBottom = 5;
watermark.fontSize = 30;
watermark.opacity = 0.2;
watermark.marginRight = 10;
watermark.marginBottom = 5;
{
  // ...
  "plotContainer": {
    "children": [{
      // ...
      "fontSize": 30,
      "opacity": 0.2,
      "marginRight": 10,
      "marginBottom": 5
    }]
  }
}

We increased fontSize, dimmed out by setting opacity, and also added some margins so that our label is not stuck to the edge of the plot area.

See the Pen amCharts 4: Watermarking charts (4) by amCharts (@amcharts) on CodePen.24419

Adding a link

Adding a link to a label, or any element for that matter, is as simple as setting its url property.

If you'd like to open your links in a separate tab/window, you can also set urlTarget.

watermark.url = "https://www.amcharts.com/";
watermark.urlTarget = "_blank";
watermark.url = "https://www.amcharts.com/";
watermark.urlTarget = "_blank";
{
  // ...
  "plotContainer": {
    "children": [{
      // ...
      "url ": "https://www.amcharts.com/",
      "urlTarget": "_blank"
    }]
  }
}

Using image

Using an image as a watermark is pretty much identical as using the text label: you instantiate an object (in this case Image) and set it up, and push it to children of the appropriate container.

let watermark = new am4core.Image();
watermark.href = "/path/to/image.svg";
chart.plotContainer.children.push(watermark);
watermark.align = "right";
watermark.valign = "bottom";
watermark.opacity = 0.2;
watermark.marginRight = 10;
watermark.marginBottom = 5;
var watermark = new am4core.Image();
watermark.href = "/path/to/image.svg";
chart.plotContainer.children.push(watermark);
watermark.align = "right";
watermark.valign = "bottom";
watermark.opacity = 0.2;
watermark.marginRight = 10;
watermark.marginBottom = 5;
{
  // ...
  "plotContainer": {
    "children": [{
      "type": "Image",
      "href": "/path/to/image.svg",
      "align": "right",
      "valign": "bottom",
      "opacity": 0.2,
      "marginRight": 10,
      "marginBottom": 5
    }]
  }
}

And we're done:

See the Pen amCharts 4: Watermarking charts (5) by amCharts (@amcharts) on CodePen.24419

Watermark patterns

So far we have been looking at adding singular watermark/branding elements.

Now, let's see how we can create a pattern that covers the whole of the container of the repeating elements.

Choosing watermark container

As before, we will need to choose which container we are going to use.

If we want to cover just the plot area, we'll go with plotContainer. If we'd like to watermark the whole of the chart, we can use our chart object as a direct container.

Creating a pattern

Risking sounding like your mother, before we begin, make sure you brush off your pattern-creation skills here.

Basically, a Pattern is a Container, we add stuff to, set its dimensions, and that stuff gets repeated as a grid when filling some other shape, such as background of a Container.

Let's first start with a pattern of text labels.

let watermark = new am4core.Label();
watermark.text = "© 2018 Myself";
watermark.fontSize = 35;

let pattern = new am4core.Pattern();
pattern.addElement(watermark.group);
pattern.width = 250;
pattern.height = 100;
pattern.x = 20;
var watermark = new am4core.Label();
watermark.text = "© 2018 Myself";
watermark.fontSize = 35;
var pattern = new am4core.Pattern();
pattern.addElement(watermark.group);
pattern.width = 250;
pattern.height = 100;
pattern.x = 20;
{
  // ...
  "plotContainer": {
    "background": {
      "fillOpacity": 0.1,
      "fill": {
        "type": "Pattern",
        "width": 250,
        "height": 100,
        "x": 20,
        "elements": [{
          "type": "Label",
          "typeProperty": "group",
          "text": "© 2018 Myself",
          "fontSize": 35
        }]
      }
    }
  }
}

IMPORTANT Notice we are using label's group property to add as an element of a pattern. Basically, we can't add a Sprite to pattern directly - we need to add a reference to an actual SVG element. We need to use group because all style properties affecting text are set on the <g> (group) node that holds actual text.

NOTE ABOUT JSON In JSON config the setting typeProperty indicates which property of the Sprite we need to use when adding and element to Pattern.

If you take a look at the code above, you'll notice how we are setting pattern's dimensions - it will fill the target area with tiles of the specified dimension.

We also set x to give it a little offset to the right. We could also set pattern's rotation setting to put our text at an angle.

Setting container's fill

Now that we have our pattern created, we can use it as a fill for the background of any container:

chart.plotContainer.background.fill = pattern;
chart.plotContainer.background.fillOpacity = 0.1;
chart.plotContainer.background.fill = pattern;
chart.plotContainer.background.fillOpacity = 0.1;
{
  // ...
  "plotContainer": {
    "background": {
      "fillOpacity": 0.1,
      "fill": {
        "type": "Pattern",
        "width": 250,
        "height": 100,
        "x": 20,
        "elements": [{
          "type": "Label",
          "typeProperty": "group",
          "text": "© 2018 Myself",
          "fontSize": 35
        }]
      }
    }
  }
}

Let's see how it turned out:

See the Pen amCharts 4: Watermarking charts (6) by amCharts (@amcharts) on CodePen.24419

Image patterns

Using images is similar: we create an Image object (instead of Label) and add it as an element to Pattern:

let watermark = new am4core.Image();
watermark.href = "/path/to/image.svg";

let pattern = new am4core.Pattern();
pattern.addElement(watermark.element);
pattern.width = 80;
pattern.height = 80;
pattern.x = 20;
chart.plotContainer.background.fill = pattern;
chart.plotContainer.background.fillOpacity = 0.1;
var watermark = new am4core.Image();
watermark.href = "/path/to/image.svg";

var pattern = new am4core.Pattern();
pattern.addElement(watermark.element);
pattern.width = 80;
pattern.height = 80;
pattern.x = 20;
chart.plotContainer.background.fill = pattern;
chart.plotContainer.background.fillOpacity = 0.1;
{
  // ...
  "plotContainer": {
    "background": {
      "fillOpacity": 0.1,
      "fill": {
        "type": "Pattern",
        "width": 80,
        "height": 80,
        "x": 20,
        "elements": [{
          "type": "Image",
          "typeProperty": "element",
          "href ": "/path/to/image.svg"
        }]
      }
    }
  }
}

Easy:

See the Pen amCharts 4: Watermarking charts (7) by amCharts (@amcharts) on CodePen.24419

NOTE Notice, in this case we are using element instead of group when adding our image element to pattern.