Skip to content

library for parsing and rendering interactive vis.js-timelines from markdown

License

Notifications You must be signed in to change notification settings

crogonint/chronos-timeline-md

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

94 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Chronos Timeline MD

A library for rendering interactive timelines from simple Markdown, anywhere. Make time make sense.

Powered by vis.js

Complete Syntax Guide

Live Playground

Obsidian Plugin

- [2020] A year
- [2020-02] A month
- [2020-02-28] A day
- [2020-02-28T12] An hour
- [2020-02-28T12:30] A minute
- [2020-02-28T12:30:09] A second

date example

Installation

npm

npm install chronos-timeline-md
import { ChronosTimeline } from "chronos-timeline-md";

CDN (Browser)

<!-- inside <head> -->
<script src="https://unpkg.com/chronos-timeline-md@latest/dist/iife-entry.global.js"></script>

Quick Start

Method 1: Static Function

import { ChronosTimeline } from "chronos-timeline-md";

const markdownSource = `
- [2020] Event 1
- [2021-06-15] Event 2 | Description
@ [2020~2022] Period 1
* [2021-01-01] Point 1
= [2020-12-31] Marker 1
`;

ChronosTimeline.render(
  document.getElementById("timeline-container"),
  markdownSource
);

Method 2: Constructor API

import { ChronosTimeline } from "chronos-timeline-md";

const timeline = new ChronosTimeline({
  container: document.getElementById("timeline-container"),
});

timeline.render(markdownSource);

Browser example (CDN)

<!DOCTYPE html>
<html>
  <head>
    <script src="https://unpkg.com/chronos-timeline-md@latest/dist/iife-entry.global.js"></script>
  </head>
  <body>
    <div id="timeline-container"></div>

    <script>
      const markdownSource = `
- [2020] Event 1
- [2021-06-15] Event 2 | Description
@ [2020~2022] Period 1
* [2021-01-01] Point 1
= [2020-12-31] Marker 1
`;

      ChronosTimeline.render(
        document.getElementById("timeline-container"),
        markdownSource
      );
    </script>
  </body>
</html>

API Reference

ChronosTimeline Class

Static Method:

ChronosTimeline.render(container, source, options?)

Constructor:

new ChronosTimeline({ container, settings?, callbacks?, cssRootClass? })
// or
new ChronosTimeline(container, settings?)

Instance Methods:

  • render(source: string) - Parse and render markdown
  • on(event: string, handler: Function) - Attach timeline events
  • destroy() - Clean up resources

Static Properties:

  • ChronosTimeline.version - Library version
  • ChronosTimeline.templates - Built-in templates
  • ChronosTimeline.cheatsheet - Syntax reference

Callbacks

Chronos will exposes a small set of optional callbacks that hosts can provide when constructing a timeline instance. Callbacks are passed either via the callbacks property on ChronosTimeline's constructor object or via CoreParseOptions.callbacks when using the lower-level parse/render functions.

Currently available callbacks:

setTooltip?: (el: Element, text: string) => void

  • Purpose: Allow the host application to take control of how tooltips are displayed. Chronos calls this for timeline items, custom markers, and UI helper buttons (for example the "Fit all" refit button).

  • When called: Chronos calls this callback with a target DOM element and the formatted tooltip text whenever a tooltip should be shown.

  • Default behaviour: If you don't provide setTooltip, Chronos falls back to a simple implementation that sets the element's title attribute (so native browser tooltips appear). The default is intentionally minimal so the library remains portable across environments.

  • Example (basic):

    const timeline = new ChronosTimeline({
      container: document.getElementById("timeline-container"),
      settings: { selectedLocale: "en" },
      callbacks: {
        setTooltip: (el, text) => {
          // Use a custom tooltip library, or set a data attribute
          // Example using tippy.js:
          tippy(el, { content: text, placement: "top" });
        },
      },
    });

Core Functions

import {
  parseChronos,
  renderChronos,
  attachChronosStyles,
} from "chronos-timeline-md";

// Parse markdown to timeline data
const result = parseChronos(source, options);

// Render complete timeline
const { timeline, parsed } = renderChronos(container, source, options);

// Inject default styles
attachChronosStyles();

Syntax Highlighting for Developers

Want to add Chronos markdown syntax highlighting to your code editor, IDE, or web application?

Syntax Highlighting Implementation Guide

Quick highlight.js Integration

import { ui } from "chronos-timeline-md";

// Register Chronos language with highlight.js
ui.registerChronosLanguage(hljs);

// Inject CSS styling
ui.injectChronosHighlightCSS();

// Highlight markdown text
const highlighted = ui.highlightChronosText(markdownSource, hljs);

Chronos Syntax (Quick Reference)

For complete syntax documentation, see CHRONOS_SYNTAX_GUIDE.md

# Basic syntax

