Heatmap

Overview

To help with visual analysis of large datasets, KronoGraph offers the option to aggregate individual events into a heatmap. In the heatmap view, individual cells span periods of time in the timeline.

By default, the heatmap cell colors are based on the colors of underlying events and the cell color alpha values (that is, transparency) represent the event count. Customize your heatmaps using Heatmap Values and Heatmap Colors.

The heatmap view shows when there are more than 100 events in the active range. You can change the default number of events with the heatmapThreshold option.

The heatmapDirection option allows you to control how the heatmap shows entity and event connections. Three options are provided: any (the default), from and to.

For example, here we see a number of entities and events.Events on the timeline.
With any selected the heatmap will show a cell for all underlying event directions.Heatmap direction any.
With from selected, the heatmap will show cells for entity rows that have events going from them.Heatmap direction from.
With to selected, the heatmap will show cells for entity rows that have events going to them.Heatmap direction to.

Additional options to style the heatmap include heatmapPadding and showLines. Both can be seen in the Styling the Timeline story.

For more examples, see the Heatmap section in our storybook.

Heatmap Values

You can set a custom value to be used by the heatmap instead of the event count to determine the color of the cells.

Specify this property with the heatmapValue option:

timeline.options({
  events: {
    heatmapValue: 'amount',
  }
});
options{{
  events: {
    heatmapValue: 'amount',
  }
}}

The custom value is defined in the Event object:

const events = {
  event1: {
    entityIds: ['Person 1', 'Person 2'],
    time:  new Date(2025, 7, 14, 9, 27),
    data: {
      amount: 50,
    },
  },
};
const events = {
  event1: {
    entityIds: ['Person 1', 'Person 2'],
    time:  new Date(2025, 7, 14, 9, 27),
    data: {
      amount: 50,
    },
  },
};

Heatmap Colors

KronoGraph also provides heatmapColor options that allow you choose a color scheme for your heatmap.

Heatmap colors example.

