Introduction

Annotations can help explain narratives in your charts and allow users to provide context and highlight important insights directly in the chart.

Annotations are readable at any chart size and zoom level. You can style them to fit your application design, and also integrate them with your user interface so that chart users don't need to use external tools for sharing insights.

To provide more context in documents or presentations, you can export annotated charts with chart.export().

image of a chart with annotations

To find out more, have a look at the available annotation demos and explore the Annotations API Reference.

Adding annotations

KeyLines lets you annotate nodes, links and open and closed combos. You can annotate a single item or multiple items at once, and also annotate items of different types together.

In the items array, an annotation is a special type of chart item that contains the id or ids of the annotated items in the subject array:

let data = {
  type: 'LinkChart',
  items: [
    {
      id: 'annotation1',
      type: 'annotation',
      subject: 'node1',
      t: { t: 'Node 1 annotation' },
    },
    { id: 'node1', type: 'node', c: '#ff00ff' },
  ],
};

an image of a single node with a simple annotation

Annotations are loaded into the chart for example using chart.load(), chart.merge(), chart.expand() or chart.setItem().

Annotations are only drawn when at least one of their subjects is visible in the chart. Annotations of items inside a combo are only drawn when the combo is open.

If your application code contains logic checking whether a chart item is either a node or a link ( if (item.type === 'node') { etc } ), introducing annotations into your code may require changes to also consider annotations.

Positioning

KeyLines annotations are drawn in their own separate layer on top of the chart and they are positioned relative to their subjects. The positioning is determined by:

  • the angle relative to their subjects, either in compass points or in degrees
  • the distance from their subjects in view coordinates

When a layout is run or when their subjects are repositioned, annotations also move to keep their position relative to their subjects.

Annotations do not scale during zooming and instead remain readable at every zoom level.

Styling

a image of an annotated node outlining the line, subject end and container parts of an annotation

A default annotation has two main parts:

  • A body with text, images, font icons or custom user controls, styled in the annotation properties
  • A connector that relates the annotation to its subject(s), styled in the connectorStyle object

The connector is made of three parts:

  • A line or lines pointing to the subject(s)
  • An optional subjectEnd decoration, which can be a dot or an arrow
  • An optional container around node or combo subjects, which can be a circle or a rectangle

The c (colour), w (width) and ls (line style) options of connectorStyle style the whole connector. Setting the w option to 0 hides the connector and creates an annotation that isn't visibly connected to subjects but stays in a relative position to them.

See more about individual annotation parts in the Annotation Basics demo.

The styling of body in the annotation properties includes setting custom dimensions, fill colour, borders, or adding multiple labels and multiple glyphs. Take a look at the Advanced Annotation Styles demo to explore various examples and levels of styling.

Both chart.setProperties() and chart.animateProperties() can be used to set annotation properties.

Custom user controls

You can add custom user controls to annotations to integrate them into your application's user workflow.

Using the KeyLines API, you can add labels (t) and glyphs (g) as buttons or toggles and respond to chart events triggered by interacting with the buttons:

// example click handler where the 2nd label is a delete button

const clickHandler = ({ subItem, id }) => {
  const item = chart.getItem(id);
  if (
    item &&
    item.type === 'annotation' &&   // if an item is an annotation
    subItem.type === 'label' &&     // and the clicked item is a label
    subItem.index === 1             // and the label has index of 1 in the array (2nd label)
  ) {
    // code for delete button here
  }
};

See an example of this in our Advanced Annotation Styles demo.

You can also create annotations with user-editable text fields or any other custom elements by overlaying your own HTML elements over KeyLines annotations. For more details, have a look at the User-Created Annotations demo.

Filtering

An annotation is drawn in the chart when at least one of its subjects is visible in the chart.

To control visibility of annotations in the chart independently of their subjects, you can set the hi property on annotations, remove the annotations from the items array or pass the annotation ids to the chart.show() or chart.hide() functions.

Annotations also inherit these states from their subjects:

  • hi - annotations are hidden if all of their subjects are hidden.
  • chart.filter() - iterates over subjects, annotations are hidden if all of their subjects are hidden.
  • Special behaviour

    While annotations are loaded into the chart just like nodes and links, they are a special type of always-readable chart item that are not considered as items by the layout algorithms. As a result, some of their behaviour is different from other chart items:

    • Annotations cannot be selected.
    • Annotations cannot be foregrounded or backgrounded.
    • Annotations are not shown on a Leaflet map.