Product Integrations

KronoGraph can be integrated with other Cambridge Intelligence products, such as KeyLines ReGraph and MapWeave, to show timeline visualizations of your data alongside a chart or map visualization. You can configure your application so that when the data updates, or a user interaction changes the timeline, the changes are reflected in the other product and vice versa.

See the Integration Playground or the Integrations section of our Storybook for examples.

In this section we refer to KronoGraph timelines and entities, KeyLines ReGraph charts and nodes, and MapWeave maps and nodes.

General Considerations

There's no one standard way to integrate KronoGraph with another of our products as it depends on your data model and the interactions you want to offer your end users. It's worth considering:

  • How will you model and convert your data between the two? Bear in mind that this also determines the relationship between your nodes and entities. Will you map timeline events directly to links between nodes?
  • How will you display the app components. Do you want to display the timeline and the chart, or map, side by side, or in separate tabs? Do you also want to include a time bar?
  • What interaction patterns between the two products will you use?

The following sections illustrate the most common interaction patterns to get you started:

  • Using the current timeline range to just display information related to that time period in the chart or map.
  • Selecting a node to focus on its associated entity in the timeline.
  • Setting the focus on an entity in the timeline to highlight its associated node in the chart or map.

We provide a set of stories to illustrate how to do this with each of our products, and an Integration Playground

Integrating KeyLines ReGraph

Integrate KronoGraph with KeyLines ReGraph to show both timeline and chart visualizations of your data together.

Filtering the Chart by Time

Keep the chart synchronized with the time range shown in the timeline. As the user pans or zooms the timeline, the chart should then only show connections that are present during the displayed time range.

When the timeline range changes, handle it:

timeline.on('range', timelineRangeHandler);
onTimelineChange={timelineChangeHandler}

Create a function to identify the entities currently visible in the timeline, and then display just their corresponding nodes in the chart. The isEmpty function, pickBy function, used here, is provided by the lodash library.

async function timelineRangeHandler() {
  const { entities: visibleEntityIds } = timeline.getInRangeItems({ focus: false });
  const filterOptions = { type: 'node', animate: false };
  const { shown, hidden } = await chart.filter(item => visibleEntityIds[item.id], filterOptions);
    if (!isEmpty(shown.nodes) || !isEmpty(hidden.nodes)) {
      await chart.layout('organic');
    }
};
function timelineChangeHandler() {
  const { entities, events } = timeline.current.getInRangeItems({ focus: false });
  setChartItems(pickBy(chartData, (_item, id) => events[id] || entities[id]));
};

This use of range and getInRangeItems is illustrated in the KeyLines and ReGraph Integration Basics story.

This use of range and getInRangeItems is illustrated in the KeyLines and ReGraph Integration Basics story.

Focusing on Entities to Select Chart Items

The KronoGraph focus API focus API filters the timeline so that only focused items and their connections are shown. This example shows how to use this to select the corresponding items in the chart.

In this example chart nodes have the same ids as their corresponding timeline entities.

When an entity is focused in the timeline, handle it:

timeline.on('focus', ({ focus }) => applySelection(focus));
onTimelineChange={timelineChangeHandler}

Create a function that passes the focused items to chart selection:

async function applySelection(selection) {
  chart.selection(selection);
};
function timelineChangeHandler({ focus }) {
  if (focus){
    setFocusedItems(Object.fromEntries(focus.map(id => [id, true])));
  }
}

This use of focus focus is illustrated in the KeyLines and ReGraph Integration Basics story, which also illustrates how using focus compares to using entitySelection. entitySelection.

You could adapt this further by setting eventSelectionMode, eventSelectionMode, and using the eventSelection API eventSelection prop to highlight links in the chart.

Selecting Chart Nodes to Set Their Focus

The example below shows how to display the timelines associated with items selected in the chart.

In this example chart nodes have the same ids as their corresponding timeline entities.

When an item is selected in the chart, handle it:

chart.on('selection-change', () => applySelection(chart.selection()));
onChange={chartChangeHandler}

Create a function that passes the selected items to the timeline, and sets their focus:

async function applySelection(selection) {
  const selectedNodeIds = selection.filter(itemId => chart.getItem(itemId).type === 'node');
  timeline.focus(selectedNodeIds);
};
function chartChangeHandler({ selection }) {
  if (selection) {
    setFocusedItems(selection);
  }
}

This use of focus focus is illustrated in the KeyLines and ReGraph Integration Basics story, which also illustrates how using focus compares to using entitySelection. entitySelection.

Integrating MapWeave

Integrate KronoGraph with MapWeave to conduct in-depth temporal analysis on your geospatial data. You can use the visible timeline range to filter data, or set the focus on entities to filter and zoom on specific nodes and their journeys on the map. You can also use KronoGraph features such as the Ping API Ping API to highlight the item on the timeline, which can be useful for busy datasets.

Filtering Information on a Map by Time Range

Keep the information displayed in MapWeave synchronized with the timeline's time range. As the user pans or zooms the timeline, the map should then only show nodes involved with events displayed in the time range.

When the timeline range changes, handle it:

timeline.on('range', timeRangeChangeHandler);
onTimelineChange={timelineChangeHandler}

Create a function to identify the entities currently visible in the timeline, and then display just their corresponding nodes in the map:

function timeRangeChangeHandler( range ) {
  networkLayer.options({ timeFilterRange: range });
}
function timelineChangeHandler({ range }) {

  setNetworkLayerOptions(options => {
    return { ...options, timeFilterRange: range };
  });
}

This use of range range is illustrated in the MapWeave Integration Basics story.

Focusing Items to Select Nodes on the Map

The KronoGraph focus API focus API filters the timeline so that only focused items and their connections are shown. The example below shows how to use this to select the corresponding nodes in the map.

In this example the MapWeave nodes have the same ids as their corresponding timeline entities.

Get the items which have focus in the timeline:

timeline.on('focus', focusHandler);
onTimelineChange={timelineChangeHandler}

Create a function that passes them to MapWeave and displays just these focused items:

function focusHandler(event) {
  const focusedNode  = event.focus[0];
  const neighbours = graphEng.neighbors(focusedNode );
  const neighbourNodes = neighbours.nodeIds;

  networkLayer.options({
    foreground: { ids: [
      ...neighbourNodes.concat(neighbours.linkIds),
      focusedNode ]},
  });
}
function timelineChangeHandler({ focus }) {
  if (focus) {
      const focusedNode = focus[0];
      const neighbours = graphEngine.neighbors(focusedNode);
      const neighbourNodes = neighbours.nodeIds;

      setNetworkLayerOptions(options => {
        return {
          ...options,
          foreground:
          { ids: [
            ...neighbourNodes.concat(neighbours.linkIds),
            focusedNode, ]},
        };
      });
  }}

This use of focus focus is illustrated in the MapWeave Integration Basics story.

Selecting a Node to Set its Focus

The example below shows how to display the timelines associated with a selected node.

In this example nodes on the map have the same ids as their corresponding timeline entities.

Catch each node that's clicked in the map:

mapweave.on('click', clickHandler);
onClick={clickHandler}

Create a function that shows just that node, and passes the selected item to the timeline, and displays it with focus set:

function clickHandler(click) {
  const clickedItem = click.item;
  if (clickedItem.type === 'node') {

    networkLayer.options({
      foreground: { ids: [
        click.id ],
        backgroundOpacity: 0 },
    });

    timeline.focus(click.id);
  }
}
function clickHandler(click) {
  const clickedItem = click.item;
  if (clickedItem.type === 'node') {

    setNetworkLayerOptions(options => {
      return {
        ...options,
        foreground: {
          ids: [ click.id ],
          backgroundOpacity: 0 },
      };
    });

    setFocus(click.id);
  }
}

This use of focus focus is illustrated in the MapWeave Integration Basics story.

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.