14

Many presentations include some kind of a visualizer where the listeners can easily see how far the presentation has gone.

A great option to do so is adding a progress bar into the slide layout.


Minimum Working Example (MWE):

The user Gonzalo Medina has posted a nice approach on how to display a triangle above a line:

Screenshot of the code from user Gonzalo Medina

\documentclass{beamer}
\usepackage{tikz}
\usetikzlibrary{calc}

\definecolor{pbgray}{HTML}{575757}% background color for the progress bar

\makeatletter
\def\progressbar@progressbar{} % the progress bar
\newcount\progressbar@tmpcounta% auxiliary counter
\newcount\progressbar@tmpcountb% auxiliary counter
\newdimen\progressbar@pbht %progressbar height
\newdimen\progressbar@pbwd %progressbar width
\newdimen\progressbar@tmpdim % auxiliary dimension

\progressbar@pbwd=\linewidth
\progressbar@pbht=1pt

% the progress bar
\def\progressbar@progressbar{%

    \progressbar@tmpcounta=\insertframenumber
    \progressbar@tmpcountb=\inserttotalframenumber
    \progressbar@tmpdim=\progressbar@pbwd
    \multiply\progressbar@tmpdim by \progressbar@tmpcounta
    \divide\progressbar@tmpdim by \progressbar@tmpcountb

  \begin{tikzpicture}[very thin]
    \draw[pbgray!30,line width=\progressbar@pbht]
      (0pt, 0pt) -- ++ (\progressbar@pbwd,0pt);
    \draw[draw=none]  (\progressbar@pbwd,0pt) -- ++ (2pt,0pt);

    \draw[fill=pbgray!30,draw=pbgray] %
       ( $ (\progressbar@tmpdim, \progressbar@pbht) + (0,1.5pt) $ ) -- ++(60:3pt) -- ++(180:3pt) ;

    \node[draw=pbgray!30,text width=3.5em,align=center,inner sep=1pt,
      text=pbgray!70,anchor=east] at (0,0) {\insertframenumber/\inserttotalframenumber};
  \end{tikzpicture}%
}

\addtobeamertemplate{headline}{}
{%
  \begin{beamercolorbox}[wd=\paperwidth,ht=5ex,center,dp=1ex]{white}%
    \progressbar@progressbar%
  \end{beamercolorbox}%
}
\makeatother

\begin{document}

    \section{Introduction}

        \begin{frame}
            \frametitle{Introduction}
            test
        \end{frame}

    \section{Motivation}

        \begin{frame}
            \frametitle{Motivation}
            test
        \end{frame}

    \section{Methodology}

        \begin{frame}
            \frametitle{Experiments}
            test
        \end{frame}

        \begin{frame}
            \frametitle{Statistics}
            test
        \end{frame}

    \section{Results}

        \begin{frame}
            \frametitle{Results 1}
            test
        \end{frame}

        \begin{frame}
            \frametitle{Results 2}
            test
        \end{frame}

    \section{Conclusion}

        \begin{frame}
            \frametitle{Conclusion}
            test
        \end{frame}

\end{document}

Question:

This looks nice indeed, but I would prefer to add the section titles into the timeline as well.

Screenshot of the desired progres bar

Hereby you can see:

  • Introduction and Motivation has already been presented
  • Methodology is currently presented
  • Results and Conclusion will be presented afterwards

Would it be possible to extend the code so the section titles will appear in the timeline as well?

Henri Menke
  • 109,596
Dave
  • 3,758
  • 8
    Less florid, but that's just what some themes as like Berlin, Darmstadt or Berkeley do. Anyway, I doubt of the benefits of any progress bar. The bars take a valuable space (except maybe using one as discrete as in the metropolis theme) and overall, is distracting. Do you want people focused on your dissertation or in how many sections rest to leave? – Fran Aug 11 '19 at 10:04

1 Answers1

11

I know it's been a while, but you can blame the lockdown here in France for providing me free time...

I started from Gonzalo Medina's proposal and build the missing stuff around it. I believe this is the single most difficult thing I've ever done with LaTeX, so thanks for your question, I learned a lot of stuff preparing this answer.

