Events

Event Styling

Events can be styled and customized using the properties in the Event object.

You can emphasize different aspects of events using color, and control the appearance of event lines using lineWidth and showArrows. The Styling Events story allows you to explore and experiment with these settings.

You can also (in beta), add labels to event lines, styling their color and orientation, as illustrated in the Event Labels story.

In the example above the color and lineWidth properties have been changed for "event2".

const events = {
  event1: {
    entityIds: ['entity1'],
    time: new Date(2025, 7, 14, 8, 56),
  },
  event2: {
    entityIds: ['entity2', 'entity1'],
    time: new Date(2025, 7, 14, 8, 56, 10),
    color: '#e07a5f',
    lineWidth: 5,
  },
}

Event Types

If you have a number of events that you want to customize in the same way, use the EventType object and then assign a type to the Event.

In these examples we are using a subset of the "Street Network Changes" from the City of New York. Here, the street change events are styled by the type of change. Each type of change has its own EventType where a color and fontIcon are added.

This is an example of how the EventTypes are shown in the data:

  const eventTypes = {
    "Two-way Conversion": {
      "color": "#227c9d",
      "fontIcon": {
        "fontFamily": "Font Awesome 6 Free",
        "fontWeight": 900,
        "text": "\uf101"
      }
    },
    "One-way Conversion": {
      "color": "#ffcb77",
      "fontIcon": {
        "fontFamily": "Font Awesome 6 Free",
        "fontWeight": 900,
        "text": "\uf138"
      }
    },
  },

This how the EventTypes are assigned to the events using the type property:

const events = {
  "172 Stchange": {
    "entityIds": [
      "93 Ave",
      "Jamaica Ave"
    ],
    "time": 1436223600000,
    "type": "One-way Conversion"
  }
}

Event Base Types

Properties can be inherited using a baseType.

In this example each event's color is derived from its type. The fontIcon is set on the baseType of each type.

const eventTypes = {
  "Street Change": {
    "fontIcon": {
      "fontFamily": "Font Awesome 6 Free",
      "fontWeight": 900,
      "text": "\uf101"
    }
  },
  "Brooklyn": {
    "color": "#17c3b2",
    "baseType": "Street Change"
  },
  "The Bronx": {
    "color": "#227c9d",
    "baseType": "Street Change"
  },
  "Queens": {
    "color": "#ffcb77";
    "baseType": "Street Change"
  }
}

See the Inherited Styles story for more details.

Default Event Type

Events that have unspecified properties will inherit them from the default type. Assign properties to the default event type as follows:

  const eventTypes = {
    default: {
      color: '#EE9B00',
    },
  },

Note the default type cannot have a baseType.

Event Summaries

When multiple events are drawn too closely to one another, KronoGraph will combine them into event summaries to prevent overlapping.

An event summary is displayed as a lozenge running along the entity row, using the color of the majority of the events it summarizes.

Event summaries are connected vertically using a translucent band reflecting the colors of the event summaries at either end.

When interacting with any of the parts of an event summary, the targetType in the event handler is 'eventSummary' and the eventIds property contains the ids of all summarized events:

function clickHandler ({ targetType, eventIds }) {
// the user clicked an event or event summary
  if (targetType === 'event' || targetType === 'eventSummary') {
    console.log(`Event ids: `, eventIds);
  }
}
timeline.on('click', clickHandler);
const handleClick = ({ targetType, eventIds }) => {
// the user clicked an event or event summary
  if (targetType === 'event' || targetType === 'eventSummary') {
    console.log(`Event ids: `, eventIds);
  }
}
<Timeline
entities={entities}
events={events}
onTimelineClick={handleClick}
/>

Event Folds

When more than one event happens at the same time, KronoGraph allows you to inspect those events more closely in an event fold.

Because the events happen simultaneously, we imagine they are folded behind the timeline. To "unfold" them, event folds can be clicked and opened which brings the individual events into view.

The event folds are only visible once the timeline is sufficiently zoomed in so that any event summary they're part of has been resolved to single event times. Only one event fold can be open at a time.

All events within the fold have the same time stamp, shown by where the fold is attached to the scale. The time is accessible via the Event object, so a tooltip can be added if needed.

Event folds are shown by default. You can hide them using the showEventFolds API.

When interacting with the fold, the targetType in the event handler is 'fold' and the eventIds property contains the ids of the events within the fold.

function clickHandler ({ targetType, eventIds }) {
// the user clicked a fold
  if (targetType === 'fold') {
    console.log(`Events List: `, eventIds);
  }
}
timeline.on('click', clickHandler);
​​const handleClick = ({ targetType, eventIds }) => {
// the user clicked a fold
  if (targetType === 'fold') {
    console.log(`Events List: `, eventIds);
  }
}
<Timeline
entities={entities}
events={events}
onTimelineClick={handleClick}
/>

Take a peek at our Event Folds story for a working example.

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.