Find an interesting view in the data, then click the button below the timeline to export the view to a static image.
The timeline, scales and labels will be included in the export.
See also:
Find an interesting view in the data, then click the button below the timeline to export the view to a static image.
The timeline, scales and labels will be included in the export.
See also:
import { createTimeline } from "kronograph";
import { data, markers } from "./data";
const timeline = createTimeline("my-timeline");
timeline.set(data);
timeline.markers(markers);
timeline.fit();
async function onDownloadClick() {
const { url } = await timeline.export({ type: "png" });
const link = document.createElement("a");
link.download = "timeline-export.png";
link.href = url;
link.click();
URL.revokeObjectURL(url);
}
document.querySelector("#export-download").addEventListener("click", onDownloadClick); export const data = {
entityTypes: {
Claim: {
order: 2,
},
Investigated: {
baseType: "Claim",
color: "#EA3C53",
labelColor: "#fc4c63",
},
Accepted: {
baseType: "Claim",
color: "#1BBC9B",
labelColor: "#21deb8",
},
Claimant: {
color: "#b2bfd8",
lineWidth: 10,
order: 1,
},
},
eventTypes: {
default: {
showArrows: true,
},
"Not Flagged": {
baseType: "default",
color: "#1BBC9B",
lineWidth: 2,
},
Flagged: {
baseType: "default",
color: "#EA3C53",
lineWidth: 6,
},
},
entities: {
"smith-johnathan-151": {
label: "John Smith",
type: "Claimant",
},
"west-josephine-126": {
label: "Josephine West",
type: "Claimant",
},
"roberts-nathaniel-023": {
label: "Nathan Roberts",
type: "Claimant",
},
"baxter-eleanor-004": {
label: "Ella Baxter",
type: "Claimant",
},
"Claim MF-1883": {
type: "Accepted",
},
"Claim DO-1748": {
type: "Accepted",
},
"Claim EF-8738": {
type: "Accepted",
},
"Claim PD-9393": {
type: "Investigated",
},
"Claim SL-8745": {
type: "Investigated",
},
"Claim IE-9393": {
type: "Accepted",
},
"Claim GZ-2012": {
type: "Investigated",
},
"Claim SQ-5563": {
type: "Accepted",
},
"Claim FW-1888": {
type: "Investigated",
},
},
events: {
"claim 1": {
entityIds: ["smith-johnathan-151", "Claim MF-1883"],
type: "Not Flagged",
time: new Date(2027, 3, 4),
},
"claim 2": {
entityIds: ["baxter-eleanor-004", "Claim SL-8745"],
type: "Flagged",
time: new Date(2025, 2, 25),
},
"claim 3": {
entityIds: ["west-josephine-126", "Claim DO-1748"],
type: "Not Flagged",
time: new Date(2028, 12, 8),
},
"claim 4": {
entityIds: ["roberts-nathaniel-023", "Claim EF-8738"],
type: "Not Flagged",
time: new Date(2025, 6, 13),
},
"claim 5": {
entityIds: ["smith-johnathan-151", "Claim PD-9393"],
type: "Flagged",
time: new Date(2027, 10, 16),
},
"claim 6": {
entityIds: ["baxter-eleanor-004", "Claim IE-9393"],
type: "Not Flagged",
time: new Date(2028, 2, 25),
},
"claim 7": {
entityIds: ["roberts-nathaniel-023", "Claim GZ-2012"],
type: "Flagged",
time: new Date(2027, 4, 11),
},
"claim 8": {
entityIds: ["baxter-eleanor-004", "Claim SQ-5563"],
type: "Not Flagged",
time: new Date(2025, 11, 2),
},
"claim 8a": {
entityIds: ["baxter-eleanor-004", "Claim SQ-5563"],
type: "Not Flagged",
time: new Date(2025, 11, 2),
},
"claim 8b": {
entityIds: ["baxter-eleanor-004", "Claim SQ-5563"],
type: "Flagged",
time: new Date(2025, 11, 2),
},
"claim 9": {
entityIds: ["west-josephine-126", "Claim FW-1888"],
type: "Flagged",
time: new Date(2026, 8, 5),
},
},
timeSeriesCharts: {
claimValue: {
color: "#ff8838",
label: "Average Claim Value",
data: [
{
time: new Date(2025, 2, 25),
value: 10,
},
{
time: new Date(2025, 3, 14),
value: 9,
},
{
time: new Date(2025, 6, 25),
value: 6,
},
{
time: new Date(2025, 11, 11),
value: 7,
},
{
time: new Date(2026, 1, 1),
value: 8,
},
{
time: new Date(2026, 7, 4),
value: 9,
},
{
time: new Date(2027, 2, 3),
value: 10,
},
{
time: new Date(2027, 4, 8),
value: 12,
},
{
time: new Date(2027, 6, 25),
value: 9,
},
{
time: new Date(2028, 2, 25),
value: 8,
},
{
time: new Date(2028, 4, 25),
value: 9,
},
{
time: new Date(2028, 8, 25),
value: 7,
},
{
time: new Date(2029, 1, 25),
value: 5,
},
{
time: new Date(2029, 2, 25),
value: 6,
},
],
},
},
};
export const markers = [{ label: "Claim Investigation Began", time: Date.UTC(2025, 7, 14, 14, 7) }]; <!doctype html>
<html>
<head>
<link rel="stylesheet" href="@ci/theme/kg/css/examples.css" />
</head>
<body>
<div class="story">
<div class="story__timeline" id="my-timeline"></div>
<div class="story__controls story__controls--row">
<div class="story__controls__button-container">
<button class="button button--neutral" title="Export PNG image" id="export-download">
Export PNG image
</button>
</div>
</div>
</div>
<script type="module" src="./code.js"></script>
</body>
</html> import React, { useRef } from "react";
import { createRoot } from "react-dom/client";
import Timeline from "kronograph/react/Timeline";
import { data, markers } from "./data";
function Button({ clickHandler, title }) {
return (
<button className="button button--neutral" title={title} onClick={clickHandler}>
{title}
</button>
);
}
export const Demo = () => {
const timelineRef = useRef(null);
return (
<div className="story">
<Timeline
className="story__timeline"
ref={timelineRef}
markers={markers}
events={data.events}
entities={data.entities}
eventTypes={data.eventTypes}
entityTypes={data.entityTypes}
timeSeriesCharts={data.timeSeriesCharts}
/>
<div className="story__controls story__controls--row">
<div className="story__controls__button-container">
<Button
title="Export to PNG"
clickHandler={async () => {
const { url } = await timelineRef.current.export({ type: "png" });
const link = document.createElement("a");
link.download = "timeline-export.png";
link.href = url;
link.click();
URL.revokeObjectURL(url);
}}
/>
</div>
</div>
</div>
);
};
const root = createRoot(document.getElementById("my-timeline"));
root.render(<Demo />); export const data = {
entityTypes: {
Claim: {
order: 2,
},
Investigated: {
baseType: "Claim",
color: "#EA3C53",
labelColor: "#fc4c63",
},
Accepted: {
baseType: "Claim",
color: "#1BBC9B",
labelColor: "#21deb8",
},
Claimant: {
color: "#b2bfd8",
lineWidth: 10,
order: 1,
},
},
eventTypes: {
default: {
showArrows: true,
},
"Not Flagged": {
baseType: "default",
color: "#1BBC9B",
lineWidth: 2,
},
Flagged: {
baseType: "default",
color: "#EA3C53",
lineWidth: 6,
},
},
entities: {
"smith-johnathan-151": {
label: "John Smith",
type: "Claimant",
},
"west-josephine-126": {
label: "Josephine West",
type: "Claimant",
},
"roberts-nathaniel-023": {
label: "Nathan Roberts",
type: "Claimant",
},
"baxter-eleanor-004": {
label: "Ella Baxter",
type: "Claimant",
},
"Claim MF-1883": {
type: "Accepted",
},
"Claim DO-1748": {
type: "Accepted",
},
"Claim EF-8738": {
type: "Accepted",
},
"Claim PD-9393": {
type: "Investigated",
},
"Claim SL-8745": {
type: "Investigated",
},
"Claim IE-9393": {
type: "Accepted",
},
"Claim GZ-2012": {
type: "Investigated",
},
"Claim SQ-5563": {
type: "Accepted",
},
"Claim FW-1888": {
type: "Investigated",
},
},
events: {
"claim 1": {
entityIds: ["smith-johnathan-151", "Claim MF-1883"],
type: "Not Flagged",
time: new Date(2027, 3, 4),
},
"claim 2": {
entityIds: ["baxter-eleanor-004", "Claim SL-8745"],
type: "Flagged",
time: new Date(2025, 2, 25),
},
"claim 3": {
entityIds: ["west-josephine-126", "Claim DO-1748"],
type: "Not Flagged",
time: new Date(2028, 12, 8),
},
"claim 4": {
entityIds: ["roberts-nathaniel-023", "Claim EF-8738"],
type: "Not Flagged",
time: new Date(2025, 6, 13),
},
"claim 5": {
entityIds: ["smith-johnathan-151", "Claim PD-9393"],
type: "Flagged",
time: new Date(2027, 10, 16),
},
"claim 6": {
entityIds: ["baxter-eleanor-004", "Claim IE-9393"],
type: "Not Flagged",
time: new Date(2028, 2, 25),
},
"claim 7": {
entityIds: ["roberts-nathaniel-023", "Claim GZ-2012"],
type: "Flagged",
time: new Date(2027, 4, 11),
},
"claim 8": {
entityIds: ["baxter-eleanor-004", "Claim SQ-5563"],
type: "Not Flagged",
time: new Date(2025, 11, 2),
},
"claim 8a": {
entityIds: ["baxter-eleanor-004", "Claim SQ-5563"],
type: "Not Flagged",
time: new Date(2025, 11, 2),
},
"claim 8b": {
entityIds: ["baxter-eleanor-004", "Claim SQ-5563"],
type: "Flagged",
time: new Date(2025, 11, 2),
},
"claim 9": {
entityIds: ["west-josephine-126", "Claim FW-1888"],
type: "Flagged",
time: new Date(2026, 8, 5),
},
},
timeSeriesCharts: {
claimValue: {
color: "#ff8838",
label: "Average Claim Value",
data: [
{
time: new Date(2025, 2, 25),
value: 10,
},
{
time: new Date(2025, 3, 14),
value: 9,
},
{
time: new Date(2025, 6, 25),
value: 6,
},
{
time: new Date(2025, 11, 11),
value: 7,
},
{
time: new Date(2026, 1, 1),
value: 8,
},
{
time: new Date(2026, 7, 4),
value: 9,
},
{
time: new Date(2027, 2, 3),
value: 10,
},
{
time: new Date(2027, 4, 8),
value: 12,
},
{
time: new Date(2027, 6, 25),
value: 9,
},
{
time: new Date(2028, 2, 25),
value: 8,
},
{
time: new Date(2028, 4, 25),
value: 9,
},
{
time: new Date(2028, 8, 25),
value: 7,
},
{
time: new Date(2029, 1, 25),
value: 5,
},
{
time: new Date(2029, 2, 25),
value: 6,
},
],
},
},
};
export const markers = [{ label: "Claim Investigation Began", time: Date.UTC(2025, 7, 14, 14, 7) }]; <!doctype html>
<html>
<head>
<link rel="stylesheet" href="@ci/theme/kg/css/examples.css" />
</head>
<body>
<div id="my-timeline" style="height: 100vh"></div>
<script type="module" src="./code.jsx"></script>
</body>
</html>