\documentclass{beamer}
\usepackage{tikz}
\usetikzlibrary{calc,patterns.meta}
% To provide total amount of sections throughout the document
\usepackage{totcount}
% Registers de total amount of sections (see https://tex.stackexchange.com/a/192506/141947)
\regtotcounter{section}
% To be able to refer to sections when needed
\usepackage{nameref}
% Redefinition of the \section command so that each one is labeled \label{sec:n} where n is its index 
\let\oldsection\section
\renewcommand{\section}[2][\relax]{%
    \ifx#1\relax
      \oldsection{#2}%
    \else
      \oldsection[#1]{#2}%
    \fi%
    \label{sec:\thesection}%
}

% Definition of custom colors based on the initial figure of the bar by the OP
\definecolor{myblue}{HTML}{57AED1}
\definecolor{mygreen}{HTML}{8BC53F}
\definecolor{mygray}{HTML}{DDDDDD}

% Definition of custom tikz styles in order to ease readability
\tikzset{
    % Bar style (Argument : color)
    sectionbar/.style={
        % Filling with one color as a preaction, in order to avoid reset by the pattern color
        preaction={fill=#1!70},
        % Application of the line pattern on to of the fill
        pattern={Lines[angle=45,distance={6pt},line width=3pt]},pattern color=#1
    },
    % Node style (Arguments : color, section number)
    sectionnode/.style 2 args={
        fill=#1,
        draw=white,
        thick,
        circle,
        text=white,
        radius=10pt,
        % Display of the section name below the cicle
        label={[text=#1]below:\nameref{sec:#2}},
        }
}


% Actual definition of the colorbar based on Gonzalo Medina's initial proposal
\makeatletter
    \def\pbar@progressbar{} % the progress bar
    \newcount\pbar@tmpcnta% auxiliary counter
    \newcount\pbar@tmpcntb% auxiliary counter
    \newdimen\pbar@pbht %progressbar height
    \newdimen\pbar@pbwd %progressbar width
    \newdimen\pbar@tmpdim % auxiliary dimension
    \pbar@pbwd=\linewidth
    \pbar@pbht=4pt

% The progress bar
\def\pbar@progressbar{%
    \pbar@tmpcnta=\value{section} % tmpcnta stores the section number
    \pbar@tmpcntb=\totvalue{section} % tmbcountb sotres the total amount of sections
    \advance\pbar@tmpcntb by 1 % tmbcountb is advanced by 1 in order to have the last bar segment after the last node

    \begin{tikzpicture}[very thin]
        % Clipping scope to avoid tests for the bar dimensions
        \begin{scope}
        % Clipping path
        \path[rounded corners=2pt,clip] (0pt,{-\pbar@pbht/2}) rectangle (\pbar@pbwd,{\pbar@pbht/2});
        % Gray bar (from 0 to last section)
        \path[sectionbar=mygray] (0pt,{-\pbar@pbht/2}) rectangle (\linewidth,{\pbar@pbht/2});
        % Blue bar (from 0 to the current section)
        \path[sectionbar=myblue] (0pt,{-\pbar@pbht/2}) rectangle ({(\pbar@tmpcnta-0.5)*\linewidth/\pbar@tmpcntb},{\pbar@pbht/2});
        % Green bar (from current to next section)
        \path[sectionbar=mygreen] ({(\pbar@tmpcnta-0.5)*\linewidth/\pbar@tmpcntb},{-\pbar@pbht/2}) rectangle ({(\pbar@tmpcnta+0.5)*\linewidth/\pbar@tmpcntb},{\pbar@pbht/2});
        \end{scope}
        % Drawing of the nodes on top of the bars, based on the number of the current section
        \foreach \secnumber in {1,...,\totvalue{section}}{
            % Number is lower, section is past, blue color
            \ifnum\secnumber<\pbar@tmpcnta
                \node[sectionnode={myblue}{\secnumber}] at ({(\secnumber-0.5)*\linewidth/\pbar@tmpcntb},0) {\strut\secnumber};
            \fi
            % Number is equal, section is current, green color
            \ifnum\secnumber=\pbar@tmpcnta
                \node[sectionnode={mygreen}{\secnumber}] at ({(\secnumber-0.5)*\linewidth/\pbar@tmpcntb},0) {\strut\secnumber};
            \fi
            % Number is larger, to be done section, gray color
            \ifnum\secnumber>\pbar@tmpcnta
            \node[sectionnode={mygray}{\secnumber}] at ({(\secnumber-0.5)*\linewidth/\pbar@tmpcntb},0) {\strut\secnumber};
            \fi
        }
  \end{tikzpicture}%
}

\addtobeamertemplate{headline}{}
{%
  \begin{beamercolorbox}[wd=\paperwidth,ht=10ex,center,dp=1ex]{white}%
    \pbar@progressbar%
  \end{beamercolorbox}%
}
\makeatother

\begin{document}


\section{Introduction}

\begin{frame}
    \frametitle{Introduction}
    test
\end{frame}

\section{Motivation}

\begin{frame}
    \frametitle{Motivation}
    test
\end{frame}

\section{Methodology}

\begin{frame}
    \frametitle{Experiments}
    test
\end{frame}

\begin{frame}
    \frametitle{Statistics}
    test
\end{frame}

\section{Results}

\begin{frame}
    \frametitle{Results 1}
    test
\end{frame}

\begin{frame}
    \frametitle{Results 2}
    test
\end{frame}

\section{Conclusion}

\begin{frame}
    \frametitle{Conclusion}
    test
\end{frame}
\end{document}

enter image description here enter image description here enter image description here

EDIT Just for fun, a slightly leaner definition or the bar using a pgf ifthenelse construct and precomputing \linewidth/\pbar@tempcntb.

% The progress bar
\def\pbar@progressbar{%
    \pbar@tmpcnta=\value{section} % tmpcnta stores the section number
    \pbar@tmpcntb=\totvalue{section} % tmbcountb sotres the total amount of sections
    \advance\pbar@tmpcntb by 1 % tmbcountb is advanced by 1 in order to have the last bar segment after the last node
    \pbar@tmpdim=\linewidth
    \divide\pbar@tmpdim by \pbar@tmpcntb

    \begin{tikzpicture}[very thin]
        % Clipping scope to avoid tests for the bar dimensions
        \begin{scope}
        % Clipping path
        \path[rounded corners=2pt,clip] (0pt,{-\pbar@pbht/2}) rectangle (\pbar@pbwd,{\pbar@pbht/2});
        % Gray bar (from 0 to last section)
        \path[sectionbar=mygray] (0pt,{-\pbar@pbht/2}) rectangle (\linewidth,{\pbar@pbht/2});
        % Blue bar (from 0 to the current section)
        \path[sectionbar=myblue] (0pt,{-\pbar@pbht/2}) rectangle ({(\pbar@tmpcnta-0.5)*\pbar@tmpdim},{\pbar@pbht/2});
        % Green bar (from current to next section)
        \path[sectionbar=mygreen] ({(\pbar@tmpcnta-0.5)*\pbar@tmpdim},{-\pbar@pbht/2}) rectangle ({(\pbar@tmpcnta+0.5)*\pbar@tmpdim},{\pbar@pbht/2});
        \end{scope}
        % Drawing of the nodes on top of the bars, based on the number of the current section
        \foreach \secnumber in {1,...,\totvalue{section}}{
            % Conditional definition of the colors
            \pgfmathsetmacro{\currcolor}{(\secnumber<\pbar@tmpcnta ? "myblue" : (\secnumber==\pbar@tmpcnta ? "mygreen" : "mygray"))}
            \node[sectionnode={\currcolor}{\secnumber}] at ({(\secnumber-0.5)*\pbar@tmpdim},0) {\strut\secnumber};
        }
  \end{tikzpicture}%
}

\addtobeamertemplate{headline}{}
{%
  \begin{beamercolorbox}[wd=\paperwidth,ht=10ex,center,dp=1ex]{white}%
    \pbar@progressbar%
  \end{beamercolorbox}%
}
\makeatother
BambOo
  • 8,801
  • 2
  • 20
  • 47
  • It does not work for me: "PGF Math Error: You've asked me to divide -182.09767' by0', but I cannot divide any number by `0' (in '(\pbar@tmpcnta -0.5)*\linewidth /\pbar@tmp cntb ')". – Fran Apr 12 '20 at 10:26
  • @Fran, did you compile twice ? – BambOo Apr 12 '20 at 10:31
  • Yes, but the error remain. – Fran Apr 12 '20 at 17:11
  • @Fran, well I am sorry, but I cannot reproduce your error – BambOo Apr 12 '20 at 17:17
  • Wow, thank you for your amazing efforts! Unfortunately I receive the error ! Package pgf Error: Undefined patternLines'.` - I need to figure that out... :-) Probably my TexLive is just too old - need to update! – Dave Apr 12 '20 at 21:58
  • @Dave, I hope you could make it work. In addition to this answer, I tried to find a way to reproduce the shadow effects on bars and nodes. See this post if you want to implement it – BambOo Apr 14 '20 at 07:59
  • @Fran I faced the same problem and I found a very unelegant fix: "pdflatex -interaction nonstopmode $(PAPER).tex" twice should do it. If you are using a Makefile, each time you clean the log files you will have to run this command to create the snm and nav files which contain the section numbers and titles. – elia Nov 06 '20 at 22:08