Skip to main content
โšก Calmops

LaTeX Timelines, Gantt Charts, and Chronological Visualizations

Introduction

Timelines and Gantt charts are essential for visualizing sequences of events, project schedules, and historical chronologies. LaTeX provides several approaches: TikZ for custom timelines, pgfgantt for project Gantt charts, and the chronosys package for historical timelines.

Simple TikZ Timeline

A horizontal timeline with events:

\usepackage{tikz}
\usetikzlibrary{arrows.meta, positioning}

\begin{tikzpicture}[
  event/.style={circle, draw, fill=blue!20, minimum size=8pt, inner sep=0},
  label/.style={font=\small, text width=2.5cm, align=center}
]
  % Main timeline axis
  \draw[->, thick] (0,0) -- (12,0) node[right] {Time};

  % Year markers
  \foreach \x/\year in {0/2020, 3/2021, 6/2022, 9/2023, 12/2024} {
    \draw (\x, 0.1) -- (\x, -0.1);
    \node[below, font=\small] at (\x, -0.1) {\year};
  }

  % Events above the line
  \node[event] (e1) at (1, 0) {};
  \node[label, above=0.3cm of e1] {Project\\Launch};

  \node[event] (e2) at (4, 0) {};
  \node[label, above=0.3cm of e2] {Beta\\Release};

  \node[event] (e3) at (7, 0) {};
  \node[label, above=0.3cm of e3] {v1.0\\Release};

  \node[event] (e4) at (10, 0) {};
  \node[label, above=0.3cm of e4] {v2.0\\Release};

  % Events below the line
  \node[event, fill=red!20] (e5) at (2.5, 0) {};
  \node[label, below=0.3cm of e5] {Team\\Expansion};

  \node[event, fill=red!20] (e6) at (8, 0) {};
  \node[label, below=0.3cm of e6] {Series A\\Funding};
\end{tikzpicture}

Vertical Timeline

\begin{tikzpicture}[
  event/.style={rectangle, draw, fill=blue!10, rounded corners,
                minimum width=4cm, minimum height=0.8cm, text centered},
  year/.style={font=\bfseries\large, text=blue!70}
]
  % Vertical line
  \draw[thick, blue!50] (0, 0) -- (0, -12);

  % Events
  \foreach \y/\yr/\desc in {
    0/1969/{Unix created at Bell Labs},
    -2/1972/{C language developed},
    -4/1983/{GNU Project started},
    -6/1991/{Linux kernel released},
    -8/2000/{Mac OS X released},
    -10/2015/{Rust 1.0 released}
  } {
    \node[year] at (-1.5, \y) {\yr};
    \draw[thick] (-0.1, \y) -- (0.1, \y);
    \node[event] at (2.5, \y) {\desc};
    \draw[->] (0.1, \y) -- (0.5, \y);
  }
\end{tikzpicture}

Gantt Charts with pgfgantt

pgfgantt is the standard package for project Gantt charts:

\usepackage{pgfgantt}

\begin{ganttchart}[
  hgrid,
  vgrid,
  x unit=0.8cm,
  y unit title=0.6cm,
  y unit chart=0.5cm,
  title label font=\small,
  bar label font=\small,
  milestone label font=\small\itshape,
  bar/.append style={fill=blue!40},
  milestone/.append style={fill=red!60}
]{1}{16}

  % Title row
  \gantttitle{Project Schedule 2026}{16} \\
  \gantttitlelist{Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec}{1} \\
  % (simplified to 16 units for demo)

  % Tasks
  \ganttbar{Requirements}{1}{2} \\
  \ganttbar{Design}{2}{4} \\
  \ganttbar{Development}{4}{10} \\
  \ganttbar{Testing}{9}{12} \\
  \ganttbar{Deployment}{12}{13} \\
  \ganttbar{Documentation}{10}{14} \\

  % Milestones
  \ganttmilestone{Design Review}{4} \\
  \ganttmilestone{Beta Release}{10} \\
  \ganttmilestone{Launch}{13} \\

  % Dependencies
  \ganttlink{elem0}{elem1}
  \ganttlink{elem1}{elem2}
  \ganttlink{elem2}{elem3}
  \ganttlink{elem3}{elem4}

\end{ganttchart}

Gantt with Groups and Colors

