Timelines
A timeline draws dated events on a rail, in the order you write them, with the periods grouped into eras. Use it for a company or product history, a release train, a roadmap, or a changelog read in order. It is for anyone, human or AI agent, who needs a sequence of periods with a few events under each.
TL;DR
| Question | Answer |
|---|---|
| What is it for? | A history or a roadmap: a rail of periods, each with cards for its events, and optional named eras around runs of periods. |
| What is the header? | timeline "Title", with the options direction=, side=, and desc=. |
| In what order are periods drawn? | The order you write them. Periods are labels, not dates, so nothing is sorted. |
| Which way does it run? | direction=right (the default) draws a horizontal rail read left to right. direction=down draws a vertical rail read top to bottom. |
| Which side are the cards on? | side=both (the default) alternates the cards between the two sides of the rail. side=one puts every card on one side: below the rail, or to its right. |
| What are the limits? | 200 periods, 500 events, 40 sections, and 12 events in one period. Past any of them the answer is error E140. |
| Which Mermaid type converts? | timeline. Sections, periods, and events keep their order, and a few Mermaid details are dropped with a diagnostic. |
Ask your agent
Use Plotwork to draw a timeline of our product history. Group it into three eras: Prototype (2019 and 2020), Growth (2021 and 2022), and Platform (2023 and 2024). Give each event a short note and an icon where one fits.Use Plotwork to draw a timeline of a release train, read downward, with every card on one side. Four quarters: design freeze in Q1, beta and docs in Q2, general availability in Q3, and a retrospective in Q4.Example
An agent can write this from the first prompt. Three eras frame the periods, one period lists its events one to a line, and the last period carries its own tone.
timeline "Orbit product history" desc="From a weekend prototype to a platform that teams run their work on."
section "Prototype" { at "2019" : "Weekend hack" sub="Two founders and one laptop" icon=lucide:laptop, "First paying customer" icon=lucide:badge-check at "2020" : "Public beta" sub="1,200 sign-ups in a week" icon=lucide:rocket}
section "Growth" { period "2021" { event "Seed round" sub="Led by two angels" icon=lucide:wallet event "Team of ten" icon=lucide:users } at "2022" : "Series A", "Berlin office opens" icon=lucide:map-pin}
section "Platform" { at "2023" : "Public API" sub="REST and webhooks" icon=lucide:code at "2024" : "10,000 teams" tone=green icon=lucide:crown, "SOC 2 report" icon=lucide:shield-check}Periods, in the order drawn:
Section Prototype:
- 2019: Weekend hack (Two founders and one laptop); First paying customer
- 2020: Public beta (1,200 sign-ups in a week)
Section Growth:
- 2021: Seed round (Led by two angels); Team of ten
- 2022: Series A; Berlin office opens
Section Platform:
- 2023: Public API (REST and webhooks)
- 2024: 10,000 teams; SOC 2 report
The language
A timeline is a header, then periods in the order they are to be read. A period is a label, such as a year, a quarter, a date, or any words, with the events that belong to it. Periods are never sorted: the order you write is the order drawn, because a period is a label and not a date. Every label is in double quotes, and a line that starts with # is a comment.
The header
| Part | Meaning | Default |
|---|---|---|
timeline | The word that starts the header. | none |
"Title" | The title. It names the picture for screen readers and is not drawn. | none |
direction=right or direction=down | A horizontal rail read left to right, or a vertical rail read top to bottom. Any other word is error E123. | right |
side=both or side=one | Cards alternate between the two sides of the rail, or all sit on one side. Any other word is error E136. | both |
desc="text" | One or two sentences for the text description of the picture. | none |
timeline "Release train" direction=down side=one desc="Four quarters, read downward."Statements
| Statement | Meaning | Options |
|---|---|---|
section "Name" { ... } | An era: a tinted frame with its name in a corner tab, around the periods inside it. A section does not nest. A period written outside every section is drawn on the rail with no frame. | tone=, icon= |
at "Period" : "Event", "Event" | A period and its events on one line. The period is a milestone on the rail, and each event is a card that hangs from it, the first nearest the rail. at "Period" alone is a milestone with no cards. | tone= on the period, before the colon. sub=, icon=, and tone= after each event. |
period "Period" { ... } | The same as at, with one event on each line. | tone= |
event "Label" | One card of the period block it is written in. | sub=, icon=, tone= |
desc "text" | The same as desc= on the header. | none |
} | Closes the innermost block, on a line of its own. | none |
Events on an at line are separated by commas. Use at for the common case. Use period when events carry sub= and icon= and read better one to a line. Both give the same timeline.
at "2019" : "Weekend hack" sub="Two founders and one laptop" icon=lucide:laptop, "First paying customer"period "2021" { event "Seed round" sub="Led by two angels" icon=lucide:wallet event "Team of ten" icon=lucide:users}Options
| Option | Where | Values |
|---|---|---|
tone= | section, period, event | One of the tones. A section with no tone takes the next of blue, violet, aqua, orange, green, and amber, by its place in the list. A period takes its section's tone, or blue outside every section. An event takes its period's tone, and shows its own only in its border and its icon chip. |
icon= | section, event | An icon reference such as lucide:rocket, or status:success. A status icon keeps its own colour. |
sub= | event | A quieter second line under the label. |
A changelog read downward needs only direction=down and side=one. Periods outside every section sit on the rail with no frame, and a tone on one event marks it.
timeline "Changelog, read downward" direction=down side=one
at "v1.0" : "First release" icon=lucide:flagat "v1.1" : "Search", "Dark mode" sub="Follows the system setting"at "v2.0" : "New editor", "Plugins", "Offline mode"at "v2.1" : "Faster sync" tone=greenPeriods, in the order drawn:
- v1.0: First release
- v1.1: Search; Dark mode (Follows the system setting)
- v2.0: New editor; Plugins; Offline mode
- v2.1: Faster sync
Tones carry meaning. A section can take a tone and an icon, a period can take its own tone, and an event can take both. A status icon keeps its own colour, so a red outage still reads as an outage inside any section.
timeline "Tones and icons" desc="A tone on a section, a period, and an event; a status icon keeps its own colour."
section "Calm" tone=neutral icon=lucide:flag { at "Mon" : "Planned" icon=lucide:calendar at "Tue" tone=violet : "Reviewed" icon=lucide:users}section "Heat" tone=red { at "Wed" : "Outage" tone=red icon=status:error sub="Checkout down for 12 minutes" at "Thu" : "Fixed" icon=status:success}section "Quiet" tone=amber { at "Fri" : "Retro" tone=aqua icon=lucide:heart}Periods, in the order drawn:
Section Calm:
- Mon: Planned
- Tue: Reviewed
Section Heat:
- Wed: Outage (Checkout down for 12 minutes)
- Thu: Fixed
Section Quiet:
- Fri: Retro
What is drawn
| Part | How it looks |
|---|---|
| Rail | A calm line with an arrowhead, running on past the first milestone and the last. |
| Milestone | A pill on the rail with the period label, outlined in the tone of its period. |
| Card | The plate of a flow node: an icon chip when it has an icon, the label, and sub= in quieter type. |
| Connector | A line from a milestone to its cards. |
| Section | A tinted frame with a corner tab that holds its name, around the milestones and cards of its periods. |
Text never overflows a box. A card wraps its text and grows to fit, a period label is one line and is cut past a fixed width, and text is cut with an ellipsis, with warning W203, only when even the widest card is too small. The full text stays in the text description of the picture.
Limits and warnings
A timeline over a hard limit is refused with error E140 before anything is drawn, so a refusal is fast. Past a soft limit it is drawn and warning W200 says it is dense.
| Limit | Value | What happens |
|---|---|---|
| Sections | 40 | Error E140 at the header. |
| Periods | 200 | Error E140 at the header. |
| Events in one period | 12 | Error E140 at the label of the period. |
| Events in all | 500 | Error E140 at the header. |
| Periods on a horizontal rail | 12 | Warning W200. |
| Periods on a vertical rail | 24 | Warning W200. |
| Events in one period | 5 | Warning W200 at the label of the period. |
| Events in all | 48 | Warning W200. |
| Width | 80% of the column | Warning W202, which is past about 1100 pixels. |
| Code | Severity | When it fires, and the fix |
|---|---|---|
| E100, E101, E110, E111 | error | Syntax, an unterminated string, an unknown statement, or a missing header. The message gives the nearest word and a hint. Mermaid habits such as title and 2019 : x get a pointer to the Plotwork form. |
| E121, E122, E123 | error | An unknown tone, an unknown icon, or a direction that is not right or down. Choose a listed tone or icon, or one of the two directions. |
| E133, E134 | error | A block that is never closed, or a } with nothing to close. Balance the braces. |
| E135, E136 | error | An unknown option, or an option value that is not allowed: an option with no value, or a side that is not both or one. |
| E140 | error | The timeline is over a hard limit in the table above. Split it into several timelines, for example one for each era. |
| E380 | error | The timeline has no periods. It is reported only when nothing else is wrong. Add an at or a period. |
| E381 | error | An event outside a period block. Put it inside period "..." { }, or write the period with at. |
| E382 | error | A statement in a block that cannot hold it: a section inside a section or a period, or a period or an at inside a period. Move it out. |
| E383 | error | A label with no text. Write the label, or remove the statement. |
| W200 | warning | Too dense. Split along a section boundary. |
| W202 | warning | Wider than a Markdown column and its text would shrink. Use direction=down, shorten labels, or split it. |
| W203 | warning | Text was cut with an ellipsis. Shorten it, and move detail into the prose around the picture. |
| W340 | warning | A period with no events. A milestone is drawn, with no cards. Add events, or remove it if it says nothing. |
| W341 | warning | A period that reads as a date and is earlier than the one before it. Reorder the periods, or rename them if they are not dates. |
| W342 | warning | A period label written twice. Merge the two, or rename one. |
| W343 | warning | A section with no periods, so nothing is drawn for it. Add periods, or remove it. |
W341 reads only a closed set of date forms: 2019, 2019-03, 2019-03-15, 2019-2021, 2019 Q3, Q3 2019, 2019 H2, Mar 2019, and 2019 March. A label such as Founding or v2.0 is never compared, and the answer never depends on a clock or a locale.
From Mermaid
The Mermaid type timeline converts to a Plotwork timeline. Ask your agent to convert it, call convert_mermaid, or call sync_markdown with convertMermaid set to convert every Mermaid fence of a document.
timeline title History of social media section Early web 2002 : LinkedIn 2004 : Facebook : Google section Video 2005 : YouTube 2006 : TwitterThe converter writes this Plotwork, with no diagnostics:
timeline "History of social media"
section "Early web" { at "2002" : "LinkedIn" at "2004" : "Facebook", "Google"}
section "Video" { at "2005" : "YouTube" at "2006" : "Twitter"}| Mermaid | Plotwork | Report |
|---|---|---|
title: in the front matter, accTitle:, or a title Words line | The title of the header. The front matter wins, then accTitle, then the title line. | none |
accDescr: and accDescr { } | desc= | none |
section Name | A section block around the periods that follow it, in the tones of the cycle. | An empty section is dropped with M216. |
2002 : A | at "2002" : "A" | none |
2004 : A : B | at "2004" : "A", "B", or a period block when there are more than two events or the line is long. | none |
A line that starts with : | Further events of the period before it. | An event line before any period is M110, or M218 in a lenient conversion. |
| A period with no events | at "2002" | none |
| A period before the first section | A period outside every section. | none |
timeline LR | The default, direction=right. | none |
timeline TD or TB | direction=down | none |
timeline RL or BT | right or down, the nearest. | M204 |
<br>, HTML, and entities | One line of text. #colon; becomes a colon. | M205 for markup and line breaks. |
%% comments | Dropped silently. | none |
A # that is not an entity | The rest of the line is cut, as Mermaid does. | M260. Write the # as an entity in the Mermaid if it was part of the text. |
%%{init}%%, front matter config:, themeVariables, disableMulticolor | Dropped. The theme owns every colour. | M200 |
| An empty event after a colon | Dropped. | M216 |
| More than the limits above | Nothing is converted. | M102 names the part that is too big. Split the timeline. |
Periods stay in the order read, a section's colours follow its place in the list, and nothing is sorted. title and section are read as lower case words followed by a space, as Mermaid reads them, so a period called Title IX or Section 2 stays a period. The diagnostic codes are listed in Migrating from Mermaid.
See also
| Doc | Why |
|---|---|
| Writing diagrams | The language for flow, sequence, and schema diagrams, and options every kind shares |
| Examples to copy | Finished diagrams with the prompt that gets an agent to write each one |
| Migrating from Mermaid | How every Mermaid type converts, and every diagnostic code |
| Git graphs | Branches, merges, and tags drawn as lanes |
| Gantt charts | A plan scheduled in days, with dependencies |
| Class diagrams | Classes, members, and relations |
| State diagrams | States, transitions, and regions |
| User journeys | A person's steps scored from frustrated to delighted |
| Mind maps | A topic and its branches on one canvas |
| Language reference | Every statement, option, and limit, kind by kind |
| Diagram kinds | The kinds Plotwork draws and what each is for |