Timelime diagram
Example taken here ↗.
aka chronology, genealogical tree, layered digraph.
Installation
TODO:
- Remove the
Graphviz
component from the repo; need to use@beoe/astro-graphviz
instead.
First, install Graphviz:
---import Graphviz from "./Graphviz.astro";
type TimelineItem = { id: string; year: number; tooltip?: string; class?: string; label?: string; url?: string; in?: string[]; out?: string[];};
interface Props { items: TimelineItem[]; /** * https://www.graphviz.org/doc/info/attrs.html#d:rankdir */ direction?: "TB" | "BT" | "LR" | "RL";}
const { items, direction } = Astro.props;
const byYears: Record<string, string[]> = {};
items.forEach((item) => { byYears[item.year] = byYears[item.year] || []; byYears[item.year].push(item.id);});
const src = `digraph timeline { ${direction ? `rankdir=${direction}` : ""} bgcolor="transparent"; size="7,8";
edge [style=invis]; node [fontsize=24, shape = plaintext];
${Object.keys(byYears).sort().join(` -> `)} 0[label=" "]
node [fontsize=20, shape = box];
${Object.keys(byYears) .sort() .map( (year) => `{ rank=same; "${year}" ${byYears[year].map((x) => `"${x}"`).join(" ")}; }` ) .join("\n")}
edge[style=solid];
${items.map((item) => `"${item.id}"[${item.url ? `URL="${item.url}"` : ""} ${item.label ? `label="${item.label}"` : ""} ${item.class ? `class="${item.class}"` : ""} ${item.tooltip ? `tooltip="${item.tooltip}"` : ""}];`).join("\n")}
${items.map((item) => (!item.in ? "" : item.in.map((id) => `"${id}" -> "${item.id}";`).join("\n"))).join("\n")}
${items.map((item) => (!item.out ? "" : item.out.map((id) => `"${item.id}" -> "${id}";`).join("\n"))).join("\n")}}`;---
<div class="timeline"> <Graphviz src={src} /></div>
<style> .timeline { text { fill: var(--sl-color-white); } path { stroke: var(--sl-color-white); } polygon { stroke: var(--sl-color-white); } }</style>
Example
Code: Publications.astro ↗. Online demo: Exact Online String Matching ↗.