Erstellen Sie eine gekrümmte Zeitleiste in Tex

Erstellen Sie eine gekrümmte Zeitleiste in Tex

Ich versuche, eine Zeitleiste zu erstellen, die 24 Zeitpunkte umfasst, die wie folgt in einem gebogenen Pfeil angeordnet sind:

Bildbeschreibung hier eingeben

Ich habe eine Version mit geradem Pfeil (von @Gonzalo Medina), aber sie ist länger als die Seitenbreite, deshalb möchte ich eine gekrümmte Zeitleiste wie oben. Ich möchte Sie um Ihre Hilfe bitten. Vielen Dank.

\documentclass[a4]{article}
\usepackage[margin=0cm]{geometry}
\usepackage{ragged2e}
\usepackage{tikz} 
\usetikzlibrary{chains,shapes.arrows,fit,calc}

\definecolor{arrowcolor}{RGB}{50,130,230}
\definecolor{circlecolor}{RGB}{79,129,189}
\colorlet{textcolor}{white}
\colorlet{bordercolor}{white}

\pgfdeclarelayer{background}
\pgfsetlayers{background,main}

\newcounter{task}

\newlength\taskwidth
\newlength\taskvsep

\setlength\taskwidth{2.5cm}
\setlength\taskvsep{17pt}

\def\taskpos{}
\def\taskanchor{}