- [2023] Event
- [2023-06-15] Event with description | Details here
  @ [2020~2025] Background period

* [2023-06-15] Point in time
  = [2023-01-01] Important marker

# With modifiers

- [2023] #red Colored event
- [2023] {Group} Grouped event
- [2023] #blue {Authors} Combined | Description

# Flags

> ORDERBY start
> DEFAULTVIEW 2020|2025
> NOTODAY
> HEIGHT 400

Configuration Options

interface CoreParseOptions {
  selectedLocale?: string;
  roundRanges?: boolean;
  settings?: {
    align?: "left" | "center" | "right";
    clickToUse?: boolean;
    useUtc?: boolean;
    theme?: {
      colorMap?: Record<string, string>;
      cssVariables?: Record<string, string>;
    };
  };
  callbacks?: {
    setTooltip?: (el: Element, text: string) => void;
  };
  cssVars?: Record<string, string>;
  cssRootClass?: string;
}

Examples

Custom Styling

const timeline = new ChronosTimeline({
  container: document.getElementById("timeline"),
  cssVars: {
    "chronos-accent": "#007acc",
    "chronos-bg-primary": "#ffffff",
  },
});

Event Handling

const timeline = new ChronosTimeline({
  container: document.getElementById("timeline-container"),
});

timeline.render(markdownSource);

timeline.on("select", (event) => {
  console.log("Selected:", event.items);
});

Complete List of Timeline Events

Selection Events:

  • select - Items are selected/deselected
  • itemover - Mouse over an item
  • itemout - Mouse leaves an item

Interaction Events:

  • click - Mouse click on timeline
  • doubleClick - Mouse double click
  • contextmenu - Right-click context menu
  • drop - Item dropped (drag & drop)

View Events:

  • rangechange - Visible time range changed
  • rangechanged - Visible time range change completed
  • timechange - Current time changed
  • timechanged - Current time change completed

Group Events:

  • groupDragover - Group drag over
  • groupDrop - Item dropped on group

Edit Events (if editable):

  • add - Item added
  • update - Item updated
  • remove - Item removed

Example Usage:

const timeline = new ChronosTimeline({
  container: document.getElementById("timeline-container"),
});

timeline.render(markdownSource);

// Selection
timeline.on("select", (event) => {
  console.log("Selected items:", event.items);
});

// Hover effects
timeline.on("itemover", (event) => {
  console.log("Hovering over item:", event.item);
});

// View changes
timeline.on("rangechanged", (event) => {
  console.log("New time range:", event.start, "to", event.end);
});

// Click handling
timeline.on("click", (event) => {
  console.log("Clicked at:", event.time);
  console.log("Items at click:", event.item);
});

Templates

// Use built-in templates
timeline.render(ChronosTimeline.templates.basic);
timeline.render(ChronosTimeline.templates.advanced);

Theming

CSS Variables

:root {
  --chronos-bg-primary: var(--background-primary);
  --chronos-text-normal: var(--text-normal);
  --chronos-accent: var(--interactive-accent);
  --chronos-color-red: #ff4444;
  --chronos-color-blue: #0066cc;
}

Dynamic Theme Sync

function syncTheme() {
  const root = document.documentElement;
  root.style.setProperty("--chronos-bg-primary", hostThemeColor);
}

Utility Exports

// Parser utilities
export * as parser from "chronos-timeline-md/parser";

// UI components and styles
export * as ui from "chronos-timeline-md/ui";

// Common utilities and types
export * as utils from "chronos-timeline-md/utils";

Development

# Install dependencies
npm install

# Build the package
npm run build

# Development mode with watch
npm run dev

# Run local interactive playground
npm run playground

# Clean build artifacts
npm run clean

Local dev with sym link

If modifying the underlying chronos-timeline-md locally and want live changes refelcted:

# expose local chronos-timeline-md
cd ~/path/to/local/chronos-timeline-md
npm install
npm link
npm run dev # start watch mode
# consume library in plugin
cd ~/path/to/local/obsidian-plugin
npm install
npm link chronos-timeline-md
npm run dev

To check which module (npm or local sym link) your plugin is currently using:

readlink node_modules/chronos-timeline-md

# or

npm ls chronos-timeline-md --depth=0

# if linked, npm often shows an arrow or a path. If installed from the registry it shows the version (e.g., chronos-timeline-md@1.0.8)

Unlinking

npm unlink chronos-timeline-md
# then reinstall from registry
npm install

Publishing

(Note to self :P)

# Update version in package.json
npm version patch|minor|major

# Publish to npm
npm publish

Browser Support

This library requires a modern browser environment with ES2020 support. It includes vis-timeline as a bundled dependency.

License

ISC

About

library for parsing and rendering interactive vis.js-timelines from markdown

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • TypeScript 53.6%
  • HTML 41.3%
  • JavaScript 5.1%