The default setting uses the event color for the heatmap cells (or the entity color if the events don't have a color assigned). The alpha value is based on the number of events or Heatmap Values.

Heatmap values example.

Specify a color to make all heatmap cells this color. The alpha value is based on the number of events or Heatmap Values.

timeline.options({
  events: { heatmapColor: '#e5989b' },
});
<Timeline
  options={{
    events: { heatmapColor: '#e5989b' },
  }}
/>
Heatmap array example.

Specify an array of color values. The color of each cell is based on the number of events or the Heatmap Value. No alpha value is applied to the heatmap cells unless an rgba color is used.

timeline.options({
  events: {
    heatmapColor: ['#ef767a', '#eeb868', '#49dcb1', '#49beaa', '#456990']
    },
});
<Timeline
  options={{
    events: {
      heatmapColor: ['#ef767a', '#eeb868', '#49dcb1', '#49beaa', '#456990']
      },
  }}
/>
Heatmap color step example.

Specify a color and assign it to a range of values. The value is based on the number of events or Heatmap Values. No alpha value is applied to the heatmap cells unless an rgba color is used.

timeline.options({
  events: { heatmapColor: [
    { value: 0, color: 'deepskyblue' },
    // values up to 1.5 are blue
    { value: 1.5, color: 'lightpink' },
    // values between 1.5 and 3 are pink
    { value: 3, color: 'lightgreen' },
    // values above 3 are green
  ] },
});
<Timeline
  options={{
    events: { heatmapColor: [
      { value: 0, color: 'deepskyblue' },
      // values up to 1.5 are blue
      { value: 1.5, color: 'lightpink' },
      // values between 1.5 and 3 are pink
      { value: 3, color: 'lightgreen' },
      // values above 3 are green
    ] },
  }}
/>
Heatmap event type priority example.

Specify a color for each event type. No alpha value is applied to the heatmap cells unless an rgba color is used.

If a heatmap cell contains events of more than one type, then its color is based on the type with the lowest index in the array.

Heatmap cells that contain events that don't have a type property assigned will use the 'default' event type color, if specified in the array.

If a heatmap cell only contains events that have a type property assigned that isn't specified in the array, it will use the average color of the events that make up that cell.

timeline.options({
  events: { heatmapColor: [
    { eventType: 'safe', color: 'rgb(140, 179, 105)' },
    { eventType: 'unsafe', color: 'rgb(188, 75, 81)' },
    { eventType: 'default', color: 'rgba(128, 128, 128, 0.5)' },
  ], },
});
<Timeline
  options={{
    events: { heatmapColor: [
      { eventType: 'safe', color: 'rgb(140, 179, 105)' },
      { eventType: 'unsafe', color: 'rgb(188, 75, 81)' },
      { eventType: 'default', color: 'rgba(128, 128, 128, 0.5)' },
    ], },
  }}
/>

See the Heatmap Colors story for more examples for this option.

Reveal Events

You can use reveal() to keep events visible when switching to heatmap view or to show events in the context of the heatmap.

You can use reveal() to keep events visible when switching to heatmap view or to show events in the context of the heatmap.

timeline.reveal(['event2', 'event8']);
<Timeline
  reveal={['event2', 'event8']}
/>

In addition, you can use the revealHeatmapAlpha option to fade out entity rows that don't have any revealed events.

Heatmap Reveal Alpha

Log in to view live examples
timeline.options({
  events: {
    revealHeatmapAlpha: 0.3
  }
});
<Timeline
  options={{
    events: {
      revealHeatmapAlpha: 0.3
    }
  }}
/>

Try it out in the Reveal story. Note that event folds are unavailable when using reveal.

Heatmap Cells

Information for heatmap cells is available via the subItem object. When the targetType is 'cell', the subItem object will be returned with the values for that cell.

timeline.on('click', (pointerEvent) => {
  if (pointerEvent.targetType === 'cell') {
    const {value, x, y, width, height} = pointerEvent.subItem;
    alert([
      `Heatmap cell at x = ${x}, y = ${y}`,
      `   Width: ${width}`,
      `   Height: ${height}`,
      `   Value: ${value}`,
    ].join('\n'));
  }
});
const handleClick = (pointerEvent) => {
  if (pointerEvent.targetType === 'cell') {
    const {value, x, y, width, height} = pointerEvent.subItem;
    alert([
      `Heatmap cell at x = ${x}, y = ${y}`,
      `   Width: ${width}`,
      `   Height: ${height}`,
      `   Value: ${value}`,
    ].join('\n'))
  }
}
<Timeline
entities={entities}
events={events}
onTimelineClick={handleClick}
/>

The subItem parameters index and time are unused by the heatmap and return undefined.

See the Heatmap Tooltips story for ideas about how to use the subItem object.

Terms of use

These terms do not alter or supersede any existing agreements between you (or your employer) and us.

By accessing or using any Content you agree to be bound by these Terms of Use. Please review these terms carefully before using the website.

The contents of this website, including but not limited to any text, code samples, API references, schemas, interactive tools, and other materials (collectively, the 'Content'), are made available for informational and internal evaluation purposes only. All intellectual property rights in the Content are reserved. No licence is granted to use the Content for any commercial purpose, or to copy, distribute, modify, reverse-engineer, or incorporate any part of the Content into any product or service, without our prior written consent.

This Content is provided “as is” and “as available,” without any representations, warranties, or guarantees of any kind, whether express or implied, including but not limited to implied warranties of merchantability, fitness for a particular purpose, non-infringement, or accuracy. To the fullest extent permitted by applicable law, we expressly exclude and disclaim all implied warranties, conditions, and other terms that might otherwise be implied.

We disclaim all liability for any loss or damage, whether direct, indirect, incidental, consequential, or otherwise, arising from any reliance placed on the Content or from your use of it, to the fullest extent permitted by applicable law. By continuing to access or use the Content, you acknowledge and agree to these terms.