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 */,
hour: /* optional: 0–23; default: 0 */, // new
minute: /* optional: 0–59; default: 0 */, // new
second: /* optional: 0–59; default: 0 */, // new
millisecond: /* optional: 0–999; default: 0 */, // new
precision: /* optional: inferred from supplied time fields; otherwise 'day' */,
},
to: { /* optional */
year: /* required: number */,
month: /* optional: 1–12 */,
day: /* optional: 1–31 */,
hour: /* optional: 0–23; default: 0 */, // new
minute: /* optional: 0–59; default: 0 */, // new
second: /* optional: 0–59; default: 0 */, // new
millisecond: /* optional: 0–999; default: 0 */, // new
precision: /* optional: same inference and precision strings as from */
},
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: '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 are the most
specific layer in the article style cascade. See: Article Style.
millisecond,
second, minute, then hour. Zero counts as supplied. With no time
components it defaults to 'day', including year-only and year/month objects. Explicit
precision is authoritative, so fields
finer than the selected precision are ignored: hour precision ignores minute through millisecond,
for example. For a from-only article the inclusive range is exact for 'millisecond', ends
in .999 for 'second', ends in :59.999 for 'minute', and
ends in :59:59.999 for 'hour'. These are timezone-free calendar fields, not
JavaScript Date timestamps. See
Dates and Dmy for the
shared date model and its relationship to precision.
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.
For how defaultStyle, layoutStyles, lane styles, and per-article styles combine,
read the Article Style cascade. For registering and selecting your
own layout, read the
Custom Card Layouts guide.
String selectors new
HistropediaJS 1.5.0 uses descriptive strings for selector options. Prefer values such as 'all', 'medium', 'screen', and 'day' in new code.
The exported DENSITY_*, RANGE_*, and PRECISION_* constants now resolve to these strings. Legacy numeric selector values still work, but are deprecated. Function exports such as ARTICLE_FROM_SORTER are still imported from ESM builds or read from the Histropedia global in UMD builds.
// Article options (defaults)
{
density: 'all', // new descriptive string default
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: 'all', // new descriptive string default
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: 'day'
},
to: {
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
};
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,
};
Article Style
Article styles control the appearance of article cards on the timeline. You can define the default, hover, and active styles for all articles in Article Options, override them for a lane, or override them for individual articles in Article Data.
Styles can also be changed at runtime:
- Timeline defaults:
timeline.setOption() - Lane defaults:
lane.setOption() - Individual articles:
article.setStyle(),article.setHoverStyle(),article.setActiveStyle()
Article cards are rendered using a card layout, such as the built-in
portrait and landscape layouts. Each card layout can provide its own default styles.
Styles can be defined at the timeline, lane, card layout, and individual article levels, with more specific styles overriding broader defaults.
Default Style
The object below lists the complete set of available properties for styling article cards.
The values are Histropedia's base defaults, except height and borderRadius, which show the
selected landscape layout defaults. Click any property to see its description.
These properties can be used anywhere an article style object is used, including defaultStyle,
defaultHoverStyle, defaultActiveStyle, layout-specific styles, and per-article styles.
defaultStyle in the article options object.
// Default style
{
color: '#e5e5e5',
width: 150,
height: 70, // landscape only; layout default
backgroundColor: '#fff',
topRadius: 3, // portrait only
borderRadius: 4, // landscape only; layout default
maxImageHeight: 400, // deprecated Use image.maxHeight instead
image: { // new
shape: 'natural',
margin: 0,
maxHeight: 200, // portrait only
borderRadius: 0
},
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
}
}
Hover Style
Define hover styles as overrides to the normal style. All of the same properties as the main style are supported. See all fields with descriptions in the default style section above.
defaultHoverStyle in the article options object.
// Default hoverStyle
{
color: "#a6c6e2"
}
Active Style
Define active styles as overrides to the normal style. All of the same properties as the main style are supported. See 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
A timeline or lane can use layoutStyles to define overrides that apply only when a particular card layout
is selected. These layout-specific styles are part of the general style cascade,
not a separate or globally higher-priority styling system.
At either scope, defaultStyle, defaultHoverStyle, and defaultActiveStyle are applied
first, followed by the matching layout's style, hoverStyle, and activeStyle.
Configure timeline-level layout styles with the
layoutStyles key in the
article options object; each layout name acts as a key and supports
the same properties as the corresponding general article style.
The built-in portrait layout adds no layout defaults. The landscape layout supplies these
defaults before any explicitly configured timeline, lane, or article styles:
// layoutStyles
{
// "portrait" has no additional layout style by default
landscape: {
style: {
width: 220,
height: 70,
borderRadius: 4,
image: {
shape: "square",
margin: 4,
borderRadius: 4
},
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"
}
}
}
}
}
Style Cascade
Every article uses the same style cascade, whether it uses a built-in or custom card layout:
Histropedia defaults β card layout defaults β timeline β lane β article
Styles are deep-merged at each stage, so later layers only need to specify the properties they want to override.
For the normal article style, the complete precedence order is:
- Histropedia's base article style;
- the selected card layout's registered
defaultStyle; - timeline
article.defaultStyle; - timeline
article.layoutStyles[name].style; - lane
article.defaultStyle, when applicable; - lane
article.layoutStyles[name].style, when applicable; - the individual article's
style.
Within the timeline and lane scopes, the general style is applied first, followed by the matching layout-specific style. Each subsequent scope can still override eitherβfor example, a lane's general style can override a timeline layout-specific style, and an individual article always has the highest priority.
Hover and active styles follow the same cascade using their corresponding
defaultHoverStyle/hoverStyle and
defaultActiveStyle/activeStyle properties. These are then merged over the resolved normal
style. If an article is both hovered and active, the active style takes precedence over the hover style.
Card Layouts
A card layout determines how an article card's content is arranged and how the card is measured and drawn. Article styles control its appearance; the selected card layout controls its structure.
Histropedia includes two card layouts:
portraitβ a vertical card with the title and subtitle above the image. Its height follows the content.landscapeβ a compact, fixed-height horizontal card with the image beside the title and subtitle.
Choose the timeline default with
article.defaultCardLayout, use
article.cardLayoutBreakpoints to select a
layout from the available height, or override the layout for a
lane or
individual article.
To create layouts beyond the built-in cards, see the Custom Card Layouts guide for layout registration, drawing, sizing, and styling.
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;
.getCurrentStyle() new
StylingReturn the fully merged style for the article's current interaction state.
Returns
ArticleStyle – The current normal, hover, active, or active-hover style, including
timeline, lane, card-layout, and per-article overrides.
Use this method in custom card-layout hooks so state changes are handled without duplicating
HistropediaJS's style-selection logic. Use article.style, hoverStyle,
activeStyle, or activeHoverStyle when you need a specific state.
Timeline.registerCardLayout({
name: 'compact',
draw(ctx) {
const style = this.getCurrentStyle();
ctx.fillStyle = style.backgroundColor;
ctx.fillRect(this.position.left, this.position.top, style.width, style.height);
}
});
.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();