\newcommand\task[1]{%
  {\parbox[t]{\taskwidth}{\scriptsize\Centering#1}}}

\tikzset{
inner/.style={
  on chain,
  circle,
  inner sep=1pt,
  fill=circlecolor,
  line width=0.5pt,
  draw=bordercolor,
},
on grid
}

\newcommand\Time[2][]{%
\node[inner xsep=0pt] (c1) {\phantom{A}};
\stepcounter{task}
\ifodd\thetask\relax
  \renewcommand\taskpos{\taskvsep}\renewcommand\taskanchor{south}
\else
  \renewcommand\taskpos{-\taskvsep}\renewcommand\taskanchor{north}
\fi
\node[inner,font=\footnotesize\sffamily\color{textcolor}]    
  (c\the\numexpr\value{task}+1\relax) {#1};
\node[anchor=\taskanchor,yshift=\taskpos] 
  at (c\the\numexpr\value{task}+1\relax) {\task{#2}};
}

\newcommand\drawarrow{a
\ifnum\thetask=0\relax
  \node[on chain] (c1) {};
\fi
\node[on chain] (f) {};
\begin{pgfonlayer}{background}
\node[
  inner sep=10pt,
  single arrow,
  single arrow head extend=0.5cm,
  draw=none,
  fill=arrowcolor,
  fit= (c1) (f)
] (arrow) {};
\fill[white] 
  (arrow.before tail) -- (c1|-arrow.east) -- (arrow.after tail) -- cycle;
\end{pgfonlayer}
}

\newenvironment{timeline}[1][node distance=.5\taskwidth]
  {\par\noindent\begin{tikzpicture}[start chain,#1]}
  {\drawarrow\end{tikzpicture}\par}

\begin{document}

\begin{timeline}
\Time[1958]{Task 1}
\Time[1959]{Task 2}
\Time[1960]{Task 3}
\Time[1961]{Task 4}
\Time[1962]{Task 5}
\Time[1963]{Task 6}
\Time[1964]{Task 7}
\Time[1965]{Task 8}
\Time[1966]{Task 9}
\Time[1967]{Task 10}
\Time[1968]{Task 11}
\Time[1969]{Task 12}
\Time[1970]{Task 13}
\Time[1971]{Task 14}
\Time[1972]{Task 15}
\Time[1973]{Task 16}
\Time[1974]{Task 17}
\Time[1975]{Task 18}
\Time[1976]{Task 19}
\Time[1977]{Task 20}
\Time[1978]{Task 21}
\Time[1979]{Task 22}
\Time[1980]{Task 23}
\Time[1981]{Task 24}
\end{timeline}

\end{document}

Art.-Nr.:Wie kann ich eine Standardzeitleiste erstellen?[von der Community hinzugefügt]

Antwort1

Um zu beginnen...

  • Für einen Pfeil auf mehreren Linien empfehle ich die Verwendung der arrows.metaBibliothek

     % p.221
     %\usetikzlibrary {arrows.meta}
     \tikz \draw [line width=1ex,
     {Triangle Cap[reversed]-{Latex[length=0pt +2]}}]
     (0,0) -- (1,0);
    
  • Für die Beschriftung task1, task2... verwende ich \node alsomit label distancein\tikzset

BEARBEITEN: Für eine rundere Form verwende ich ein circle(mit einem clip) und füge 2 Argumente in bar arrowNr. 1 für den Anfang und Nr. 2 für das Ende hinzu.

  • Ich füge eine Länge \arrowvsepfür den Abstand zwischen den Pfeilen hinzu

Der Code

\documentclass[a4paper]{article}
% https://tex.stackexchange.com/questions/715875/create-a-curved-timeline-in-tex
\usepackage[showframe,margin=1cm]{geometry}
\usepackage{tikz} 
\usetikzlibrary{arrows.meta}
\usetikzlibrary {positioning}
\usetikzlibrary {chains}
%  color
\definecolor{arrowcolor}{RGB}{50,130,230}
\definecolor{circlecolor}{RGB}{79,129,189}
\colorlet{textcolor}{white}
\colorlet{bordercolor}{white}
%  length
\newlength\taskwidth
\newlength\taskvsep
\newlength\arrowvsep%<-- added
\setlength\taskwidth{2.cm}
\setlength\taskvsep{1.5ex}
\setlength\arrowvsep{3.cm}
%
\begin{document}
%in th doc p.601
\begin{tikzpicture}[start chain,node distance=5mm]
    % The chain is called just "chain"
    \draw[help lines] (0,-1) grid (2,1);
    \node [on chain] {A};
    \node [on chain] {B};
    \node [on chain] {C};
\end{tikzpicture}

\vspace{1cm}
\begin{tikzpicture}[start chain,node distance=5mm]
    % The chain is called just "chain"
    \draw[help lines] (0,-1) grid (2,1);
    \node [on chain,circle,draw] {A};
    \node [on chain,circle,draw] {B};
    \node [on chain,circle,draw] {C};
\end{tikzpicture}

\vspace{1cm}
%\usetikzlibrary {positioning}
\begin{tikzpicture}[start chain,node distance=1cm,on grid]
    % The chain is called just "chain"
    \draw[help lines] (0,-1) grid (2,1);
    \node [on chain,circle,draw] {A};
    \node [on chain,circle,draw] {B};
    \node [on chain,circle,draw] {C};
\end{tikzpicture}

\vspace{1cm}
\begin{tikzpicture}[start chain=1 going right,
    start chain=2 going left,
    node distance=5mm,
    every node/.style=draw]
    \draw[help lines] (0,-2) grid (3,1);
    \node [on chain=1] {A};
    \node [on chain=1] {B};
    \node [on chain=1] (C){C};
    \node [on chain=2] at ([shift={(0.5cm,-1cm)}]C) {0};
    \node [on chain=2] {1};
    \node [on chain=2] {2};
    \end{tikzpicture}

\vspace{1cm}
        % p.221
        %\usetikzlibrary {arrows.meta}
        \tikz \draw [line width=1cm,
        {Triangle Cap[reversed]-{Latex[length=0pt +2]}}]
        (0,0) -- (5,0);


 \begin{tikzpicture}
    \draw [line width=1cm,
        {Triangle Cap[reversed]-}]
        (0,0) -- (5,0);
        \begin{scope}
            \clip (5,-3) rectangle (6.5,1.5);
            \draw[line width=1cm] (5,-1) circle[radius=1cm]; 
        \end{scope}
    \draw [line width=1cm,
        -{Latex[length=0pt +2]}]
        (5,-2) -- (0,-2);
 \end{tikzpicture}


\tikzset{
    node distance=1.5cm,
    on grid,
    bar height/.initial=1.2cm,
    bar arrow/.style args={#1/#2}%
        {%
            #1-#2,
            arrowcolor,
            line width=\pgfkeysvalueof{/tikz/bar height},
            %rounded corners=5mm
        },
    inner/.style=
        {
            %on chain,
            circle,
            inner sep=1pt,
            minimum width=1cm,
            fill=circlecolor,
            line width=0.5pt,
            draw=bordercolor,
            font=\footnotesize\sffamily\color{textcolor},
        },
    label distance=\taskvsep
}

\vspace{1cm}
\noindent\centering
\fbox{%<--- comment on the final document
    \begin{tikzpicture}
    [%
        trim left=-1.5cm,% begin of the arrow at -1.5
        start chain=1 going right,
        start chain=2 going left,
    ]
    \draw[help lines] (0,0) grid (15,-4);%<-- comment in the final doc
    % \draw[bar arrow] (-1.5,0) -- (15,0) -- ++(0,-\arrowvsep)--(-1.5,-\arrowvsep);
    \draw[bar arrow={Triangle Cap[reversed]/{}}] (-1.5,0) -- (14,0);
    \begin{scope}
        \clip (14,-3.7) rectangle (16.2,1.5);
        \draw[bar arrow={{}/{}}] (14,-0.5\arrowvsep) circle[radius=0.5\arrowvsep]; 
    \end{scope}
    \draw[bar arrow={{}/{{Latex[arrowcolor, length=0pt +2]}}}] (14,-\arrowvsep) -- (-0.5\arrowvsep,-\arrowvsep);
    
    \foreach \i/\d in{
        1/1958,
        2/1958,
        3/1960,
        4/1961,
        5/1962,
        6/1963,
        7/1964,
        8/1965,
        9/1966,
        10/1967}
        {
            \node[inner,on chain=1] (N_\i)  {\d};
            \node also [label=\ifodd\i above\else below\fi:task\i] (N_\i);
        }
    \node [on chain=2] at ([shift={(1cm,-\arrowvsep)}]N_10) {};
    \foreach \i in{11,...,19}
        {
            \node[inner,on chain=2] (N_\i) {Date\i};
            \node also [label=\ifodd\i below\else above\fi:task\i] (N_\i);
        }
    \end{tikzpicture}%
}
\end{document}

Bildbeschreibung hier eingeben

Antwort2

Mir gefiel diese Art von Grafik und ich sah, dass sie sich für meine Lösungen zum Drucken massiver Etiketten eignete. Der Pfad wird in Abschnitten gezeichnet, beginnend vom Schwanz in Richtung Kopf. Wenn einer number of sectionsReihe ein bestimmter Wert erreicht wird, wird die jeweilige Kurve gezeichnet und die Abschnitte werden in die entgegengesetzte Richtung gezeichnet. Nachdem der doppelte Wert der Anzahl der Abschnitte erreicht ist, wird die andere Kurve gezeichnet und der Zähler zurückgesetzt, wodurch der Pfad automatisch wächst und schließlich der Kopf angehalten wird. Es war notwendig, die Zeichnungen an die Eingabe von Textdaten anzupassen, wodurch statt des Körpers der Kopf gezeichnet wird, wenn der Text vorhanden ist, endund in diesem Fall gibt es zwei Optionen, ob er hingeht oder zurückgeht. Wenn er zurückgeht, muss er reverseso platziert werden, dass der Kopf in die entgegengesetzte Richtung gezeichnet wird. Ich habe viel gelernt, indem ich dies gemacht und Dinge von hier und da übernommen habe. Deshalb teile ich es und wegen des Wochenendes zu Hause.

Ich verwende diese Art der Code-Organisation, weil die Daten in Zeilen angeordnet werden können und ich beim Generieren von Beschriftungen diese schnell mithilfe eines Datenblatts wie beispielsweise Excel abrufen kann, indem ich ihr jeweiliges Tikz-Codeformat in eine letzte Box exportiere.

Einige Texte habe ich zu bestimmten Themen von einem Chatbot ergänzen lassen, ich hoffe, sie sind nicht unangenehm.

ERGEBNIS: Bildbeschreibung hier eingeben

MWE:

\documentclass[tikz,border=1cm]{standalone}
\usepackage{ifthen}
\usepackage{helvet}
\definecolor{arrowcolor}{RGB}{50,130,230}

\begin{document}
    \def\NTsize{\sf\bfseries\normalsize}
    \def\CTsize{\sf\bfseries\normalsize}
    
    \def\BODY#1#2#3#4#5#6#7#8#9{
        \begin{scope}[shift={(#1)},rotate=0,transform shape]
            \ifthenelse{\equal{#2}{end}}{%Draw The end Arrow Head
                \ifthenelse{\equal{#3}{reverse}}{
                    \filldraw[#6]%Reversed Arrow
                        (-1pt,#5*0.5+#7/2)
                            -- ++(#4*0.5+1pt,0)
                            -- ++ (0,3mm) 
                            -- (#4,#5*0.5)
                            -- (#4*0.5,#5*0.5-#7/2-3mm)
                            -- ++(0,3mm)
                            -- ++(-#4*0.5-1pt,0);
                    }{
                    \filldraw[#6]%Normal Arrow
                        (#4+1pt,#5*0.5+#7/2)
                            -- ++(-#4*0.5-1pt,0)
                            -- ++ (0,3mm)
                            -- (0,#5*0.5)
                            -- (#4*0.5,#5*0.5-#7/2-3mm)
                            -- ++(0,3mm)
                            -- ++(#4*0.5+1pt,0);
                }
            }{% Draw the normal body
                \filldraw[#6] (0,#5*0.5+#7/2) rectangle ++(#4,-#7);
                \draw[white](#4*0.5,#5*0.5) node[circle,draw,fill=#6!70!black, minimum size=#7-3mm,font=\NTsize](temp){#2};
                \draw(temp)+(#8:#9) node[text width=#4-3mm, align=center,font=\CTsize](t2){#3};
                \draw[#6!40!white, preaction={draw,#6, line width=2pt}](temp)--(t2);
            }               
        \end{scope} 
    }

    \def\TAIL#1#2#3#4#5{
        \begin{scope}[shift={(#1)}]
            \filldraw[#4] (#2+1pt,#3*0.5+#5/2)-- ++(-#2*0.5-1pt,0) -- (#2*0.75,#3*0.5) -- (#2*0.5,#3*0.5-#5/2) -- ++ (1pt+#2*0.5,0);
        \end{scope} 
    }
    
    \def\CURVE#1#2#3#4#5#6{
        \begin{scope}[shift={(#1)},#4,transform shape]
            \filldraw[#5](-1pt,#3*0.5-#6/2) -- ++(1pt,0) arc (90:-90:#3*0.5-#6/2) -- ++(-1pt,0)-- ++(0,-#6) -- ++(1pt,0) arc (-90:90:#3/2+#6/2)--++(-1pt,0);
        \end{scope} 
    }
    
    \def\SNAKETEXT#1(#2)[#3][#4][#5]#6#7{%\SNAKETEXT{Contents}(Position)[x_dim][y_dim][colour]{tasks_per_line}{arrow size}
        \begin{scope}[shift={(#2)}]
            \edef\Shiftx{0}
            \edef\Shifty{0}
            \pgfmathparse{int(#6*2)}
            \xdef\tpl{\pgfmathresult}
            \foreach \cod/\direc/\dist/\desc [count=\ctr from 0] in {#1}{
                \ifnum\ctr=0
                    \TAIL{\Shiftx*#3,-\Shifty*#4-#4}{#3}{#4}{#5}{#7}
                \fi
                \ifnum\ctr<#6
                    \pgfmathparse{int(\Shiftx+1)}
                    \xdef\Shiftx{\pgfmathresult}
                    \BODY{\Shiftx*#3,-\Shifty*#4-#4}{\cod}{\desc}{#3}{#4}{#5}{#7}{\direc}{\dist}
                \fi
                \ifnum\ctr=#6
                    \pgfmathparse{int(\Shiftx+1)}
                    \xdef\Shiftx{\pgfmathresult}
                    \CURVE{\Shiftx*#3,-\Shifty*#4-#4}{#3}{#4}{}{#5}{#7}
                    \pgfmathparse{int(\Shiftx-1)}
                    \xdef\Shiftx{\pgfmathresult}
                    \pgfmathparse{int(\Shifty+1)}
                    \xdef\Shifty{\pgfmathresult}
                    \BODY{\Shiftx*#3,-\Shifty*#4-#4}{\cod}{\desc}{#3}{#4}{#5}{#7}{\direc}{\dist}
                \fi
                \ifnum\ctr>#6
                    \ifnum\ctr<\tpl
                        \pgfmathparse{int(\Shiftx-1)}
                        \xdef\Shiftx{\pgfmathresult} 
                        \BODY{\Shiftx*#3,-\Shifty*#4-#4}{\cod}{\desc}{#3}{#4}{#5}{#7}{\direc}{\dist}
                    \fi
                \fi
                \ifnum\ctr=\tpl
                    \pgfmathparse{int(\Shiftx-1)}
                    \xdef\Shiftx{\pgfmathresult}
                    \CURVE{\Shiftx*#3+#3,-\Shifty*#4-#4}{#3}{#4}{xscale=-1}{#5}{#7}
                    \pgfmathparse{int(\Shifty+1)}
                    \xdef\Shifty{\pgfmathresult}
                    \pgfmathparse{int(\Shiftx+1)}
                    \xdef\Shiftx{\pgfmathresult}
                    \BODY{\Shiftx*#3,-\Shifty*#4-#4}{\cod}{\desc}{#3}{#4}{#5}{#7}{\direc}{\dist}
                    \xdef\ctr{0}
                \fi
            }
        \end{scope} 
    }
    
    \begin{tikzpicture}
        \SNAKETEXT{
            task1/90/20mm/Detail of task 1,
            task2/-90/20mm/Detail of task 2,
            task3/90/20mm/Detail of task 3,
            task4/-90/20mm/Detail of task 4,
            task5/90/23mm/Some manual text input for more details,
            task6/-90/23mm/Become a Professional Procrastinator,
            task7/90/20mm/Organize Your Clutter,
            task8/-90/20mm/Master the Art of Napping,
            task9/90/20mm/Attend a Productivity Seminar,
            task10/-90/23mm/Create a To-Do List for Doing Nothing,
            task11/-90/20mm/Practice Active Inactivity,
            task12/90/20mm/Become an Expert at Waiting,
            task13/-90/20mm/Write a Book on Doing Nothing,
            task14/90/20mm/Achieving Zen in Pajamas,
            task15/-90/20mm/Watch 10 Hours of Cat Videos,
            task16/90/23mm/Reorganized My Sock Drawer Instead of Studying,
            task17/-90/30mm/Dedicate hours each day to scrolling through social media feeds.,
            task18/90/25mm/Spend hours contemplating the meaning of life,
            task19/-90/20mm/Some task like doing nothing,
            end/end/end/end%
        }(0,0)[25mm][50mm][arrowcolor]{10}{20mm}
    
        %Changing the font sizes
        \def\NTsize{\sf\bfseries\scriptsize}
        \def\CTsize{\sf\bfseries\scriptsize}
        \SNAKETEXT{
            JAN-30/-90/15mm/Polar Bear Plunge Day,
            FEB-29/90/15mm/International Lost Sock Memorial Day,
            MAR-13/-90/15mm/Global Labyrinth Day,
            APR-30/90/15mm/National Awkward Silence Appreciation Day,
            MAY-15/-90/15mm/World Emoji Day,
            JUN-07/-90/15mm/National Talk Like a Pirate Day,
            JUL-15/90/15mm/Global Prohibition Day,
            AUG-12/-90/15mm/National Overthinking Awareness Weeky,
            SEP-06/90/15mm/World Couch Potato Championship,
            OCT-17/-90/15mm/National Socks-with-Sandals Day,
            NOV-28/-90/15mm/ Global Pajama Conference,
            DEC-25/90/15mm/World Simultaneous Eye Roll Day ,
            end/end/end/reverse%
        }(0,-13)[25mm][30mm][green!50!black]{5}{15mm}
    
        %Changing the font sizes
        \def\NTsize{\sf\bfseries\tiny}
        \def\CTsize{\sf\bfseries\tiny}
        \SNAKETEXT{
            A/90/5mm/cmt-stg1,
            B/90/5mm/cmt-stg2,
            C/90/5mm/cmt-stg3
            D/90/5mm/cmt-stg4,
            E/90/5mm/cmt-stg5,
            F/90/5mm/cmt-stg6,
            G/90/5mm/cmt-stg7,
            H/90/5mm/cmt-stg8,
            I/90/5mm/cmt-stg9,
            J/90/5mm/cmt-stg10,
            K/90/5mm/cmt-stg11,
            L/90/5mm/cmt-stg12,
            M/90/5mm/cmt-stg13,
            N/90/5mm/cmt-stg14,
            M/90/5mm/cmt-stg15,
            O/90/5mm/cmt-stg16,
            end/end/end/end%
        }(18,-11)[20mm][10mm][cyan!50!green]{2}{5mm}
    
        %Changing the font sizes
        \def\NTsize{\sf\bfseries\tiny}
        \def\CTsize{\sf\bfseries\tiny}
        \SNAKETEXT{
            A/90/5mm/cmt-stg1,
            B/90/5mm/cmt-stg2,
            C/90/5mm/cmt-stg3
            D/90/5mm/cmt-stg4,
            E/90/5mm/cmt-stg5,
            F/90/5mm/cmt-stg6,
            G/90/5mm/cmt-stg7,
            H/90/5mm/cmt-stg8,
            I/90/5mm/cmt-stg9,
            J/90/5mm/cmt-stg10,
            K/90/5mm/cmt-stg11,
            L/90/5mm/cmt-stg12,
            M/90/5mm/cmt-stg13,
            N/90/5mm/cmt-stg14,
            M/90/5mm/cmt-stg15,
            O/90/5mm/cmt-stg16,
            P/90/5mm/cmt-stg17,
            Q/90/5mm/cmt-stg18,
            end/end/end/reverse%
        }(24,-11)[20mm][10mm][red!50!blue]{2}{5mm}
    \end{tikzpicture}
\end{document}

verwandte Informationen