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.