Pan and zoom the timeline to see how many events are loaded from the full dataset. Use the drop-down menu to simulate slow server response times.
With very large datasets it can be useful to limit how far a user can zoom out, and load the data in stages as the user pans. This can keep the amount of data loaded into the browser at a manageable level for optimal performance.
See also:
Pan and zoom the timeline to see how many events are loaded from the full dataset. Use the drop-down menu to simulate slow server response times.
With very large datasets it can be useful to limit how far a user can zoom out, and load the data in stages as the user pans. This can keep the amount of data loaded into the browser at a manageable level for optimal performance.
See also:
import { createTimeline } from "kronograph";
import data from "./data";
const eventDisplayHeading = document.getElementById("event-info");
const delaySelection = document.getElementById("delay-select");
const timelineContainer = document.getElementById("my-timeline");
const timeline = createTimeline({ container: timelineContainer });
const oneWeek = 7 * 24 * 60 * 60 * 1000; // a week in milliseconds
const weeksToShow = 2;
const initialRange = oneWeek * weeksToShow;
const timelineOptions = {
events: {
heatmapThreshold: 200,
},
scales: {
panLimit: "off",
zoomOutLimit: {
unit: "week",
value: weeksToShow,
},
},
};
const {
metadata,
entityTypes,
eventTypes,
entities,
events: eventsArray,
} = data;
const firstEventTime = metadata.firstEventTime;
const lastEventTime = metadata.lastEventTime;
const dataTimeWidth = lastEventTime - firstEventTime;
const weeksOfDataToLoad = 4;
let startTime = firstEventTime;
let endTime = firstEventTime + initialRange;
// convert to UTC milliseconds
// see https://kronograph.io/docs#milliseconds for details
function dateToMilliseconds(date) {
return Date.UTC(
date.getFullYear(),
date.getMonth(),
date.getDate(),
date.getHours(),
date.getMinutes(),
date.getSeconds(),
date.getMilliseconds(),
);
}
function setDisplayInfo(shownEventsCount) {
eventDisplayHeading.innerText = `${shownEventsCount.toLocaleString()} Events currently loaded`;
}
function setLoading(loading) {
if (loading) {
timelineContainer.classList.add("story__loading__cursor");
} else {
timelineContainer.classList.remove("story__loading__cursor");
}
}
function updateTimelineData() {
const buffer = Math.floor(endTime - startTime) / 2;
setLoading(true);
// fetch events within the given time range
const { events, eventCount } = getEvents(
Math.max(startTime - buffer, firstEventTime),
endTime + buffer,
);
setDisplayInfo(eventCount);
const setData = () => {
timeline.set({
events,
entities,
eventTypes,
entityTypes,
});
setLoading(false);
};
if (delaySelection.value > 0) {
setTimeout(setData, delaySelection.value);
} else {
setData();
}
}
function onTimelineRange({ start, end, why }) {
if (why === "user") {
startTime = dateToMilliseconds(start);
endTime = dateToMilliseconds(end);
updateTimelineData();
}
}
function initialiseHandlers() {
timeline.on("range", onTimelineRange);
}
async function startStory() {
timeline.options(timelineOptions);
updateTimelineData();
timeline.fit();
initialiseHandlers();
}
startStory();
/// /////////////////////////////////////////////////////////////////////////
// the code below is used to simulate fetching event data from a database //
/// /////////////////////////////////////////////////////////////////////////
function toIndex(items) {
return items.reduce((result, item) => {
const { id, ...itemWithoutId } = item;
result[id] = itemWithoutId;
return result;
}, {});
}
function offsetEvents(eventArray, offset) {
return eventArray.map((event) => {
return {
...event,
id: `${event.id}-${offset}`,
time: event.time + dataTimeWidth * offset,
};
});
}
// simulate fetching data incrementally from a database
function getEvents(requestedStartTime, requestedEndTime) {
const startTimeOffset = requestedStartTime - firstEventTime;
const offsetFactor = Math.floor(startTimeOffset / dataTimeWidth);
let newEvents = [];
// a full weeks worth of data is loaded in and then repeated for enough weeks to fill the view range when fully zoomed out
for (let i = 0; i < weeksOfDataToLoad; i++) {
newEvents = newEvents.concat(offsetEvents(eventsArray, offsetFactor + i));
}
const firstEventIndex = newEvents.findIndex(
(event) => event.time >= requestedStartTime,
);
const lastEventIndex = newEvents.findIndex(
(event) => event.time >= requestedEndTime,
);
newEvents = newEvents.slice(firstEventIndex, lastEventIndex);
return { events: toIndex(newEvents), eventCount: newEvents.length };
} export default {
metadata: {
firstEventTime: 1578197001722.3477,
lastEventTime: 1578852737532.8713,
},
entityTypes: {
laptop: {
typeLabel: "Client Devices",
},
server: {
typeLabel: "Cloud Infrastructure",
},
},
eventTypes: {
logOn: {
color: "#27ab83",
},
logOff: {
color: "#f58a3d",
},
updateInstalled: {
color: "#f7d06e",
},
},
entities: {
"laptop-0": {
type: "laptop",
label: "Laptop 0",
},
"laptop-1": {
type: "laptop",
label: "Laptop 1",
},
"laptop-2": {
type: "laptop",
label: "Laptop 2",
},
"laptop-3": {
type: "laptop",
label: "Laptop 3",
},
"laptop-4": {
type: "laptop",
label: "Laptop 4",
},
"laptop-5": {
type: "laptop",
label: "Laptop 5",
},
"laptop-6": {
type: "laptop",
label: "Laptop 6",
},
"laptop-7": {
type: "laptop",
label: "Laptop 7",
},
"laptop-8": {
type: "laptop",
label: "Laptop 8",
},
"laptop-9": {
type: "laptop",
label: "Laptop 9",
},
"laptop-10": {
type: "laptop",
label: "Laptop 10",
},
"laptop-11": {
type: "laptop",
label: "Laptop 11",
},
"laptop-12": {
type: "laptop",
label: "Laptop 12",
},
"laptop-13": {
type: "laptop",
label: "Laptop 13",
},
"laptop-14": {
type: "laptop",
label: "Laptop 14",
},
"laptop-15": {
type: "laptop",
label: "Laptop 15",
},
"laptop-16": {
type: "laptop",
label: "Laptop 16",
},
"laptop-17": {
type: "laptop",
label: "Laptop 17",
},
"laptop-18": {
type: "laptop",
label: "Laptop 18",
},
"laptop-19": {
type: "laptop",
label: "Laptop 19",
},
"laptop-20": {
type: "laptop",
label: "Laptop 20",
},
"laptop-21": {
type: "laptop",
label: "Laptop 21",
},
"laptop-22": {
type: "laptop",
label: "Laptop 22",
},
"laptop-23": {
type: "laptop",
label: "Laptop 23",
},
"laptop-24": {
type: "laptop",
label: "Laptop 24",
},
"laptop-25": {
type: "laptop",
label: "Laptop 25",
},
"laptop-26": {
type: "laptop",
label: "Laptop 26",
},
"laptop-27": {
type: "laptop",
label: "Laptop 27",
},
"laptop-28": {
type: "laptop",
label: "Laptop 28",
},
"laptop-29": {
type: "laptop",
label: "Laptop 29",
},
"laptop-30": {
type: "laptop",
label: "Laptop 30",
},
"laptop-31": {
type: "laptop",
label: "Laptop 31",
},
"laptop-32": {
type: "laptop",
label: "Laptop 32",
},
"laptop-33": {
type: "laptop",
label: "Laptop 33",
},
"laptop-34": {
type: "laptop",
label: "Laptop 34",
},
"laptop-35": {
type: "laptop",
label: "Laptop 35",
},
"laptop-36": {
type: "laptop",
label: "Laptop 36",
},
"laptop-37": {
type: "laptop",
label: "Laptop 37",
},
"laptop-38": {
type: "laptop",
label: "Laptop 38",
},
"laptop-39": {
type: "laptop",
label: "Laptop 39",
},
"laptop-40": {
type: "laptop",
label: "Laptop 40",
},
"laptop-41": {
type: "laptop",
label: "Laptop 41",
},
"laptop-42": {
type: "laptop",
label: "Laptop 42",
},
"laptop-43": {
type: "laptop",
label: "Laptop 43",
},
"laptop-44": {
type: "laptop",
label: "Laptop 44",
},
"laptop-45": {
type: "laptop",
label: "Laptop 45",
},
"laptop-46": {
type: "laptop",
label: "Laptop 46",
},
"laptop-47": {
type: "laptop",
label: "Laptop 47",
},
"laptop-48": {
type: "laptop",
label: "Laptop 48",
},
"laptop-49": {
type: "laptop",
label: "Laptop 49",
},
"laptop-50": {
type: "laptop",
label: "Laptop 50",
},
"laptop-51": {
type: "laptop",
label: "Laptop 51",
},
"laptop-52": {
type: "laptop",
label: "Laptop 52",
},
"laptop-53": {
type: "laptop",
label: "Laptop 53",
},
"laptop-54": {
type: "laptop",
label: "Laptop 54",
},
"laptop-55": {
type: "laptop",
label: "Laptop 55",
},
"laptop-56": {
type: "laptop",
label: "Laptop 56",
},
"laptop-57": {
type: "laptop",
label: "Laptop 57",
},
"laptop-58": {
type: "laptop",
label: "Laptop 58",
},
"laptop-59": {
type: "laptop",
label: "Laptop 59",
},
"laptop-60": {
type: "laptop",
label: "Laptop 60",
},
"laptop-61": {
type: "laptop",
label: "Laptop 61",
},
"laptop-62": {
type: "laptop",
label: "Laptop 62",
},
"laptop-63": {
type: "laptop",
label: "Laptop 63",
},
"laptop-64": {
type: "laptop",
label: "Laptop 64",
},
"laptop-65": {
type: "laptop",
label: "Laptop 65",
},
"laptop-66": {
type: "laptop",
label: "Laptop 66",
},
"laptop-67": {
type: "laptop",
label: "Laptop 67",
},
"laptop-68": {
type: "laptop",
label: "Laptop 68",
},
"laptop-69": {
type: "laptop",
label: "Laptop 69",
},
"laptop-70": {
type: "laptop",
label: "Laptop 70",
},
"laptop-71": {
type: "laptop",
label: "Laptop 71",
},
"laptop-72": {
type: "laptop",
label: "Laptop 72",
},
"laptop-73": {
type: "laptop",
label: "Laptop 73",
},
"laptop-74": {
type: "laptop",
label: "Laptop 74",
},
"laptop-75": {
type: "laptop",
label: "Laptop 75",
},
"laptop-76": {
type: "laptop",
label: "Laptop 76",
},
"laptop-77": {
type: "laptop",
label: "Laptop 77",
},
"laptop-78": {
type: "laptop",
label: "Laptop 78",
},
"laptop-79": {
type: "laptop",
label: "Laptop 79",
},
"laptop-80": {
type: "laptop",
label: "Laptop 80",
},
"laptop-81": {
type: "laptop",
label: "Laptop 81",
},
"laptop-82": {
type: "laptop",
label: "Laptop 82",
},
"laptop-83": {
type: "laptop",
label: "Laptop 83",
},
"laptop-84": {
type: "laptop",
label: "Laptop 84",
},
"laptop-85": {
type: "laptop",
label: "Laptop 85",
},
"laptop-86": {
type: "laptop",
label: "Laptop 86",
},
"laptop-87": {
type: "laptop",
label: "Laptop 87",
},
"laptop-88": {
type: "laptop",
label: "Laptop 88",
},
"laptop-89": {
type: "laptop",
label: "Laptop 89",
},
"laptop-90": {
type: "laptop",
label: "Laptop 90",
},
"laptop-91": {
type: "laptop",
label: "Laptop 91",
},
"laptop-92": {
type: "laptop",
label: "Laptop 92",
},
"laptop-93": {
type: "laptop",
label: "Laptop 93",
},
"laptop-94": {
type: "laptop",
label: "Laptop 94",
},
"laptop-95": {
type: "laptop",
label: "Laptop 95",
},
"laptop-96": {
type: "laptop",
label: "Laptop 96",
},
"laptop-97": {
type: "laptop",
label: "Laptop 97",
},
"laptop-98": {
type: "laptop",
label: "Laptop 98",
},
"laptop-99": {
type: "laptop",
label: "Laptop 99",
},
"laptop-100": {
type: "laptop",
label: "Laptop 100",
},
"laptop-101": {
type: "laptop",
label: "Laptop 101",
},
"laptop-102": {
type: "laptop",
label: "Laptop 102",
},
"laptop-103": {
type: "laptop",
label: "Laptop 103",
},
"laptop-104": {
type: "laptop",
label: "Laptop 104",
},
"laptop-105": {
type: "laptop",
label: "Laptop 105",
},
"laptop-106": {
type: "laptop",
label: "Laptop 106",
},
"laptop-107": {
type: "laptop",
label: "Laptop 107",
},
"laptop-108": {
type: "laptop",
label: "Laptop 108",
},
"laptop-109": {
type: "laptop",
label: "Laptop 109",
},
"laptop-110": {
type: "laptop",
label: "Laptop 110",
},
"laptop-111": {
type: "laptop",
label: "Laptop 111",
},
"laptop-112": {
type: "laptop",
label: "Laptop 112",
},
"laptop-113": {
type: "laptop",
label: "Laptop 113",
},
"laptop-114": {
type: "laptop",
label: "Laptop 114",
},
"laptop-115": {
type: "laptop",
label: "Laptop 115",
},
"laptop-116": {
type: "laptop",
label: "Laptop 116",
},
"laptop-117": {
type: "laptop",
label: "Laptop 117",
},
"laptop-118": {
type: "laptop",
label: "Laptop 118",
},
"laptop-119": {
type: "laptop",
label: "Laptop 119",
},
"laptop-120": {
type: "laptop",
label: "Laptop 120",
},
"laptop-121": {
type: "laptop",
label: "Laptop 121",
},
"laptop-122": {
type: "laptop",
label: "Laptop 122",
},
"laptop-123": {
type: "laptop",
label: "Laptop 123",
},
"laptop-124": {
type: "laptop",
label: "Laptop 124",
},
"laptop-125": {
type: "laptop",
label: "Laptop 125",
},
"laptop-126": {
type: "laptop",
label: "Laptop 126",
},
"laptop-127": {
type: "laptop",
label: "Laptop 127",
},
"laptop-128": {
type: "laptop",
label: "Laptop 128",
},
"laptop-129": {
type: "laptop",
label: "Laptop 129",
},
"laptop-130": {
type: "laptop",
label: "Laptop 130",
},
"laptop-131": {
type: "laptop",
label: "Laptop 131",
},
"laptop-132": {
type: "laptop",
label: "Laptop 132",
},
"laptop-133": {
type: "laptop",
label: "Laptop 133",
},
"laptop-134": {
type: "laptop",
label: "Laptop 134",
},
"laptop-135": {
type: "laptop",
label: "Laptop 135",
},
"laptop-136": {
type: "laptop",
label: "Laptop 136",
},
"laptop-137": {
type: "laptop",
label: "Laptop 137",
},
"laptop-138": {
type: "laptop",
label: "Laptop 138",
},
"laptop-139": {
type: "laptop",
label: "Laptop 139",
},
"laptop-140": {
type: "laptop",
label: "Laptop 140",
},
"laptop-141": {
type: "laptop",
label: "Laptop 141",
},
"laptop-142": {
type: "laptop",
label: "Laptop 142",
},
"laptop-143": {
type: "laptop",
label: "Laptop 143",
},
"laptop-144": {
type: "laptop",
label: "Laptop 144",
},
"laptop-145": {
type: "laptop",
label: "Laptop 145",
},
"laptop-146": {
type: "laptop",
label: "Laptop 146",
},
"laptop-147": {
type: "laptop",
label: "Laptop 147",
},
"laptop-148": {
type: "laptop",
label: "Laptop 148",
},
"laptop-149": {
type: "laptop",
label: "Laptop 149",
},
"laptop-150": {
type: "laptop",
label: "Laptop 150",
},
"laptop-151": {
type: "laptop",
label: "Laptop 151",
},
"laptop-152": {
type: "laptop",
label: "Laptop 152",
},
"laptop-153": {
type: "laptop",
label: "Laptop 153",
},
"laptop-154": {
type: "laptop",
label: "Laptop 154",
},
"laptop-155": {
type: "laptop",
label: "Laptop 155",
},
"laptop-156": {
type: "laptop",
label: "Laptop 156",
},
"laptop-157": {
type: "laptop",
label: "Laptop 157",
},
"laptop-158": {
type: "laptop",
label: "Laptop 158",
},
"laptop-159": {
type: "laptop",
label: "Laptop 159",
},
"laptop-160": {
type: "laptop",
label: "Laptop 160",
},
"laptop-161": {
type: "laptop",
label: "Laptop 161",
},
"laptop-162": {
type: "laptop",
label: "Laptop 162",
},
"laptop-163": {
type: "laptop",
label: "Laptop 163",
},
"laptop-164": {
type: "laptop",
label: "Laptop 164",
},
"laptop-165": {
type: "laptop",
label: "Laptop 165",
},
"laptop-166": {
type: "laptop",
label: "Laptop 166",
},
"laptop-167": {
type: "laptop",
label: "Laptop 167",
},
"laptop-168": {
type: "laptop",
label: "Laptop 168",
},
"laptop-169": {
type: "laptop",
label: "Laptop 169",
},
"laptop-170": {
type: "laptop",
label: "Laptop 170",
},
"laptop-171": {
type: "laptop",
label: "Laptop 171",
},
"laptop-172": {
type: "laptop",
label: "Laptop 172",
},
"laptop-173": {
type: "laptop",
label: "Laptop 173",
},
"laptop-174": {
type: "laptop",
label: "Laptop 174",
},
"laptop-175": {
type: "laptop",
label: "Laptop 175",
},
"laptop-176": {
type: "laptop",
label: "Laptop 176",
},
"laptop-177": {
type: "laptop",
label: "Laptop 177",
},
"laptop-178": {
type: "laptop",
label: "Laptop 178",
},
"laptop-179": {
type: "laptop",
label: "Laptop 179",
},
"laptop-180": {
type: "laptop",
label: "Laptop 180",
},
"laptop-181": {
type: "laptop",
label: "Laptop 181",
},
"laptop-182": {
type: "laptop",
label: "Laptop 182",
},
"laptop-183": {
type: "laptop",
label: "Laptop 183",
},
"laptop-184": {
type: "laptop",
label: "Laptop 184",
},
"laptop-185": {
type: "laptop",
label: "Laptop 185",
},
"laptop-186": {
type: "laptop",
label: "Laptop 186",
},
"laptop-187": {
type: "laptop",
label: "Laptop 187",
},
"laptop-188": {
type: "laptop",
label: "Laptop 188",
},
"laptop-189": {
type: "laptop",
label: "Laptop 189",
},
"laptop-190": {
type: "laptop",
label: "Laptop 190",
},
"laptop-191": {
type: "laptop",
label: "Laptop 191",
},
"laptop-192": {
type: "laptop",
label: "Laptop 192",
},
"laptop-193": {
type: "laptop",
label: "Laptop 193",
},
"laptop-194": {
type: "laptop",
label: "Laptop 194",
},
"laptop-195": {
type: "laptop",
label: "Laptop 195",
},
"laptop-196": {
type: "laptop",
label: "Laptop 196",
},
"laptop-197": {
type: "laptop",
label: "Laptop 197",
},
"laptop-198": {
type: "laptop",
label: "Laptop 198",
},
"laptop-199": {
type: "laptop",
label: "Laptop 199",
},
"laptop-200": {
type: "laptop",
label: "Laptop 200",
},
"laptop-201": {
type: "laptop",
label: "Laptop 201",
},
"laptop-202": {
type: "laptop",
label: "Laptop 202",
},
"laptop-203": {
type: "laptop",
label: "Laptop 203",
},
"laptop-204": {
type: "laptop",
label: "Laptop 204",
},
"laptop-205": {
type: "laptop",
label: "Laptop 205",
},
"laptop-206": {
type: "laptop",
label: "Laptop 206",
},
"laptop-207": {
type: "laptop",
label: "Laptop 207",
},
"laptop-208": {
type: "laptop",
label: "Laptop 208",
},
"laptop-209": {
type: "laptop",
label: "Laptop 209",
},
"laptop-210": {
type: "laptop",
label: "Laptop 210",
},
"laptop-211": {
type: "laptop",
label: "Laptop 211",
},
"laptop-212": {
type: "laptop",
label: "Laptop 212",
},
"laptop-213": {
type: "laptop",
label: "Laptop 213",
},
"laptop-214": {
type: "laptop",
label: "Laptop 214",
},
"laptop-215": {
type: "laptop",
label: "Laptop 215",
},
"laptop-216": {
type: "laptop",
label: "Laptop 216",
},
"laptop-217": {
type: "laptop",
label: "Laptop 217",
},
"laptop-218": {
type: "laptop",
label: "Laptop 218",
},
"laptop-219": {
type: "laptop",
label: "Laptop 219",
},
"laptop-220": {
type: "laptop",
label: "Laptop 220",
},
"laptop-221": {
type: "laptop",
label: "Laptop 221",
},
"laptop-222": {
type: "laptop",
label: "Laptop 222",
},
"laptop-223": {
type: "laptop",
label: "Laptop 223",
},
"laptop-224": {
type: "laptop",
label: "Laptop 224",
},
"laptop-225": {
type: "laptop",
label: "Laptop 225",
},
"laptop-226": {
type: "laptop",
label: "Laptop 226",
},
"laptop-227": {
type: "laptop",
label: "Laptop 227",
},
"laptop-228": {
type: "laptop",
label: "Laptop 228",
},
"laptop-229": {
type: "laptop",
label: "Laptop 229",
},
"laptop-230": {
type: "laptop",
label: "Laptop 230",
},
"laptop-231": {
type: "laptop",
label: "Laptop 231",
},
"laptop-232": {
type: "laptop",
label: "Laptop 232",
},
"laptop-233": {
type: "laptop",
label: "Laptop 233",
},
"laptop-234": {
type: "laptop",
label: "Laptop 234",
},
"laptop-235": {
type: "laptop",
label: "Laptop 235",
},
"laptop-236": {
type: "laptop",
label: "Laptop 236",
},
"laptop-237": {
type: "laptop",
label: "Laptop 237",
},
"laptop-238": {
type: "laptop",
label: "Laptop 238",
},
"laptop-239": {
type: "laptop",
label: "Laptop 239",
},
"laptop-240": {
type: "laptop",
label: "Laptop 240",
},
"laptop-241": {
type: "laptop",
label: "Laptop 241",
},
"laptop-242": {
type: "laptop",
label: "Laptop 242",
},
"laptop-243": {
type: "laptop",
label: "Laptop 243",
// ...truncated 27732 lines <!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="/public/fonts/fontawesome-free/css/all.css" />
<link rel="stylesheet" href="@ci/theme/kg/css/examples.css" />
<link rel="stylesheet" href="./style.css" />
</head>
<body>
<div class="story">
<div class="story__timeline" id="my-timeline"></div>
<div class="story__controls story__controls--row">
<div class="stack">
<label for="delay-select">Additional Loading Latency</label>
<select id="delay-select" class="select">
<option value="0" selected>None</option>
<option value="500">500ms</option>
<option value="1000">1000ms</option>
<option value="2000">2000ms</option>
</select>
</div>
<div class="stack">
<p class="story__controls__heading" id="event-info"></p>
</div>
</div>
</div>
<script type="module" src="./code.js"></script>
</body>
</html> .story__loading__cursor canvas {
cursor: progress !important;
} import React, { useEffect, useState } from "react";
import { createRoot } from "react-dom/client";
import Timeline from "kronograph/react/Timeline";
import data from "./data";
const oneWeek = 7 * 24 * 60 * 60 * 1000; // a week in milliseconds
const weeksToShow = 2;
const initialRange = oneWeek * weeksToShow;
const options = {
events: {
heatmapThreshold: 200,
},
scales: {
panLimit: "off",
zoomOutLimit: {
unit: "week",
value: weeksToShow,
},
},
};
const {
metadata,
entityTypes,
eventTypes,
entities,
events: eventsArray,
} = data;
const firstEventTime = metadata.firstEventTime;
const lastEventTime = metadata.lastEventTime;
const dataTimeWidth = lastEventTime - firstEventTime;
const weeksOfDataToLoad = 4;
// convert to UTC milliseconds
// see https://kronograph.io/docs#milliseconds for details
function dateToMilliseconds(date) {
return Date.UTC(
date.getFullYear(),
date.getMonth(),
date.getDate(),
date.getHours(),
date.getMinutes(),
date.getSeconds(),
date.getMilliseconds(),
);
}
export const Demo = () => {
const [events, setEvents] = useState();
const [eventCount, setEventCount] = useState(0);
const [latency, setLatency] = useState(0);
const [loading, setLoading] = useState(false);
useEffect(() => {
setLoading(true);
const { events: initialEvents, eventCount: initialEventCount } =
getEventsWithBuffer(firstEventTime, firstEventTime + initialRange);
setEvents(initialEvents);
setEventCount(initialEventCount);
setLoading(false);
}, []);
const getEventsWithBuffer = (start, end) => {
const buffer = Math.floor(end - start) / 2;
return getEvents(Math.max(start - buffer, firstEventTime), end + buffer);
};
const onTimelineChange = ({ range, why }) => {
if (range !== undefined && why === "user") {
const start = dateToMilliseconds(range.start);
const end = dateToMilliseconds(range.end);
setLoading(true);
const { events: newEvents, eventCount: newEventCount } =
getEventsWithBuffer(start, end);
const loadData = () => {
setEvents(newEvents);
setEventCount(newEventCount);
setLoading(false);
};
if (latency > 0) {
setTimeout(loadData, latency);
} else {
loadData();
}
}
};
return (
<div className="story">
<Timeline
className={`story__timeline ${loading && "story__loading__cursor"}`}
entityTypes={entityTypes}
eventTypes={eventTypes}
entities={entities}
events={events}
options={options}
onTimelineChange={onTimelineChange}
/>
<div className="story__controls story__controls--row">
<div className="stack">
<label htmlFor="delay-select">Additional Loading Latency</label>
<select
className="select"
value={latency}
onChange={(e) => {
setLatency(e.target.value);
}}
>
<option value="0">None</option>
<option value="500">500ms</option>
<option value="1000">1000ms</option>
<option value="2000">2000ms</option>
</select>
</div>
<div className="stack">
<p className="story__controls__heading">
{`${eventCount.toLocaleString()} Events currently loaded`}
</p>
</div>
</div>
</div>
);
};
/// /////////////////////////////////////////////////////////////////////////
// the code below is used to simulate fetching event data from a database //
/// /////////////////////////////////////////////////////////////////////////
function toIndex(items) {
return items.reduce((result, item) => {
const { id, ...itemWithoutId } = item;
result[id] = itemWithoutId;
return result;
}, {});
}
function offsetEvents(eventArray, offset) {
return eventArray.map((event) => {
return {
...event,
id: `${event.id}-${offset}`,
time: event.time + dataTimeWidth * offset,
};
});
}
// simulate fetching data incrementally from a database
function getEvents(requestedStartTime, requestedEndTime) {
const startTimeOffset = requestedStartTime - firstEventTime;
const offsetFactor = Math.floor(startTimeOffset / dataTimeWidth);
let newEvents = [];
// a full weeks worth of data is loaded in and then repeated for enough weeks to fill the view range when fully zoomed out
for (let i = 0; i < weeksOfDataToLoad; i++) {
newEvents = newEvents.concat(offsetEvents(eventsArray, offsetFactor + i));
}
const firstEventIndex = newEvents.findIndex(
(event) => event.time >= requestedStartTime,
);
const lastEventIndex = newEvents.findIndex(
(event) => event.time >= requestedEndTime,
);
newEvents = newEvents.slice(firstEventIndex, lastEventIndex);
return { events: toIndex(newEvents), eventCount: newEvents.length };
}
const root = createRoot(document.getElementById("my-timeline"));
root.render(<Demo />); export default {
metadata: {
firstEventTime: 1578197001722.3477,
lastEventTime: 1578852737532.8713,
},
entityTypes: {
laptop: {
typeLabel: "Client Devices",
},
server: {
typeLabel: "Cloud Infrastructure",
},
},
eventTypes: {
logOn: {
color: "#27ab83",
},
logOff: {
color: "#f58a3d",
},
updateInstalled: {
color: "#f7d06e",
},
},
entities: {
"laptop-0": {
type: "laptop",
label: "Laptop 0",
},
"laptop-1": {
type: "laptop",
label: "Laptop 1",
},
"laptop-2": {
type: "laptop",
label: "Laptop 2",
},
"laptop-3": {
type: "laptop",
label: "Laptop 3",
},
"laptop-4": {
type: "laptop",
label: "Laptop 4",
},
"laptop-5": {
type: "laptop",
label: "Laptop 5",
},
"laptop-6": {
type: "laptop",
label: "Laptop 6",
},
"laptop-7": {
type: "laptop",
label: "Laptop 7",
},
"laptop-8": {
type: "laptop",
label: "Laptop 8",
},
"laptop-9": {
type: "laptop",
label: "Laptop 9",
},
"laptop-10": {
type: "laptop",
label: "Laptop 10",
},
"laptop-11": {
type: "laptop",
label: "Laptop 11",
},
"laptop-12": {
type: "laptop",
label: "Laptop 12",
},
"laptop-13": {
type: "laptop",
label: "Laptop 13",
},
"laptop-14": {
type: "laptop",
label: "Laptop 14",
},
"laptop-15": {
type: "laptop",
label: "Laptop 15",
},
"laptop-16": {
type: "laptop",
label: "Laptop 16",
},
"laptop-17": {
type: "laptop",
label: "Laptop 17",
},
"laptop-18": {
type: "laptop",
label: "Laptop 18",
},
"laptop-19": {
type: "laptop",
label: "Laptop 19",
},
"laptop-20": {
type: "laptop",
label: "Laptop 20",
},
"laptop-21": {
type: "laptop",
label: "Laptop 21",
},
"laptop-22": {
type: "laptop",
label: "Laptop 22",
},
"laptop-23": {
type: "laptop",
label: "Laptop 23",
},
"laptop-24": {
type: "laptop",
label: "Laptop 24",
},
"laptop-25": {
type: "laptop",
label: "Laptop 25",
},
"laptop-26": {
type: "laptop",
label: "Laptop 26",
},
"laptop-27": {
type: "laptop",
label: "Laptop 27",
},
"laptop-28": {
type: "laptop",
label: "Laptop 28",
},
"laptop-29": {
type: "laptop",
label: "Laptop 29",
},
"laptop-30": {
type: "laptop",
label: "Laptop 30",
},
"laptop-31": {
type: "laptop",
label: "Laptop 31",
},
"laptop-32": {
type: "laptop",
label: "Laptop 32",
},
"laptop-33": {
type: "laptop",
label: "Laptop 33",
},
"laptop-34": {
type: "laptop",
label: "Laptop 34",
},
"laptop-35": {
type: "laptop",
label: "Laptop 35",
},
"laptop-36": {
type: "laptop",
label: "Laptop 36",
},
"laptop-37": {
type: "laptop",
label: "Laptop 37",
},
"laptop-38": {
type: "laptop",
label: "Laptop 38",
},
"laptop-39": {
type: "laptop",
label: "Laptop 39",
},
"laptop-40": {
type: "laptop",
label: "Laptop 40",
},
"laptop-41": {
type: "laptop",
label: "Laptop 41",
},
"laptop-42": {
type: "laptop",
label: "Laptop 42",
},
"laptop-43": {
type: "laptop",
label: "Laptop 43",
},
"laptop-44": {
type: "laptop",
label: "Laptop 44",
},
"laptop-45": {
type: "laptop",
label: "Laptop 45",
},
"laptop-46": {
type: "laptop",
label: "Laptop 46",
},
"laptop-47": {
type: "laptop",
label: "Laptop 47",
},
"laptop-48": {
type: "laptop",
label: "Laptop 48",
},
"laptop-49": {
type: "laptop",
label: "Laptop 49",
},
"laptop-50": {
type: "laptop",
label: "Laptop 50",
},
"laptop-51": {
type: "laptop",
label: "Laptop 51",
},
"laptop-52": {
type: "laptop",
label: "Laptop 52",
},
"laptop-53": {
type: "laptop",
label: "Laptop 53",
},
"laptop-54": {
type: "laptop",
label: "Laptop 54",
},
"laptop-55": {
type: "laptop",
label: "Laptop 55",
},
"laptop-56": {
type: "laptop",
label: "Laptop 56",
},
"laptop-57": {
type: "laptop",
label: "Laptop 57",
},
"laptop-58": {
type: "laptop",
label: "Laptop 58",
},
"laptop-59": {
type: "laptop",
label: "Laptop 59",
},
"laptop-60": {
type: "laptop",
label: "Laptop 60",
},
"laptop-61": {
type: "laptop",
label: "Laptop 61",
},
"laptop-62": {
type: "laptop",
label: "Laptop 62",
},
"laptop-63": {
type: "laptop",
label: "Laptop 63",
},
"laptop-64": {
type: "laptop",
label: "Laptop 64",
},
"laptop-65": {
type: "laptop",
label: "Laptop 65",
},
"laptop-66": {
type: "laptop",
label: "Laptop 66",
},
"laptop-67": {
type: "laptop",
label: "Laptop 67",
},
"laptop-68": {
type: "laptop",
label: "Laptop 68",
},
"laptop-69": {
type: "laptop",
label: "Laptop 69",
},
"laptop-70": {
type: "laptop",
label: "Laptop 70",
},
"laptop-71": {
type: "laptop",
label: "Laptop 71",
},
"laptop-72": {
type: "laptop",
label: "Laptop 72",
},
"laptop-73": {
type: "laptop",
label: "Laptop 73",
},
"laptop-74": {
type: "laptop",
label: "Laptop 74",
},
"laptop-75": {
type: "laptop",
label: "Laptop 75",
},
"laptop-76": {
type: "laptop",
label: "Laptop 76",
},
"laptop-77": {
type: "laptop",
label: "Laptop 77",
},
"laptop-78": {
type: "laptop",
label: "Laptop 78",
},
"laptop-79": {
type: "laptop",
label: "Laptop 79",
},
"laptop-80": {
type: "laptop",
label: "Laptop 80",
},
"laptop-81": {
type: "laptop",
label: "Laptop 81",
},
"laptop-82": {
type: "laptop",
label: "Laptop 82",
},
"laptop-83": {
type: "laptop",
label: "Laptop 83",
},
"laptop-84": {
type: "laptop",
label: "Laptop 84",
},
"laptop-85": {
type: "laptop",
label: "Laptop 85",
},
"laptop-86": {
type: "laptop",
label: "Laptop 86",
},
"laptop-87": {
type: "laptop",
label: "Laptop 87",
},
"laptop-88": {
type: "laptop",
label: "Laptop 88",
},
"laptop-89": {
type: "laptop",
label: "Laptop 89",
},
"laptop-90": {
type: "laptop",
label: "Laptop 90",
},
"laptop-91": {
type: "laptop",
label: "Laptop 91",
},
"laptop-92": {
type: "laptop",
label: "Laptop 92",
},
"laptop-93": {
type: "laptop",
label: "Laptop 93",
},
"laptop-94": {
type: "laptop",
label: "Laptop 94",
},
"laptop-95": {
type: "laptop",
label: "Laptop 95",
},
"laptop-96": {
type: "laptop",
label: "Laptop 96",
},
"laptop-97": {
type: "laptop",
label: "Laptop 97",
},
"laptop-98": {
type: "laptop",
label: "Laptop 98",
},
"laptop-99": {
type: "laptop",
label: "Laptop 99",
},
"laptop-100": {
type: "laptop",
label: "Laptop 100",
},
"laptop-101": {
type: "laptop",
label: "Laptop 101",
},
"laptop-102": {
type: "laptop",
label: "Laptop 102",
},
"laptop-103": {
type: "laptop",
label: "Laptop 103",
},
"laptop-104": {
type: "laptop",
label: "Laptop 104",
},
"laptop-105": {
type: "laptop",
label: "Laptop 105",
},
"laptop-106": {
type: "laptop",
label: "Laptop 106",
},
"laptop-107": {
type: "laptop",
label: "Laptop 107",
},
"laptop-108": {
type: "laptop",
label: "Laptop 108",
},
"laptop-109": {
type: "laptop",
label: "Laptop 109",
},
"laptop-110": {
type: "laptop",
label: "Laptop 110",
},
"laptop-111": {
type: "laptop",
label: "Laptop 111",
},
"laptop-112": {
type: "laptop",
label: "Laptop 112",
},
"laptop-113": {
type: "laptop",
label: "Laptop 113",
},
"laptop-114": {
type: "laptop",
label: "Laptop 114",
},
"laptop-115": {
type: "laptop",
label: "Laptop 115",
},
"laptop-116": {
type: "laptop",
label: "Laptop 116",
},
"laptop-117": {
type: "laptop",
label: "Laptop 117",
},
"laptop-118": {
type: "laptop",
label: "Laptop 118",
},
"laptop-119": {
type: "laptop",
label: "Laptop 119",
},
"laptop-120": {
type: "laptop",
label: "Laptop 120",
},
"laptop-121": {
type: "laptop",
label: "Laptop 121",
},
"laptop-122": {
type: "laptop",
label: "Laptop 122",
},
"laptop-123": {
type: "laptop",
label: "Laptop 123",
},
"laptop-124": {
type: "laptop",
label: "Laptop 124",
},
"laptop-125": {
type: "laptop",
label: "Laptop 125",
},
"laptop-126": {
type: "laptop",
label: "Laptop 126",
},
"laptop-127": {
type: "laptop",
label: "Laptop 127",
},
"laptop-128": {
type: "laptop",
label: "Laptop 128",
},
"laptop-129": {
type: "laptop",
label: "Laptop 129",
},
"laptop-130": {
type: "laptop",
label: "Laptop 130",
},
"laptop-131": {
type: "laptop",
label: "Laptop 131",
},
"laptop-132": {
type: "laptop",
label: "Laptop 132",
},
"laptop-133": {
type: "laptop",
label: "Laptop 133",
},
"laptop-134": {
type: "laptop",
label: "Laptop 134",
},
"laptop-135": {
type: "laptop",
label: "Laptop 135",
},
"laptop-136": {
type: "laptop",
label: "Laptop 136",
},
"laptop-137": {
type: "laptop",
label: "Laptop 137",
},
"laptop-138": {
type: "laptop",
label: "Laptop 138",
},
"laptop-139": {
type: "laptop",
label: "Laptop 139",
},
"laptop-140": {
type: "laptop",
label: "Laptop 140",
},
"laptop-141": {
type: "laptop",
label: "Laptop 141",
},
"laptop-142": {
type: "laptop",
label: "Laptop 142",
},
"laptop-143": {
type: "laptop",
label: "Laptop 143",
},
"laptop-144": {
type: "laptop",
label: "Laptop 144",
},
"laptop-145": {
type: "laptop",
label: "Laptop 145",
},
"laptop-146": {
type: "laptop",
label: "Laptop 146",
},
"laptop-147": {
type: "laptop",
label: "Laptop 147",
},
"laptop-148": {
type: "laptop",
label: "Laptop 148",
},
"laptop-149": {
type: "laptop",
label: "Laptop 149",
},
"laptop-150": {
type: "laptop",
label: "Laptop 150",
},
"laptop-151": {
type: "laptop",
label: "Laptop 151",
},
"laptop-152": {
type: "laptop",
label: "Laptop 152",
},
"laptop-153": {
type: "laptop",
label: "Laptop 153",
},
"laptop-154": {
type: "laptop",
label: "Laptop 154",
},
"laptop-155": {
type: "laptop",
label: "Laptop 155",
},
"laptop-156": {
type: "laptop",
label: "Laptop 156",
},
"laptop-157": {
type: "laptop",
label: "Laptop 157",
},
"laptop-158": {
type: "laptop",
label: "Laptop 158",
},
"laptop-159": {
type: "laptop",
label: "Laptop 159",
},
"laptop-160": {
type: "laptop",
label: "Laptop 160",
},
"laptop-161": {
type: "laptop",
label: "Laptop 161",
},
"laptop-162": {
type: "laptop",
label: "Laptop 162",
},
"laptop-163": {
type: "laptop",
label: "Laptop 163",
},
"laptop-164": {
type: "laptop",
label: "Laptop 164",
},
"laptop-165": {
type: "laptop",
label: "Laptop 165",
},
"laptop-166": {
type: "laptop",
label: "Laptop 166",
},
"laptop-167": {
type: "laptop",
label: "Laptop 167",
},
"laptop-168": {
type: "laptop",
label: "Laptop 168",
},
"laptop-169": {
type: "laptop",
label: "Laptop 169",
},
"laptop-170": {
type: "laptop",
label: "Laptop 170",
},
"laptop-171": {
type: "laptop",
label: "Laptop 171",
},
"laptop-172": {
type: "laptop",
label: "Laptop 172",
},
"laptop-173": {
type: "laptop",
label: "Laptop 173",
},
"laptop-174": {
type: "laptop",
label: "Laptop 174",
},
"laptop-175": {
type: "laptop",
label: "Laptop 175",
},
"laptop-176": {
type: "laptop",
label: "Laptop 176",
},
"laptop-177": {
type: "laptop",
label: "Laptop 177",
},
"laptop-178": {
type: "laptop",
label: "Laptop 178",
},
"laptop-179": {
type: "laptop",
label: "Laptop 179",
},
"laptop-180": {
type: "laptop",
label: "Laptop 180",
},
"laptop-181": {
type: "laptop",
label: "Laptop 181",
},
"laptop-182": {
type: "laptop",
label: "Laptop 182",
},
"laptop-183": {
type: "laptop",
label: "Laptop 183",
},
"laptop-184": {
type: "laptop",
label: "Laptop 184",
},
"laptop-185": {
type: "laptop",
label: "Laptop 185",
},
"laptop-186": {
type: "laptop",
label: "Laptop 186",
},
"laptop-187": {
type: "laptop",
label: "Laptop 187",
},
"laptop-188": {
type: "laptop",
label: "Laptop 188",
},
"laptop-189": {
type: "laptop",
label: "Laptop 189",
},
"laptop-190": {
type: "laptop",
label: "Laptop 190",
},
"laptop-191": {
type: "laptop",
label: "Laptop 191",
},
"laptop-192": {
type: "laptop",
label: "Laptop 192",
},
"laptop-193": {
type: "laptop",
label: "Laptop 193",
},
"laptop-194": {
type: "laptop",
label: "Laptop 194",
},
"laptop-195": {
type: "laptop",
label: "Laptop 195",
},
"laptop-196": {
type: "laptop",
label: "Laptop 196",
},
"laptop-197": {
type: "laptop",
label: "Laptop 197",
},
"laptop-198": {
type: "laptop",
label: "Laptop 198",
},
"laptop-199": {
type: "laptop",
label: "Laptop 199",
},
"laptop-200": {
type: "laptop",
label: "Laptop 200",
},
"laptop-201": {
type: "laptop",
label: "Laptop 201",
},
"laptop-202": {
type: "laptop",
label: "Laptop 202",
},
"laptop-203": {
type: "laptop",
label: "Laptop 203",
},
"laptop-204": {
type: "laptop",
label: "Laptop 204",
},
"laptop-205": {
type: "laptop",
label: "Laptop 205",
},
"laptop-206": {
type: "laptop",
label: "Laptop 206",
},
"laptop-207": {
type: "laptop",
label: "Laptop 207",
},
"laptop-208": {
type: "laptop",
label: "Laptop 208",
},
"laptop-209": {
type: "laptop",
label: "Laptop 209",
},
"laptop-210": {
type: "laptop",
label: "Laptop 210",
},
"laptop-211": {
type: "laptop",
label: "Laptop 211",
},
"laptop-212": {
type: "laptop",
label: "Laptop 212",
},
"laptop-213": {
type: "laptop",
label: "Laptop 213",
},
"laptop-214": {
type: "laptop",
label: "Laptop 214",
},
"laptop-215": {
type: "laptop",
label: "Laptop 215",
},
"laptop-216": {
type: "laptop",
label: "Laptop 216",
},
"laptop-217": {
type: "laptop",
label: "Laptop 217",
},
"laptop-218": {
type: "laptop",
label: "Laptop 218",
},
"laptop-219": {
type: "laptop",
label: "Laptop 219",
},
"laptop-220": {
type: "laptop",
label: "Laptop 220",
},
"laptop-221": {
type: "laptop",
label: "Laptop 221",
},
"laptop-222": {
type: "laptop",
label: "Laptop 222",
},
"laptop-223": {
type: "laptop",
label: "Laptop 223",
},
"laptop-224": {
type: "laptop",
label: "Laptop 224",
},
"laptop-225": {
type: "laptop",
label: "Laptop 225",
},
"laptop-226": {
type: "laptop",
label: "Laptop 226",
},
"laptop-227": {
type: "laptop",
label: "Laptop 227",
},
"laptop-228": {
type: "laptop",
label: "Laptop 228",
},
"laptop-229": {
type: "laptop",
label: "Laptop 229",
},
"laptop-230": {
type: "laptop",
label: "Laptop 230",
},
"laptop-231": {
type: "laptop",
label: "Laptop 231",
},
"laptop-232": {
type: "laptop",
label: "Laptop 232",
},
"laptop-233": {
type: "laptop",
label: "Laptop 233",
},
"laptop-234": {
type: "laptop",
label: "Laptop 234",
},
"laptop-235": {
type: "laptop",
label: "Laptop 235",
},
"laptop-236": {
type: "laptop",
label: "Laptop 236",
},
"laptop-237": {
type: "laptop",
label: "Laptop 237",
},
"laptop-238": {
type: "laptop",
label: "Laptop 238",
},
"laptop-239": {
type: "laptop",
label: "Laptop 239",
},
"laptop-240": {
type: "laptop",
label: "Laptop 240",
},
"laptop-241": {
type: "laptop",
label: "Laptop 241",
},
"laptop-242": {
type: "laptop",
label: "Laptop 242",
},
"laptop-243": {
type: "laptop",
label: "Laptop 243",
// ...truncated 27732 lines <!doctype html>
<html>
<head>
<link rel="stylesheet" href="@ci/theme/kg/css/examples.css" />
<link rel="stylesheet" href="./style.css" />
</head>
<body>
<div id="my-timeline" style="height: 100vh"></div>
<script type="module" src="./code.jsx"></script>
</body>
</html> .story__loading__cursor canvas {
cursor: progress !important;
}