Getting Started
Build your first interactive timeline in minutes.
Installation
1. Install from npm
For bundlers and ESM-capable runtimes, install the package from npm:
npm install histropediajs
2. Load the library
Use ESM imports with a bundler, or load the UMD build from a CDN for script-tag embeds.
import Histropedia, { Timeline, Dmy } from 'histropediajs';
const container = document.getElementById('timeline');
const timeline = new Timeline(container);
console.log(Histropedia.Timeline === Timeline);
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
<script>
const container = document.getElementById('timeline');
const timeline = new Histropedia.Timeline(container);
</script>
<script type="module">
import Histropedia, { Timeline, Dmy } from 'https://cdn.jsdelivr.net/npm/[email protected]/dist/histropedia.esm.js';
const container = document.getElementById('timeline');
const timeline = new Timeline(container);
</script>
HistropediaJS is published as an ESM package for npm and bundlers. CommonJS
require('histropediajs') is not supported.
For non-module browser usage, use the UMD script-tag build shown above, or self-host
histropedia.umd.js / histropedia.umd.min.js.
TypeScript definitions are included with the npm package. The download bundle also includes
histropedia.esm.d.ts for direct ESM usage.
CDN URLs
For direct CDN imports, you can target the package default or a specific build file:
https://cdn.jsdelivr.net/npm/[email protected]
https://cdn.jsdelivr.net/npm/[email protected]/dist/histropedia.esm.js
https://cdn.jsdelivr.net/npm/[email protected]/dist/histropedia.umd.js
https://cdn.jsdelivr.net/npm/[email protected]/dist/histropedia.umd.min.js
Your First Timeline
With HistropediaJS loaded (see Installation), you're ready to render a timeline. Create a container element, instantiate the timeline, and load a few events.
<div id="timeline"></div>
import { Timeline } from 'histropediajs';
const container = document.getElementById('timeline');
const timeline = new Timeline(container, {
width: 1000,
height: 500,
initialDate: { year: 1989, month: 3, day: 12 },
zoom: { initial: 34 },
});
timeline.load([
{
id: 1,
title: 'Moon Landing',
subtitle: 'Apollo 11',
from: { year: 1969, month: 7, day: 16 },
to: { year: 1969, month: 7, day: 24 },
},
{
id: 2,
title: 'World Wide Web',
subtitle: 'Tim Berners-Lee proposal',
from: { year: 1989, month: 3, day: 12 },
},
{
id: 3,
title: 'iPhone Launch',
subtitle: 'Apple unveils the iPhone',
from: { year: 2007, month: 1, day: 9 },
},
]);
const { Timeline } = Histropedia;
const container = document.getElementById('timeline');
const timeline = new Timeline(container, {
width: 1000,
height: 500,
initialDate: { year: 1989, month: 3, day: 12 },
zoom: { initial: 34 },
});
timeline.load([
{
id: 'moon-landing',
title: 'Moon Landing',
subtitle: 'Apollo 11',
from: { year: 1969, month: 7, day: 16 },
to: { year: 1969, month: 7, day: 24 },
},
{
id: 'internet-created',
title: 'World Wide Web',
subtitle: 'Tim Berners-Lee proposal',
from: { year: 1989, month: 3, day: 12 },
},
{
id: 'iphone-launch',
title: 'iPhone Launch',
subtitle: 'Apple unveils the iPhone',
from: { year: 2007, month: 1, day: 9 },
},
]);
Congratulations!
You've rendered your first interactive timeline. Head to the configuration and data model sections to customize it further.
Core Concepts
Understand the core concepts that power HistropediaJS.
Timeline
The Timeline is the engine that renders and manages the interactive canvas. Creating a Timeline instance is the first step and provides the foundation for configuration, loaded Articles, Lanes, Time Bands, event listeners, and other features.
You can create multiple timelines on the same page, each with its own configuration, data, and render state.
API reference: Timeline Options, Timeline Methods
Article
An Article is a single item on the timeline, representing an event which may be an instant or a period of time. Articles are added to the timeline using the timeline.load method and follow the Article Schema.
Each Article appears as a card attached to a period line that represents its time span. Article options control behaviour and the type of card layout ("portrait", "landscape", or a custom layout) and article styles define the appearance for whichever layout has been selected.
API reference: Load Articles Method, Article Schema, Article Options, Article Style
Lane new
A Lane is a horizontal section for grouping related Articles while preserving one shared bottom timeline axis. Lane's have backgrounds which are created as DOM elements underneath the timeline canvas so they can easily be styled via CSS if preferred.
Define explicit lanes with options.lane.data or timeline.loadLanes, then load articles
usingtimeline.loadLaneArticles. Alternatively, use the standard timeline.load method with
a lane key on each article. Articles without a lane use options.lane.defaultId.
If an article references a lane id that has not been defined yet, HistropediaJS automatically creates an implicit
lane for that id.
You can also move an article between lanes after loading it with
article.setOption("lane", laneId).
API reference: Lane Options, Lane Schema, Lane Methods
Time Band new
A Time Band is a background band used to mark broad periods or eras, shown beneath the main timeline line by default.
Time Bands are loaded using the timeBand.data option or the timeline.loadTimeBands
method, following the Time Band schema.
API reference: Load Time Bands Method, Time Band Schema, Time Band Options, Time Band Style
Configuration
Control initialization and behavior via Timeline options, and nested options for Lanes, Articles, and Time Bands.
Timeline Options
An object containing all settings supported by the timeline. Any option not specified will use the default value.
The timeline options are the main root for all configuration. They include nested settings for controlling zoom, panning, Lanes, Articles, Time Bands, image loading, and styling (shown below with links in the comments).
All timeline options, including nested options, can be set at timeline initialization by passing the object
to the Timeline constructor. They can also be set at runtime using the setOption
timeline method.
// Core timeline options (defaults)
{
width: 1000,
height: 500,
verticalOffset: 40,
enableUserControl: true,
enableCursor: true,
draggingVicinity: true,
shiftBceDates: false,
initialDate: {
year: 1990,
month: 1,
day: 1,
},
canvas: { // new
dpr: 'auto',
dprMode: 'stable',
maxDpr: 3,
},
zoom: { /* See: Zoom Options */ },
pan: { /* See: Pan Options */ }, // new
article: { /* See: Article Options */ },
lane: { /* See: Lane Options */ }, // new
timeBand: { /* See: Time Band Options */ }, // new
image: { /* See: Image Options */ }, // new
style: { /* See: Timeline Style */ },
// Additional optional event handling:
// - on: { 'event-name': (...args) => { /* handler */ } } // new
// deprecated Legacy event handlers (since v1.3.0):
// - onRedraw
// - onArticleClick
// - onArticleDoubleClick
// - onSave
}
Zoom Options
Control the zoom behavior of the timeline, including initial level, limits and wheel behaviour.
These options live under options.zoom.*. The values shown below are the defaults.
// Zoom options (defaults)
{
initial: 34,
minimum: 0,
maximum: 123,
wheelStep: 0.2, // changed default
wheelSpeed: 3,
allowCtrlWheel: false, // new
wheelMode: 'auto', // new
discreteWheelAnimation: { // new
active: true,
duration: 250
},
proportionalGain: 2, // new
proportionalExponent: 1.1, // new
ratio: 0.8,
unitSize: {
initial: 200,
showMinorLabels: 48,
minimum: 8,
}
};
Pan Options new
Control drag-release momentum after a user pans the timeline viewport.
These options live under options.pan.*. The values shown below are the defaults.
// Pan options (defaults)
{
momentum: {
active: true,
sampleWindow: 100,
minVelocity: 0.01,
stopVelocity: 0.005,
friction: 0.005,
maxDuration: 5600
}
};
Article Options
Configure how articles (event cards) look and behave: stacking, period lines, animations, and default styles for normal, hover, and active states.
These options live under options.article.*. Defaults are shown below.
Tip
Exported constants and functions like DENSITY_ALL, RANGE_ALL, and ARTICLE_FROM_SORTER
are available in both build types:
- ESM:
import { DENSITY_ALL, RANGE_ALL } from 'histropediajs'; - UMD:
const { DENSITY_ALL, RANGE_ALL } = Histropedia;
// Article options (defaults)
{
density: DENSITY_ALL,
rendering: { // new
pixelSnap: 'device'
},
draggable: true,
distanceToBaseline: { // changed
value: 350,
responsive: {
active: true,
lanesOnly: true,
byCardLayout: {
portrait: { ratio: 0.6, min: 310, max: 410 },
landscape: { ratio: 0.6, min: 100, max: 160 }
}
}
},
// distanceToMainLine: 350, // deprecated Use distanceToBaseline.value
collectOngoing: false,
autoStacking: {
active: true,
rowSpacing: 50,
range: RANGE_ALL,
fitToHeight: true,
topGap: 10
},
periodLine: {
position: 'lane', // new
baselineGap: 0, // new
spacing: 4,
thickness: 10,
stacking: {
sorter: ARTICLE_FROM_SORTER,
reverseOrder: false
}
},
animation: {
fade: {
active: true,
duration: 1500,
easing: 'swing' // new values
},
move: {
active: true,
duration: 1500,
easing: 'swing' // new values
}
},
star: { // new
visible: true
},
defaultData: { // new
from: {
precision: PRECISION_DAY
},
to: {
precision: PRECISION_DAY
},
rank: 0,
starred: false,
hidePeriodLine: false,
hiddenByFilter: false
},
defaultCardLayout: 'portrait', // new
cardLayoutBreakpoints: [ // new
{ maxHeight: 320, layout: 'landscape' }
],
defaultStyle: {/* See: Article Default Style — Options */ },
defaultHoverStyle: {/* See: Article Default Hover Style — Options */ },
defaultActiveStyle: {/* See: Article Default Active Style — Options */ },
layoutStyles: {/* See: Article Layout Styles — Options */ } // new
};
Lane Options new
Configure multi-lane timelines where related articles sit in separate horizontal lanes while sharing one bottom axis.
These options live under options.lane.*. The values shown below are the defaults.
Lane layout controls lane chrome. Article options control article placement.
See Lane Article Overrides for the subset of article options
supported by each lane's article object.
For a minimal runnable setup, see the
simple timeline lanes CodePen.
// Lane options (defaults)
{
visible: true,
defaultId: 'default',
gap: 12,
topGap: 0,
axisGap: 24,
defaultLayout: {/* See: Lane Layout */ },
defaultStyle: {/* See: Lane Style */ },
defaultClassName: '',
defaultHeaderClassName: '',
defaultBodyClassName: '',
defaultTitleClassName: '',
data: [
/* see Lane Schema; each lane can include
article: { ... } - see Lane Article Overrides */
]
};
Lane Article Overrides
Set LaneData.article to override the timeline-wide article defaults from
options.article for one lane. It supports a focused subset of
Article Options; each value merges over the timeline article options
for articles in that lane.
Use the Article Options section for the full descriptions and value shapes. The links below point to the matching option descriptions.
Merge order
Timeline article options apply first. Lane article overrides apply next for that lane, then individual article data and article-level style overrides apply last.
Supported keys
-
Data:
defaultData,density -
Baseline distance:
distanceToBaseline.value,distanceToBaseline.responsive,distanceToMainLine -
Card layout and styles:
defaultCardLayout,defaultStyle,defaultHoverStyle,defaultActiveStyle,layoutStyles -
Auto stacking:
autoStacking.active,autoStacking.rowSpacing,autoStacking.fitToHeight,autoStacking.topGap -
Period lines:
periodLine.baselineGap,periodLine.spacing,periodLine.thickness
Other article keys, including cardLayoutBreakpoints, rendering,
animation, star, periodLine.position,
periodLine.stacking, and autoStacking.range, remain timeline-wide
options.
Time Band Options new
Control visibility, layout, and defaults for background eras rendered behind the main timeline line.
These options live under options.timeBand.*. The values shown below are the defaults.
// Time Band options (defaults)
{
visible: true,
reserveSpace: true,
reserveSpacePixels: 20,
area: { up: 0, down: 'edge' },
defaultStyle: { /* see Time Band Style */ },
data: [ /* see Time Band Schema */ ]
};
Image Options new
Configure built-in image loading, caching, and sanitization. This only affects images loaded automatically from the imageUrl
property in each article's data. Images are queued for loading when required to render an article. Images are evicted from the cache when the
configured image.maxCacheBytes limit has been exceeded, or an image's dimensions have changed.
These options live under options.image.*. The values shown below are the defaults.
// Image options (defaults)
{
maxConcurrent: 6,
maxCacheBytes: 64 * 1024 * 1024,
requireCORS: false,
decodeMode: 'auto',
sanitizer: {
allowedSchemes: ['http', 'https', 'data', 'blob'],
// allowedOrigins: ['*.example.com'],
},
// customSanitizer: (url, options) => url,
};
Debugging and Logging new
HistropediaJS uses a centralized Logger service to control all debug output. Logging is
disabled by default so it will not spam your console unless you explicitly turn it on.
You can toggle logging globally via the default Histropedia export, or work directly with the
Logger class in ESM/bundler setups. UMD/script builds expose the same helpers on the global
Histropedia namespace.
Enable or disable debug logging (default export helpers)
When using the default export, call the convenience helpers below to enable or disable debug output across the
library. These methods internally delegate to the shared Logger instance.
import Histropedia from 'histropediajs';
// Or use the global Histropedia object directly for UMD/script-tag usage
// Turn on all HistropediaJS logging
Histropedia.enableDebug();
// Or explicitly set the flag
Histropedia.setDebug(true);
// Later, turn logging off again
Histropedia.disableDebug();
// Equivalent:
Histropedia.setDebug(false);
// Check current state
const isOn = Histropedia.isDebugEnabled(); // boolean
Using the Logger directly (ESM / bundlers)
In module-based builds you can import the Logger class directly. This gives you fine-grained control
over the debug flag and lets you emit structured messages at different levels.
import { Logger } from 'histropediajs';
Logger.setEnabled(true); // enable logging
Logger.debug('Timeline initialized');
Logger.info('Loaded articles', articles);
Logger.warn('Something looks odd');
Logger.error('Something went wrong', err);
UMD / script-tag usage
When using the UMD build via a <script> tag, the same helpers are available on the global
Histropedia object. You can either toggle logging via Histropedia.enableDebug() or work
with Histropedia.Logger directly.
<script src="https://cdn.jsdelivr.net/npm/histropediajs@1/dist/histropedia.umd.min.js"></script>
<script>
// Enable debug logging
Histropedia.enableDebug();
// Or via the Logger instance
Histropedia.Logger.setEnabled(true);
Histropedia.Logger.debug('Timeline ready');
</script>
Changing the debug label (console prefix)
All log messages are prefixed with a label (by default [Histropedia]) so you can easily spot them in
the console. You can change this prefix to include your app name, environment, or any other marker.
import { Logger } from 'histropediajs';
// Set a custom label that will appear in front of every log message
Logger.setPrefix('[MyApp Timeline]');
Logger.setEnabled(true);
Logger.debug('Loading articles...');
// Output: [MyApp Timeline] Loading articles...
For script-tag/UMD usage you can configure the same prefix via the global Logger instance:
Histropedia.Logger.setPrefix('[MyApp Timeline]');
Histropedia.enableDebug();
Histropedia.Logger.info('Timeline is ready');
// Output: [MyApp Timeline] Timeline is ready
The prefix is applied to all standard console-style methods exposed by the logger
(log, info, warn, error, debug,
group, groupCollapsed, groupEnd).
Styling
Customize the default appearance and lane layout of Timelines, Articles, Lanes, and Time Bands across your project.
Timeline Style
Define the base styling for the timeline canvas. Override these defaults per instance as needed.
These options live under options.style.*. The values shown below are the defaults.
// Timeline style options (defaults)
{
mainLine: {
visible: true,
size: 8
},
draggingHighlight: {
visible: true,
area: { up: 0, down: 'edge' }, // changed default new values
color: 'rgba(237, 247, 255, 0.5)'
},
marker: {
minor: {
height: 12,
color: '#6097f2',
futureColor: '#ccc'
},
major: {
height: 30,
color: '#0c3a88',
futureColor: '#ccc'
}
},
dateLabel: {
minor: {
font: 'normal 10px Calibri',
color: '#333',
futureColor: '#ccc',
textAlign: 'start',
offset: {
x: 4,
y: 0
},
bceText: '',
thousandsSeparator: ',',
yearPrefixes: {
ka: { label: 'ka', value: 1000, minDivision: 1000 },
Ma: { label: 'Ma', value: 1e6, minDivision: 1e5 },
Ga: { label: 'Ga', value: 1e9, minDivision: 1e8 }
}
},
major: {
font: 'normal 16px Calibri',
color: '#000',
futureColor: '#ccc',
textAlign: 'start',
offset: {
x: 4,
y: 0
},
bceText: ' ʙᴄᴇ',
thousandsSeparator: ',',
yearPrefixes: {
ka: { label: 'ka', value: 1000, minDivision: 1e5 },
Ma: { label: 'Ma', value: 1e6, minDivision: 1e6 },
Ga: { label: 'Ga', value: 1e9, minDivision: 1e9 }
}
}
}
};
Article Style
Article styles control the appearance of article cards on the timeline. You can define the default style, hover style, and active style for all articles in the Article Options, or override them per article in the Article Data.
Styles can also be changed at runtime:
Timeline defaults: timeline.setOption
Individual articles: article.setStyle(),
article.setHoverStyle(), article.setActiveStyle()
Caution: If a change to the default styles doesn’t take effect,
it may have been overridden by layout styles (for example, the
landscape layout).
Update the property in layoutStyles.<layout>.style
(or the corresponding hover/active override).
Default Style
The object below lists the complete set of available properties for styling article cards. The values shown for each property are the system defaults. Click on any property to see a description.
These properties can be used anywhere an article style object is used, such as the default style,
hoverStyle, and activeStyle, or the layoutStyles object.
However, some properties are only supported for specific card layouts,
and will be ignored for other layouts. This is indicated with a callout in the description for the property.
defaultStyle in the article options object.
// Default style
{
color: '#e9e9e9',
width: 150,
height: 70,
backgroundColor: '#fff',
topRadius: 3,
borderRadius: 0,
maxImageHeight: 400, // deprecated Use image.maxHeight instead
image: { // new
shape: 'natural',
margin: 0,
maxHeight: 400,
borderRadius: 4
},
header: {
height: 50,
text: {
font: "normal 14px 'Segoe UI'",
color: "#333",
align: "left",
baseline: "middle",
margin: 10,
lineHeight: 18,
numberOfLines: 2,
offsetY: 0 // new
}
},
subheader: {
height: 30,
color: '#555',
text: {
font: "normal 11px 'Segoe UI'",
color: "#eee",
align: "left",
baseline: "middle",
margin: 10,
lineHeight: 6,
offsetY: 0 // new
}
},
shadow: {
x: 0,
y: 0,
amount: 0,
color: '#000'
},
border: {
color: '#ddd',
width: 1
},
connectorLine: {
visible: true,
offsetX: 18,
offsetY: -20,
thickness: 1,
arrow: { width: 16, height: 45 }
},
star: {
width: 16,
margin: 3
}
}
Default Hover Style
Define hover styles as overrides to the normal style. All of the same properties as the main style are supported. See all all fields with descriptions in the default style section above.
defaultHoverStyle in the article options object.
// Default hoverStyle
{
color: "#a6c6e2"
}
Default Active Style
Define active styles as overrides to the normal style. All of the same properties as the main style are supported. See all all fields with descriptions in the default style section above.
defaultActiveStyle in the article options object.
// Default activeStyle
{
color: "#337ab7",
header: {
text: { color: "#fff" }
},
subheader: { color: '#333' },
shadow: { x: 3, y: 3, amount: 5, color: '#333' },
border: { width: 2, color: "#2e6da4" },
connectorLine: { thickness: 2 }
}
Layout Styles
Layout styles override the normal style, hoverStyle, and activeStyle objects. They are applied only when a specific card layout is used. HistropediaJS currently includes two built-in layouts — “portrait” and “landscape” — with more coming soon (along with guidance for defining custom layouts).
You can define or override layout-specific styles using the
layoutStyles key in the
article options object, where each
layout name acts as a key. Each layout style object supports the same properties as the main
article style. See the Default Style section above
for the complete list of available fields.
The portrait layout (the default) has no additional overrides.
The landscape layout includes the following differences:
// layoutStyles
{
// "portrait" has no additional layout style by default
landscape: {
style: {
width: 220,
height: 70, // Only used for landscape layout
borderRadius: 4, // Only used for landscape layout
image: {
shape: "circle",
margin: 10
},
header: {
text: {
color: "#333",
baseline: "alphabetic"
}
},
subheader: {
text: {
color: "#777",
baseline: "alphabetic"
}
}
},
hoverStyle: {
border: {
color: "#a6c6e2"
}
},
activeStyle: {
header: {
text: {
color: "#000"
}
},
subheader: {
text: {
color: "#333"
}
}
}
}
}
Lane Layout new
Configure the reusable geometry shape for lane chrome. These fields are used by
lane.defaultLayout and
LaneData.layout.
Lane layout controls lane chrome height and title placement. Article options still control article placement inside each lane.
// LaneLayout options
{
// height: 240, // optional fixed lane height in px
heightWeight: 1,
header: {
visible: true,
height: 24,
padding: {
left: 12,
right: 12
}
}
};
Fixed and automatic heights: lanes with height consume fixed pixels first. Lanes
without height divide the remaining lane area by heightWeight, excluding hidden lanes.
Lane Style new
Customize the DOM chrome for lane headers, bodies, and titles. These fields are used by
lane.defaultStyle and
LaneData.style.
Lane style defaults are empty objects, so inline styles are only written for values you explicitly configure.
Lane DOM also has stylesheet hooks for themes that should stay out of inline configuration:
histropedia-lane, histropedia-lane-index-N,
histropedia-lane-position-top, histropedia-lane-position-middle,
histropedia-lane-position-bottom, histropedia-lane-header,
histropedia-lane-title, and histropedia-lane-body.
N follows timeline.lanes from the shared axis outward. Lower lanes are given
higher z-index values than lanes above them, so CSS shadows can make upper lanes appear
tucked behind the lane below.
// LaneStyle options
{
header: {
// backgroundColor: 'rgba(219, 234, 254, 0.35)'
},
body: {
// backgroundColor: 'rgba(219, 234, 254, 0.2)',
// borderColor: 'rgba(30, 58, 138, 0.25)',
// borderWidth: 1,
// borderRadius: 4
},
title: {
// color: '#1e3a8a',
// font: '600 13px Inter, sans-serif',
// textAlign: 'left'
}
};
Per-lane overrides: set the style key in Lane data,
call lane.setStyle, or provide global defaults with options.lane.defaultStyle.
Fields you omit stay stylesheet-controlled.
.histropedia-lane {
overflow: visible;
}
.histropedia-lane:not(.histropedia-lane-position-top) {
box-shadow: 0 -14px 22px -20px rgba(15, 23, 42, 0.7);
}
.histropedia-lane-position-bottom {
box-shadow: none;
}
Time Band Style new
Customize the palette, borders, and typography applied to every band. Per-band overrides merge deeply with this default object.
timeBand.defaultStyle in the Time Band Options object.
// Time Band defaultStyle
{
backgroundColor: 'rgba(200, 200, 200, 0.25)',
border: {
color: 'rgba(120, 120, 120, 0.25)',
width: 1
},
text: {
font: 'normal 16px Calibri',
color: '#555',
align: 'left',
baseline: 'bottom',
verticalAlign: 'bottom',
margin: 4,
offsetY: 0
}
};
Per-band overrides: call band.setStyle, or set the style key in the Time Band data with a partial object. Fields you omit
fall back to the defaults above.
Data Model
Define the structure for timeline content and how per-entry overrides build on your configuration.
Article Schema
An article object powers a single timeline entry: metadata, span on the timeline, and optional style overrides that plug into the article defaults defined in your timeline options.
At a glance: Required fields — id, title,
from.
// Article Schema (clickable)
// Keys are clickable; annotations are NOT defaults.
{
id: /* required: number|string */,
title: /* required: string */,
subtitle: /* optional: string */,
lane: /* optional: number|string */,
from: {
year: /* required: number */,
month: /* optional: 1–12 */,
day: /* optional: 1–31 */,
precision: /* optional: one of the PRECISION_* constants; default: PRECISION_DAY */,
},
to: { /* optional */
year: /* required: number */,
month: /* optional: 1–12 */,
day: /* optional: 1–31 */,
precision: /* optional: one of the PRECISION_* constants; default: PRECISION_DAY */
},
isToPresent: /* optional: boolean; default: false */,
imageUrl: /* optional: string (URL) */,
rank: /* optional: number */,
starred: /* optional: boolean; default: false */,
hiddenByFilter: /* optional: boolean | function(Article): boolean; default: false */,
hidePeriodLine: /* optional: boolean | function(Article): boolean; default: false */,
offsetLeft: /* optional: number (px); default: 0 */,
offsetTop: /* optional: number (px); default: 0 */,
cardLayout: /* optional: 'portrait' | 'landscape' | string */,
// Per-article style overrides (sparse)
style: /* optional: ArticleStyle */,
hoverStyle: /* optional: ArticleStyle */,
activeStyle: /* optional: ArticleStyle */,
}
// Minimal article
{
id: 1,
title: "Example",
from: { year: 1990, month: 3, day: 15 }
}
// Full article example
{
id: 1,
title: "Alfred Hitchcock",
subtitle: "Film director (1899–1980)",
lane: "film",
from: { year: 1899, month: 8, day: 13 },
to: { year: 1980, precision: Histropedia.PRECISION_YEAR },
isToPresent: false,
imageUrl: "https://example.com/image.jpg",
rank: 100,
starred: true,
hiddenByFilter: (article) => HIDDEN_CATEGORIES.includes(article.data.category),
hidePeriodLine: true,
offsetLeft: 20,
offsetTop: -12,
cardLayout: "portrait",
// Per-article style overrides (sparse). See: Article Style Object
style: { color: '#cfe9ff' },
hoverStyle: { border: { width: 2 } },
activeStyle: { color: '#cfe9ff' }
}
Per-article style, hoverStyle, and activeStyle override the
timeline's article default styles. See: Article Style.
Lane Schema new
A lane object defines one horizontal section of a multi-lane timeline. Load articles with timeline.load and add a lane key to place them in a lane.
At a glance: Required fields — id. All other fields are optional.
Lane layout controls lane chrome. Article options control article placement.
See Lane Article Overrides for the supported article
keys.
// LaneData schema (clickable)
{
id: /* required: number|string */,
title: /* optional: string */,
visibility: /* optional: 'visible' | 'hidden' | function(Lane): 'visible' | 'hidden' */,
className: /* optional: string */,
headerClassName: /* optional: string */,
bodyClassName: /* optional: string */,
titleClassName: /* optional: string */,
layout: { /* See: Lane Layout */ },
style: { /* See: Lane Style */ },
article: { /* See: Lane Article Overrides */ }
}
const lanes = [
{
id: 'people',
title: 'People',
layout: { heightWeight: 2 },
style: { // See: Lane Style
body: { backgroundColor: 'rgba(219, 234, 254, 0.35)' },
title: { color: '#1e3a8a', font: '600 13px Inter' }
},
article: {
defaultCardLayout: 'landscape',
defaultStyle: { width: 220 },
autoStacking: { rowSpacing: 36 }
}
},
{
id: 'projects',
title: 'Projects'
}
];
Time Band Schema new
Time bands describe the spans rendered behind the main timeline line. They use the same day/month/year precision model as articles.
At a glance: Required fields — id, title,
from.
// Time Band Schema (clickable)
{
id: /* required: number|string */,
title: /* required: string */,
from: {
year: /* required: number */,
month: /* optional: 1-12 */,
day: /* optional: 1-31 */,
precision: /* optional: one of the PRECISION_* constants; default: PRECISION_DAY */
},
to: { /* optional */
year: /* required: number */,
month: /* optional: 1-12 */,
day: /* optional: 1-31 */,
precision: /* optional: one of the PRECISION_* constants; default: PRECISION_DAY */
},
isToPresent: /* optional: boolean; default: false */,
style: /* optional: TimeBandStyle */,
visibility: /* optional: 'visible' (default) | 'hidden' | function(TimeBand): 'visible' | 'hidden' */
};
// Minimal Time Band
{
id: 1,
title: "Middle Ages",
from: { year: 500 },
to: { year: 1500 }
}
// Full Time Band example
{
id: 2,
title: "Industrial Revolution",
from: { year: 1760, month: 1, day: 1 },
to: { year: 1840, precision: Histropedia.PRECISION_YEAR },
isToPresent: false,
style: {
backgroundColor: 'rgba(14, 165, 233, 0.2)',
border: { color: 'rgba(14, 165, 233, 0.45)', width: 2 },
text: { color: '#0ea5e9', align: 'center', font: '600 16px Calibri' }
},
visibility: (band) => band.owner.getZoom() >= 20 ? 'visible' : 'hidden'
}
API Reference
Complete reference for every method you can call from a timeline instance.
Timeline Methods
Master these methods to control every aspect of your timeline:
.load(articles)
DataLoad the given array of articles on to the timeline.
Parameters
Returns
void – Loads the articles in place and updates internal state.
This method is used to populate the timeline with articles.
It can be called again at any time to add more articles, provided they have unique id properties.
const timeline = new Histropedia.Timeline(container);
// Load articles on to the timeline
timeline.load([
{
id: 1,
title: 'Moon Landing',
subtitle: 'Apollo 11',
from: { year: 1969, month: 7, day: 16 },
to: { year: 1969, month: 7, day: 24 }
},
{
id: 2,
title: 'World Wide Web',
subtitle: 'Tim Berners-Lee proposal',
from: { year: 1989, month: 3, day: 12 }
}
]);
.loadLanes(lanes) new
DataAdd or update explicit lane definitions.
Parameters
Returns
void – Adds or updates lanes and redraws the timeline.
If a lane already exists implicitly because article data referenced its id, loadLanes upgrades it to an explicit lane.
timeline.loadLanes([
{
id: 'people',
title: 'People',
layout: { heightWeight: 2 },
article: {
defaultCardLayout: 'landscape',
defaultStyle: { width: 220 }
}
},
{
id: 'projects',
title: 'Projects'
}
]);
.loadLaneArticles(laneId, articles) new
DataStamp a lane id onto a batch of articles and load them onto the timeline.
Parameters
laneId string | number
Lane identifier to assign to every article in the batch.
articles ArticleData[]
Article objects. Existing conflicting lane values are overwritten by laneId.
Returns
void – Loads the articles and redraws the timeline.
timeline.loadLaneArticles('projects', [
{
id: 'analytical-engine',
title: 'Analytical Engine',
from: { year: 1837 }
},
{
id: 'difference-engine',
title: 'Difference Engine',
from: { year: 1822 }
}
]);
.loadTimeBands(bands) new
DataLoad the given array of Time Bands on to the timeline.
Parameters
Returns
void – Loads the bands in place and updates internal state.
This method is used to populate the timeline with Time Bands.
It can be called again at any time to add more bands, provided they have unique id properties.
const timeline = new Histropedia.Timeline(container);
// Load bands on to the timeline
timeline.loadTimeBands([
{
id: 1,
title: "18th Century",
from: { year: 1800, precision: Histropedia.PRECISION_CENTURY }
},
{
id: 2,
title: "Presidency of John F. Kennedy",
from: { year: 1961, month: 1, day: 20 },
to: { year: 1963, month: 1, day: 22 }
},
{
id: 3,
title: "Digital Age (1970s - present)",
from: { year: 1970, precision: Histropedia.PRECISION_DECADE },
isToPresent: true
}
]);
.setOption(option, value?)
ConfigurationSet any timeline option, or retrieve its current value when called with a dot-notation path.
Parameters
option string | object
Either a full timeline options object, or a dot-notation string pointing at a specific option.
value any
New value for the option when using a string path. Omit to read the current value instead.
Returns
any – Current option value when reading via a string path without a value
argument; otherwise void.
For large inspections it is more efficient to use the timeline.options object directly
(e.g. timeline.options.style).
// set new width and height
timeline.setOption({ width: 700, height: 400 });
// set mainLine size
timeline.setOption('style.mainLine.size', 10);
// set default article subheader height and color
timeline.setOption('article.defaultStyle.subheader', { height: 20, color: '#EEE' });
// get current animation settings
const animSettings = timeline.setOption('article.animation');
.setSize(width, height) new
ConfigurationResize the timeline canvas and reflow article layout to the given dimensions (CSS pixels).
Parameters
width number
New canvas width in pixels.
height number
New canvas height in pixels.
Returns
void – Resizes the canvas and triggers any necessary redraw.
Useful when the container resizes after initialisation. Call it from your own resize logic or a ResizeObserver.
const container = document.getElementById('timeline');
const timeline = new Histropedia.Timeline(container);
// Keep the timeline sized with the container
const resize = () => {
timeline.setSize(container.clientWidth, container.clientHeight);
};
window.addEventListener('resize', resize);
resize();
.on(event, handler) new
EventsRegister a runtime event listener for timeline interactions and updates.
Parameters
event string
Name of the timeline event to listen for (e.g. 'article-select').
handler function
Callback invoked with the event payload and, when available, the original DOM event.
Returns
void – Attaches the listener without returning a value.
See the Events & Handlers reference for the complete list of events and payload signatures.
const onArticleSelect = (article) => {
console.log('Selected article:', article.title);
};
timeline.on('article-select', onArticleSelect);
timeline.on('viewport-drag-start', (dragPayload, pointerEvent) => {
console.log('Viewport drag started', dragPayload, pointerEvent);
console.log(this); // Always the timeline instance for all handlers
});
.off(event, handler)
EventsUnregister a previously added event listener.
Parameters
handler function
The exact callback reference that was used when registering the listener.
Returns
void – Removes the listener and returns nothing.
const onZoom = ({ zoom }) => {
console.log('Zoom level:', zoom);
};
timeline.on('zoom', onZoom);
// stop listening when the UI panel closes
timeline.off('zoom', onZoom);
.getArticleById(id)
QueryRetrieve the article currently loaded on the timeline with the matching identifier.
Parameters
id string | number
Unique article identifier, as provided in your timeline article data.
Returns
Article | undefined – The matching article object, or undefined when no
article is found.
// get the article with id = 1
const article = timeline.getArticleById(1);
// check article data (see article options for structure)
console.log(article.data);
// call article methods
article.setOption('hidePeriodLine', true);
.getActiveArticle()
QueryReturn the article currently selected by the user in the timeline UI.
Returns
Article | null – The active article object, if one is selected.
// get the currently active article
const article = timeline.getActiveArticle();
// check article data
console.log(article?.data);
// call article methods when available
article?.setOption('hidePeriodLine', true);
.getLaneById(id) new
QueryRetrieve the lane currently loaded on the timeline with the matching identifier.
Parameters
id string | number
Lane identifier, as provided in options.lane.data, timeline.loadLanes, or article data.
Returns
Lane | undefined – The matching lane object, if one exists.
const peopleLane = timeline.getLaneById('people');
peopleLane?.setStyle('title.color', '#1e3a8a');
peopleLane?.hide();
.moveLaneToIndex(lane, index) and lane reorder helpers new
OrderingReorder lanes from the timeline instance. Public lane index 0 is nearest the shared axis.
Parameters
lane Lane | string | number
Lane instance or lane id to move.
index number
Target public index for moveLaneToIndex. Out-of-range values are clamped.
Returns
Lane – The lane that was moved.
Related helpers: moveLaneBefore, moveLaneAfter, moveLaneUp, and moveLaneDown.
timeline.moveLaneToIndex('people', 0);
timeline.moveLaneAfter('projects', 'people');
timeline.moveLaneUp('reference');
timeline.moveLaneDown('people');
.goToDateAnim(dmy, options?)
NavigationAnimate the timeline viewport so the supplied date scrolls into view.
Parameters
dmy Histropedia.Dmy
Destination date (e.g. new Histropedia.Dmy(year, month, day)). The target date lands
on the left edge by default.
options object
Optional animation settings:
durationnumber – Animation length in milliseconds (default2000).easingstring – Easing name (default'swing'). Supported names:'linear','swing','easeInQuad','easeOutQuad','easeInOutQuad','easeInCubic','easeOutCubic','easeInOutCubic'.offsetXnumber – Pixel offset to position the date within the viewport (default0).completefunction – Callback invoked when the animation finishes.
Returns
void – Performs an animated pan without returning a value.
// create Dmy for 5th Jan 1970
const date = new Histropedia.Dmy(1970, 1, 5);
// pan to date, with date located on left edge of canvas
timeline.goToDateAnim(date);
// ... with date located in centre of the canvas
timeline.goToDateAnim(date, { offsetX: timeline.width / 2 });
// ... with all options set
const options = {
duration: 400,
offsetX: 50,
complete: () => console.log('done!')
};
timeline.goToDateAnim(date, options);
.fitDateRange(start, end, options?) new
NavigationZoom and pan the viewport so a supplied date range fits inside the timeline width.
Parameters
start Dmy | DateParts
Start date as a Dmy instance or plain object such as { year: 1900 }.
end Dmy | DateParts
End date. Dates may be passed in either order.
options object
Optional fit settings:
paddingnumber | { left?: number, right?: number } – Space in pixels between the fitted range and the viewport edge (default0).animationobject – Optional animation settings:active,duration, andeasing. Supported easing names:'linear','swing','easeInQuad','easeOutQuad','easeInOutQuad','easeInCubic','easeOutCubic','easeInOutCubic'.
Returns
void – Updates the viewport in place.
Year-only and month-only inputs are treated as full periods for fit calculations.
timeline.fitDateRange(
{ year: 1961, month: 1, day: 20 },
{ year: 1963, month: 11, day: 22 },
{
padding: { left: 80, right: 80 },
animation: { active: true, duration: 500 }
}
);
.fitArticleRange(article, options?) new
NavigationZoom and pan the viewport so a single article's full date range fits inside the timeline width.
Parameters
article Article
Article instance to fit, using its computed period.from and period.to dates.
options object
Optional fit settings:
paddingnumber | { left?: number, right?: number } – Space in pixels between the fitted article range and the viewport edge (default0).animationobject – Optional animation settings using the same shape asfitDateRange, includingeasing.
Returns
boolean – true when the article has a range that can be fitted; otherwise false.
The options object uses the same padding and animation keys as fitDateRange.
const article = timeline.getArticleById('apollo-11');
if (article) {
timeline.fitArticleRange(article, {
padding: 80,
animation: { active: true, duration: 500 }
});
}
.fitArticles(options?) new
NavigationZoom and pan the viewport so the currently unfiltered article cards fit inside the timeline width.
Parameters
options object
Optional fit settings:
paddingnumber | { left?: number, right?: number } – Space in pixels between the outermost fitted article cards and the viewport edge (default40).articleFilterfunction – Optional predicate for choosing which articles to fit. By default, articles hidden by filters are excluded.animationobject – Optional animation settings using the same shape asfitDateRange, includingeasing.
Returns
boolean – true when at least one article can be fitted; otherwise false.
The fit uses each article's start date, card width, and connector offset rather than only the article date range.
// Fit all currently unfiltered articles
timeline.fitArticles();
// Fit only articles in a specific lane
timeline.fitArticles({
padding: { left: 60, right: 60 },
articleFilter: article => article.data.lane === 'projects',
animation: { active: true, duration: 500 }
});
.goToPixelAnim(pixel, options?)
NavigationPan the timeline by a fixed number of pixels with smooth animation.
Parameters
pixel number
Pixels to move the timeline. Positive values go forward in time; negative values go backward.
options object
Optional animation settings:
durationnumber – Animation length in milliseconds (default2000).easingstring – Easing name (default'swing'). Supported names:'linear','swing','easeInQuad','easeOutQuad','easeInOutQuad','easeInCubic','easeOutCubic','easeInOutCubic'.completefunction – Callback invoked when the animation finishes.
Returns
void – Performs an animated pan without returning a value.
// 50 pixels backward in time (viewport moves left)
timeline.goToPixelAnim(-50);
// 1 million pixels forward in time (viewport moves right)
timeline.goToPixelAnim(1e6);
// whole canvas width, useful for next/previous navigation arrows
timeline.goToPixelAnim(timeline.width);
// ... with all available options set
const options = {
duration: 400,
easing: 'linear',
complete: () => console.log('done!')
};
timeline.goToPixelAnim(timeline.width, options);
.setStartDate(date, offsetX?)
NavigationJump directly to a date on the timeline without animation.
Parameters
date string | Histropedia.Dmy
Destination date as 'yyyy-mm-dd' (month/day optional) or a
Histropedia.Dmy instance. Defaults to the left edge of the canvas.
offsetX number
Pixel offset positioning the date within the viewport (default 0).
Returns
void – Updates the viewport start date in place.
// create Dmy for 5th Jan 1970
const date = new Histropedia.Dmy(1970, 1, 5);
// jump to date, with date located on left edge of canvas
timeline.setStartDate(date);
// ... with date located in centre of the canvas
timeline.setStartDate(date, timeline.width / 2);
// set date using string notation
timeline.setStartDate('1970-6'); // 1st June 1970
// set BC date using string notation
timeline.setStartDate('-500-3-25'); // 25th March 500 BC
.getZoom() new
NavigationRetrieve the current zoom level applied to the timeline viewport.
Returns
number – Current zoom value (lower values are more zoomed in, higher values more zoomed out).
// read the current zoom
const currentZoom = timeline.getZoom();
// zoom out by a small amount
timeline.setZoom(currentZoom + 0.5);
// or, zoom in by a small amount
timeline.setZoom(currentZoom - 0.5);
.setZoom(zoom, centrePixel?)
NavigationApply a new zoom level while optionally specifying the point that stays anchored on screen.
Parameters
zoom number
Zoom level between 0 (most zoomed in) and 123 (most zoomed out). Values
are clamped to timeline.options.zoom.minimum/maximum.
centrePixel number
Pixel position from the left edge that remains fixed during zoom. Defaults to half of the timeline width.
Returns
void – Updates the timeline zoom level in place.
// set zoom level 13.5, zooming from the centre of the canvas
timeline.setZoom(13.5);
// ... zooming from the left edge of the canvas
timeline.setZoom(13.5, 0);
// ... zooming from the right edge of the canvas
timeline.setZoom(13.5, timeline.width);
.requestRedraw(redrawFunction?)
RenderingQueue a redraw so it runs at the optimal time, even while animations are in progress.
Parameters
redrawFunction function
Specific redraw function to run (timeline.redraw,
timeline.repositionRedraw, timeline.defaultRedraw, or a custom
function). Defaults to timeline.repositionRedraw.
Returns
void – Schedules the supplied redraw without returning a value.
Details
Use this after dynamic changes to avoid interrupting animations. Requests are coalesced with any in-flight animation work for a major performance boost.
// hide currently active article and set date labels to green
timeline.getActiveArticle().hiddenByFilter = true;
timeline.options.style.dateLabel.major.color = 'green';
// redraw the timeline using the default `repositionRedraw`
timeline.requestRedraw();
// specify the most basic redraw for extra performance
timeline.requestRedraw(timeline.redraw);
// or request a full restack of articles
timeline.requestRedraw(timeline.defaultRedraw);
.redraw()
RenderingRun the fastest, most lightweight timeline redraw.
Returns
void – Applies the basic redraw immediately.
Details
Best used when the start date and zoom level are unchanged. Prefer requestRedraw to
orchestrate redraw timing automatically.
// hide currently active article and set date labels to green
timeline.getActiveArticle().hiddenByFilter = true;
timeline.options.style.dateLabel.major.color = 'green';
// redraw to see the results
timeline.redraw();
// For best performance call via requestRedraw instead
timeline.requestRedraw(timeline.redraw);
.repositionRedraw()
RenderingRedraw the timeline while recalculating article positions for new start dates or zoom levels.
Returns
void – Performs the repositioning redraw immediately.
Details
Calls all steps of .redraw and additionally re-computes article origins. Also the
default function used by requestRedraw.
// hide currently active article and set date labels to green
timeline.getActiveArticle().hiddenByFilter = true;
timeline.options.style.dateLabel.major.color = 'green';
// redraw to see the changes
timeline.repositionRedraw();
// For best performance call via requestRedraw instead
timeline.requestRedraw(); // defaults to repositionRedraw
.defaultRedraw()
RenderingPerform the most thorough timeline redraw, including article restacking.
Returns
void – Executes the full redraw immediately.
Details
Runs every step of .repositionRedraw and also re-stacks articles when
options.article.autoStacking.active is enabled. Called automatically after user zoom or
scroll actions.
// hide currently active article and set date labels to green
timeline.getActiveArticle().hiddenByFilter = true;
timeline.options.style.dateLabel.major.color = 'green';
// redraw to see the changes with restacked articles
timeline.defaultRedraw();
// For best performance call via requestRedraw instead
timeline.requestRedraw(timeline.defaultRedraw);
Article Methods
Control any individual article on your timeline with these focused helpers:
Tip: Retrieve articles with timeline.getArticleById,
timeline.getActiveArticle, or by reading the timeline.articles array before
calling these methods.
.setOption(option, value?)
ConfigurationSet article data fields or read them by providing a dot-notation path.
Parameters
option string | object
Either a full article options object or a dot-notation path into the article options.
value any
Value to assign when using a string path. Omit to read the current value.
Returns
any – Current option value when reading via a string path without a value
argument; otherwise void.
For broad inspection prefer the article.data object (e.g.
article.data.style).
Use article.setOption("lane", laneId) to move an article to another lane. If the lane id
does not already exist, HistropediaJS creates an implicit lane automatically.
// get an article to work with from your timeline
const article = myTimeline.getActiveArticle();
// set a group of options
article.setOption({
title: 'New title',
subtitle: '2005 - 2007',
from: { year: 2005 },
to: { month: 3, day: 16 }
});
// set a single field using a path string
article.setOption('from.year', 2005);
// move the article to another lane
article.setOption('lane', 'projects');
// read the current rank without changing it
const rank = article.setOption('rank');
.setStyle(option, value?)
StylingOverride the per-article style or query an override value.
Parameters
option string | object
Style overrides object or dot-notation path into the article style options.
value any
Value to apply when using a string path. Omit to read the current override.
Returns
any – Current article-specific style value when reading via a string path
without a value argument; otherwise void.
This reads and writes only the article's individual overrides. Use article.style
to inspect the final computed style after defaults are applied.
const article = myTimeline.getArticleById(1);
// update a single style property
article.setStyle('border.width', 3);
// update several properties at once
article.setStyle({
color: '#9b1000',
header: { height: 60 },
shadow: { x: 5, y: 10, color: 'blue' }
});
// read a specific override
const borderColor = article.setStyle('border.color');
// inspect the computed style including defaults
const computedStyle = article.style;
.setHoverStyle(option, value?)
StylingCustomize hover state styling introduced in HistropediaJS 1.2.0 or read its overrides.
Parameters
option string | object
Hover style overrides object or dot-notation path into the hover style options.
value any
Value to apply when using a string path. Omit to read the current override.
Returns
any – Current hover-style value when reading via a string path without a value
argument; otherwise void.
Use article.hoverStyle to inspect the computed hover appearance including defaults.
const article = myTimeline.getActiveArticle();
// change a single hover property
article.setHoverStyle('star.width', 25);
// apply multiple hover overrides
article.setHoverStyle({
color: '#9b1000',
subheader: { height: 60 },
shadow: { x: 5, y: 10, color: 'green' }
});
// read a hover override
const hoverBorderColor = article.setHoverStyle('border.color');
// inspect the computed hover style
const computedHoverStyle = article.hoverStyle;
.setActiveStyle(option, value?)
StylingAdjust the styling used while the article is active (selected) or read its overrides.
Parameters
option string | object
Active style overrides object or dot-notation path into the active style options.
value any
Value to apply when using a string path. Omit to read the current override.
Returns
any – Current active-style value when reading via a string path without a value
argument; otherwise void.
Access article.activeStyle to inspect the fully computed style when the article is
selected.
const article = myTimeline.getActiveArticle();
// tweak a single active-state property
article.setActiveStyle('border.width', 3);
// provide several active-state overrides
article.setActiveStyle({
color: '#9b1000',
header: { height: 60 },
shadow: { x: 5, y: 10, color: 'blue' }
});
// read an active-state override
const activeBorderColor = article.setActiveStyle('border.color');
// inspect the computed active style
const computedActiveStyle = article.activeStyle;
.moveTo(position)
LayoutPlace the article's event card at specific canvas coordinates.
Parameters
position object
Object with left and/or top numbers defining the card's new
top-left coordinates. Omitted properties keep their current value.
Returns
void – Updates the stored position without drawing immediately.
Details
Use this to pin an event card anywhere on the canvas while it remains linked to its timeline date.
Call timeline.redraw() (or requestRedraw) to render the new placement.
If timeline auto-stacking is enabled, the card will return to its stacked position when the user scrolls or zooms.
const article = myTimeline.getActiveArticle();
// move the card to the top-left corner
article.moveTo({ left: 0, top: 0 });
myTimeline.redraw();
// move horizontally only
article.moveTo({ left: 60 });
myTimeline.redraw();
// move vertically only
article.moveTo({ top: 100 });
myTimeline.redraw();
.moveToOffset(offset)
LayoutShift the event card relative to its origin position.
Parameters
offset object
Object with left and/or top numbers describing the offset from the
origin (directly above the start date at the default height). Omitted properties keep their
current value.
Returns
void – Updates the stored offset without drawing immediately.
Details
Offset coordinates are relative to the article's origin position. left: 0 keeps
the card centered above its date; top: 0 keeps it at the default height from
article.distanceToBaseline.value, or the resolved responsive baseline distance when enabled.
Call timeline.redraw() (or requestRedraw) to show the new placement. With
auto-stacking enabled the card may snap back after user interactions.
const article = myTimeline.getActiveArticle();
// return to the origin position
article.moveToOffset({ left: 0, top: 0 });
myTimeline.redraw();
// keep the connector vertical but raise the card
article.moveToOffset({ left: 0, top: 60 });
myTimeline.redraw();
// apply both horizontal and vertical offsets
article.moveToOffset({ left: 100, top: -250 });
myTimeline.redraw();
Lane Methods new
Manage lane data, styles, visibility, and order after your timeline is initialized.
Tip: Loaded lanes are stored as Lane instances in timeline.lanes. Retrieve one with timeline.getLaneById(id) before calling the instance methods below.
.setOption(option, value?)
ConfigurationUpdate lane data fields using objects or dot-notation paths.
Parameters
option string | object
Full lane object for batch updates, or a dot-notation path such as 'layout.heightWeight'.
value any
New value when using a string path. Omit this argument to read the current value.
Returns
any when called as a getter; otherwise void.
const lane = timeline.getLaneById('people');
lane.setOption({
title: 'People & biographies',
article: {
defaultCardLayout: 'landscape',
defaultStyle: { width: 220 }
}
});
const layout = lane.setOption('layout');
.setStyle(option, value?)
StylingOverride lane chrome styling or query a style value.
Parameters
option string | object
Partial style object or dot-notation path such as 'title.color'.
value any
New value when using a string path. Omit to read the current override.
Returns
any when reading; otherwise void.
const lane = timeline.getLaneById('projects');
lane.setStyle('title.color', '#155e75');
lane.setStyle({
body: {
backgroundColor: 'rgba(207, 250, 254, 0.35)',
borderColor: 'rgba(14, 116, 144, 0.35)'
}
});
.hide() / .show()
VisibilityHide or show a lane without unloading its data.
Returns
void – Updates visibility and redraws the timeline.
Hidden lanes are excluded from lane layout and hide their articles while lane layout is active.
const lane = timeline.getLaneById('reference');
lane.hide();
lane.show();
.moveToIndex(index) / .moveUp() / .moveDown()
OrderingReorder lanes by public lane index, where 0 is nearest the shared axis.
Parameters
index number
Target public lane index for moveToIndex. Out-of-range values are clamped.
Returns
Lane – The lane that was moved.
const peopleLane = timeline.getLaneById('people');
peopleLane.moveToIndex(0);
peopleLane.moveUp();
peopleLane.moveDown();
.moveBefore(targetLane) / .moveAfter(targetLane)
OrderingMove a lane relative to another lane instance or lane id.
Parameters
targetLane Lane | string | number
Lane instance or lane id to move before or after.
Returns
Lane – The lane that was moved.
const projectsLane = timeline.getLaneById('projects');
projectsLane.moveBefore('people');
projectsLane.moveAfter('reference');
Time Band Methods new
Manage broad eras and background spans after your timeline is initialized.
Tip: Loaded bands are stored as TimeBand instances in
timeline.timeBands. TimeBand is also exported as
Histropedia.TimeBand for UMD and as a named ESM export.
.setOption(option, value?)
ConfigurationUpdate Time Band data fields using objects or dot-notation paths.
Parameters
option string | object
Full band object for batch updates, or a dot-notation path such as 'to.year'.
value any
New value when using a string path. Omit this argument to read the current value.
Returns
any – Current value when called as a getter; otherwise void.
Use this method for making changes to Time Band data fields after they have been loaded. The available fields are defined in the Time Band Schema.
const band = timeline.timeBands.find(b => b.id === 2);
// Batch update fields
band.setOption({
title: 'Reagan Presidency',
to: { year: 1989, month: 1, day: 20, precision: Histropedia.PRECISION_DAY }
});
// Read the current end date
const end = band.setOption('to');
.setStyle(option, value?)
StylingOverride the visual style for a specific band or query an override value.
Parameters
option string | object
Partial style object or dot-notation path (e.g. 'text.color').
value any
New value when using a string path. Omit to read the current override.
Returns
any – Current override value when reading; otherwise void.
Overrides merge deeply with timeBand.defaultStyle, so supply only the properties
you want to change.
const spotlight = timeline.timeBands.find(b => b.id === 3);
// Update a single field
spotlight.setStyle('backgroundColor', 'rgba(12, 74, 110, 0.35)');
// Apply multiple overrides
spotlight.setStyle({
text: {
color: '#0f172a',
align: 'center'
}
});
// Read the current override
const labelColor = spotlight.setStyle('text.color');
Events & Handlers new
Subscribe prior to initialization with options.on, or at runtime with timeline.on(event, handler).
Unsubscribe with timeline.off(event, handler). Some handlers receive the originating DOM event as the last
argument.
Quick index
ReferenceAll public events grouped by category. Click any to jump to details.
Timeline
LifecycleBackground interactions and notifications affecting the whole timeline.
timeline-click: TimelineClickPayload, originalEventtimeline-dblclick: TimelineClickPayload, originalEvent – fires aftertimeline-clickwhen the background receives a double-click.timeline-render-start: RedrawContext – emitted before each draw cycle;drawCycleContextis not yet set.timeline-render-end: RedrawContext – emitted after each draw cycle withdrawCycleContextpopulated when available.timeline-state-change: SerializedState:string
timeline.on('timeline-click', ({ viewport }, evt) => {
console.log('timeline-click', viewport, evt);
});
timeline.on('timeline-dblclick', ({ viewport }, evt) => {
console.log('timeline-dblclick', viewport, evt);
});
timeline.on('timeline-render-start', (redrawCtx) => {
const { canvasContext, top } = redrawCtx;
// canvasContext is the actual CanvasRenderingContext2D used to draw the timeline
console.log('render-start', top, canvasContext);
});
timeline.on('timeline-render-end', ({ canvasContext, drawCycleContext }) => {
console.log('render-end', drawCycleContext, canvasContext);
});
timeline.on('timeline-state-change', (stateJson) => {
console.log('timeline-state-change', JSON.parse(stateJson));
});
Payload
- TimelineClickPayload
viewport: { x:number, y:number } – coordinates relative to the timeline canvas
- RedrawContext
canvasContext: CanvasRenderingContext2D – the context used to draw the timeline.top: number – vertical position of the timeline main line relative to the canvas.drawCycleContext?: object – data about the current draw cycle (e.g. cached date coordinates).
Article
InteractionPointer entry/exit, clicks, and dragging on individual articles.
article-pointerenter/article-pointermove/article-pointerleave: article: Article, originalEventarticle-click: article: Article, originalEventarticle-dblclick: article: Article, originalEventarticle-select: article: Article – When a new article is selected on the timelinearticle-drag-start/article-drag-end: article: Article, originalEventarticle-drag: article: Article, delta: DragDelta, originalEvent
timeline.on('article-pointerenter', (article, evt) => console.log('enter', article, evt));
timeline.on('article-pointerleave', (article) => console.log('leave', article));
timeline.on('article-click', (article, evt) => console.log('click', article, evt));
timeline.on('article-select', (article) => console.log('select', article));
timeline.on('article-drag', (article, { dx, dy, totalDx, totalDy }) => {
console.log('drag', article, { dx, dy, totalDx, totalDy });
});
Payload
- DragDelta
dx: numberdy: numbertotalDx: numbertotalDy: number
Zoom
InteractionTrack unified zoom changes and specific wheel/pinch gestures.
zoom-wheel: WheelPayload, originalEventzoom-pinch-start: PinchPayload, originalEventzoom-pinch: PinchPayload, originalEventzoom-pinch-end: PinchPayload, originalEventzoom: ZoomPayload
// Unified zoom stream
timeline.on('zoom', ({ zoom, zoomDelta }) => {
console.log('zoom', zoom, zoomDelta);
});
// Pinch lifecycle
timeline.on('zoom-pinch-start', ({ centre, zoom }) => console.log('pinch start', centre, zoom));
timeline.on('zoom-pinch', ({ centre, zoomDelta, totalZoomDelta }) => console.log('pinch', centre, zoomDelta, totalZoomDelta));
timeline.on('zoom-pinch-end', () => console.log('pinch end'));
// Wheel steps
timeline.on('zoom-wheel', ({ centre, zoom, zoomDelta }, evt) => {
console.log('wheel', centre, zoom, zoomDelta, evt);
});
Payloads
- ZoomPayload
zoom: number – current zoom levelzoomDelta: number – change since previous update
- WheelPayload
centre: { x:number, y:number } – canvas pivotzoom: numberzoomDelta: number – change from before the wheel step
- PinchPayload
centre: { x:number, y:number } – pinch centre (canvas coords)scale: number – distance / startDistancedistance: number – current finger distance (px)zoom: numberzoomDelta: number – per-frame deltatotalZoomDelta: number – accumulated sincezoom-pinch-startdx?: number – centre.x delta since previous framepointers: PointerEvent[]
Viewport
InteractionPan the visible window by dragging the canvas.
viewport-drag-start: ViewportDragPayload, originalEventviewport-drag: ViewportDragPayload, originalEventviewport-drag-end: ViewportDragPayload, originalEvent
timeline.on('viewport-drag-start', (payload) => console.log('drag-start', payload));
timeline.on('viewport-drag', ({ dx, totalDx }) => console.log('drag', dx, totalDx));
timeline.on('viewport-drag-end', (payload) => console.log('drag-end', payload));
// Legacy helper (prefer viewport-drag-end)
timeline.on('drag-end', (totalDx) => console.log('drag-end (legacy)', totalDx));
Payload
- ViewportDragPayload
startToken: { unit:number, value:Histropedia.Dmy, length:number } – left edge tokenoffsetX: number – current internal horizontal offset (px)dx?: number – per-frame horizontal delta (px; left positive)totalDx?: number – accumulated sinceviewport-drag-start
Conventions & guarantees
Notes- Event names follow subject-action-phase:
zoom-pinch-start,viewport-drag. - High-frequency interactions emit
*-start, mid*, and*-end. - Payloads include only relevant keys. Per-frame deltas are
dx,dy,zoomDelta. - Totals accumulate from the corresponding
*-start(e.g.totalDx). - When provided, the original DOM event is always the last argument.
startTokenis an internal timescale token; treat as opaque unless usingHistropedia.Dmy.
Need More Help?
Our documentation is constantly evolving. If you can't find what you're looking for, we're here to help!