\begin{ganttchart}[
  hgrid,
  vgrid={*{6}{draw=none}, dotted},
  x unit=0.6cm,
  bar/.append style={fill=cyan!40},
  group/.append style={fill=gray!60},
  milestone/.append style={fill=orange!80}
]{1}{24}

  \gantttitle{Q1 2026}{8}
  \gantttitle{Q2 2026}{8}
  \gantttitle{Q3 2026}{8} \\

  \gantttitlelist{Jan,...,Sep}{1} \\

  % Phase 1
  \ganttgroup{Phase 1: Foundation}{1}{8} \\
  \ganttbar[bar/.append style={fill=blue!40}]{Architecture}{1}{3} \\
  \ganttbar[bar/.append style={fill=blue!40}]{Database Design}{2}{5} \\
  \ganttbar[bar/.append style={fill=blue!40}]{API Design}{3}{6} \\
  \ganttmilestone{Phase 1 Complete}{8} \\

  % Phase 2
  \ganttgroup{Phase 2: Development}{7}{18} \\
  \ganttbar[bar/.append style={fill=green!40}]{Backend}{7}{14} \\
  \ganttbar[bar/.append style={fill=green!40}]{Frontend}{9}{16} \\
  \ganttbar[bar/.append style={fill=green!40}]{Integration}{14}{18} \\
  \ganttmilestone{Beta Release}{18} \\

  % Phase 3
  \ganttgroup{Phase 3: Launch}{17}{24} \\
  \ganttbar[bar/.append style={fill=orange!40}]{Testing}{17}{21} \\
  \ganttbar[bar/.append style={fill=orange!40}]{Documentation}{19}{22} \\
  \ganttbar[bar/.append style={fill=orange!40}]{Deployment}{22}{24} \\
  \ganttmilestone{Launch}{24}

\end{ganttchart}

Historical Timeline with chronosys

\usepackage{chronosys}

\startchronology[startyear=1960, stopyear=2000,
                 color=blue!30, height=0.7ex]
\chronoevent{1969}{Unix}
\chronoevent{1972}{C Language}
\chronoevent{1983}{GNU Project}
\chronoevent{1991}{Linux}
\chronoevent{1995}{Java}
\stopchronology

Timeline with Annotations

\usetikzlibrary{decorations.pathreplacing, calligraphy}

\begin{tikzpicture}[scale=0.9]
  % Timeline
  \draw[ultra thick, ->] (0,0) -- (14,0);

  % Periods (colored spans)
  \fill[blue!20]  (0,-0.3) rectangle (4,0.3);
  \fill[green!20] (4,-0.3) rectangle (9,0.3);
  \fill[red!20]   (9,-0.3) rectangle (13,0.3);

  % Period labels
  \node[font=\small\bfseries] at (2,0)   {Early Stage};
  \node[font=\small\bfseries] at (6.5,0) {Growth Stage};
  \node[font=\small\bfseries] at (11,0)  {Mature Stage};

  % Year markers
  \foreach \x/\yr in {0/2018, 4/2020, 9/2022, 13/2024} {
    \draw (\x, 0.4) -- (\x, -0.4);
    \node[below, font=\footnotesize] at (\x, -0.4) {\yr};
  }

  % Key events with annotations
  \draw[thick, ->] (2, 0.5) -- (2, 1.2);
  \node[above, font=\small, text width=2cm, align=center] at (2, 1.2)
    {Product\\Launch};

  \draw[thick, ->] (6, 0.5) -- (6, 1.2);
  \node[above, font=\small, text width=2cm, align=center] at (6, 1.2)
    {1M Users};

  \draw[thick, ->] (11, 0.5) -- (11, 1.2);
  \node[above, font=\small, text width=2cm, align=center] at (11, 1.2)
    {IPO};
\end{tikzpicture}

Swimlane Timeline

For showing parallel tracks:

\begin{tikzpicture}[scale=0.8]
  % Axes
  \draw[->] (0,0) -- (12,0) node[right] {Time};

  % Swimlane labels
  \node[left, font=\small\bfseries] at (0, 1)   {Frontend};
  \node[left, font=\small\bfseries] at (0, 0)   {Backend};
  \node[left, font=\small\bfseries] at (0, -1)  {DevOps};

  % Horizontal lane dividers
  \draw[gray!40, dashed] (0, 0.5) -- (12, 0.5);
  \draw[gray!40, dashed] (0, -0.5) -- (12, -0.5);

  % Frontend tasks
  \fill[blue!30]  (1, 0.6) rectangle (4, 1.4) node[midway, font=\tiny] {UI Design};
  \fill[blue!50]  (3, 0.6) rectangle (8, 1.4) node[midway, font=\tiny] {Development};
  \fill[blue!70]  (7, 0.6) rectangle (10, 1.4) node[midway, font=\tiny] {Testing};

  % Backend tasks
  \fill[green!30] (1, -0.4) rectangle (3, 0.4) node[midway, font=\tiny] {API Design};
  \fill[green!50] (2, -0.4) rectangle (7, 0.4) node[midway, font=\tiny] {Development};
  \fill[green!70] (6, -0.4) rectangle (9, 0.4) node[midway, font=\tiny] {Testing};

  % DevOps tasks
  \fill[red!30]   (1, -1.4) rectangle (2, -0.6) node[midway, font=\tiny] {Setup};
  \fill[red!50]   (8, -1.4) rectangle (10, -0.6) node[midway, font=\tiny] {Deploy};
  \fill[red!70]   (10, -1.4) rectangle (11, -0.6) node[midway, font=\tiny] {Monitor};
\end{tikzpicture}

Packages Summary

Package Best For Complexity
tikz (manual) Custom timelines, full control High
pgfgantt Project Gantt charts Medium
chronosys Historical timelines Low
timeline Simple horizontal timelines Low

Resources

Comments