Pfeil und Häkchen in Tikz reparieren

Pfeil und Häkchen in Tikz reparieren

So korrigieren Sie den Pfeil und die Markierungen (Jahre) unten, damit sie gut aussehen. Außerdem erfahren Sie, wie Sie eine Linie von den Balken zur Jahreszahl unten hinzufügen, wie im beigefügten Bild gezeigt.

Hier ist mein Ergebnis.

Bildbeschreibung hier eingeben

Hier ist mein Code

\documentclass[a4paper,12pt,titlepage,twoside,final,openany]{book}
\usepackage{tikz}
\usetikzlibrary{arrows.meta} % Arrows library
\usepackage[pdftex,a4paper=true,pagebackref=false]{hyperref} % with basic options
\usepackage[left=2cm,right=2cm,top=2cm,bottom=4.5cm]{geometry}% Redefine the page margins 


\begin{document}
    \begin{tikzpicture}[x=\textwidth/47] % Adjusted scale
        % Draw the horizontal line with an arrow at the end, extending beyond 2040
        \draw[thick, -{Triangle[length=3mm, width=2mm]}] (0,0) -- (47,0); % Extend line beyond 2040
        
        % Draw tick marks and label for each year from 1994 to 2040
        \foreach \year in {1994,1995,...,2040} {
            \pgfmathsetmacro{\xpos}{\year-1994}
            \draw (\xpos,0.25) -- (\xpos,-0.25) node[below] {\tiny \year};
        }
        
        
        % Additional gradient bar from 2016 to 2040
        \shade[left color=green, right color=red, middle color=yellow] (22,2.6) rectangle (46,3.0);
        % Add text inside the additional colored bar
        \node[text=black] at (36,2.8) {20neo};
        % Red dashed arrow starting at the end of the "A330-900" gradient bar
        \draw[dashed, ->, >=latex, line width=0.2cm, draw=red] (46.2,2.8) -- (47.2,2.8);
        
        
        % Gradient bar from 2020 to 2040
        \shade[left color=green, right color=red, middle color=yellow] (26,2) rectangle (46,2.4);
        % Add text inside the additional colored bar
        \node[text=black] at (36,2.2) {800};
        % Red dashed arrow starting at the end of the "A330-800" gradient bar
        \draw[dashed, ->, >=latex, line width=0.2cm, draw=red] (46.2,2.2) -- (47.2,2.2);
        
        
        % Gradient bar from 2018 to 2040
        \shade[left color=green, right color=red, middle color=yellow] (24,1.4) rectangle (46,1.8);
        % Add text inside the new colored bar
        \node[text=black] at (35,1.6) {900};
        % Red dashed arrow starting at the end of the "A330-900" gradient bar
        \draw[dashed, ->, >=latex, line width=0.2cm, draw=red] (46.2,1.6) -- (47.2,1.6);
        
        
        % Draw colored bar (red) from 1998 to 2019 for A330-200
        \fill[red] (4,0.8) rectangle (25,1.2);
        % Add text inside the red colored bar
        \node[text=white] at (14.5,1.0) {200};
        % Draw a dashed line at the level and height of the red colored bar from 2019 to 2039
        \draw[dashed, red, line width=0.4cm] (25,1.0) -- (45,1.0); % Line from 2019 to 2039
        
        
        % Draw a blue colored bar from 1994 to 2020 above the horizontal line
        \fill[blue] (0,0.3) rectangle (26,0.7);
        % Add text inside the blue colored bar
        \node[text=white] at (13,0.5) {300};
        % Draw a dashed blue line from 2020 to 2040 at the level and height of the first colored bar
        \draw[dashed, blue, line width=0.4cm] (26,0.5) -- (46,0.5); % Line up to 2040
        
        
    \end{tikzpicture}
    
\end{document}

Antwort1

Falls Sie mehr als ein Diagramm zeichnen möchten, empfehle ich einen Ansatz, bei dem einige Schlüssel verwendet werden, um viele der fest codierten Werte und Berechnungen zu entfernen.

Mit der yearFunktion kann der Wert 2000 von den Jahreszahlen abgezogen werden. Die Funktion PGFMath wertet den Kürzungsbetrag der Endspitzenspezifikation aus, um die Stelle zu ändern, an der das schattierte Rechteck endet.

Die beiden Schleifen, die die Balken platzieren, bilden einen Pfad, sodass sie markerim Hintergrund gezeichnet werden können.

Code

\documentclass[tikz]{standalone}
\usetikzlibrary{arrows.meta}
\makeatletter
\pgfmathdeclarefunction{arrowlengthend}{0}{%
  \begingroup\nullfont
    \pgf@arrow@compute@shortening\pgf@end@tip@sequence
    \pgfmath@returnone\pgf@xa\endgroup}
\makeatother
\tikzset{
  outer sep=auto,
  reset row counter/.code=\setcounter{tikzrowcounter}{0},
  increment row/.code=\stepcounter{tikzrowcounter}%
                      \tikzset{shift=(up:\value{tikzrowcounter})},
  edges/.style={every edge/.append style={#1}},
  rect to/.style={to path=rectangle(\tikztotarget)\tikztonodes}}
\newcounter{tikzrowcounter}
\tikzset{
  bar height/.initial=4mm,         % controls the height of the bars
  bar/.style={line width=\pgfkeysvalueof{/tikz/bar height}},
  bar arrow rect/.style={
    draw=none, left color=green, right color=red, middle color=yellow, rect to},
  bar arrow style/.style={
    nodes=black, bar, -{Latex[red, length=+0pt +2, width=+0pt +1.4]}},
  bar dashy/.style={dashed, dash phase=3pt},
  bar marker style/.style={arrows=-{Latex[round]}, thick, purple, line to},
  %
  bar with dash/.style args={#1-#2-#3:#4}{
    edges=bar, nodes=white,
    insert path={
      (year #1, 0) edge[line to]   node{#4} (year #2, 0)
      (year #2, 0) edge[line to, bar dashy] (year #3, 0)
      [bar marker={#1}]}},
  bar with tip/.style args={#1-#2:#3}{
    bar arrow style, nodes=black,
    insert path={
      (year #1,-\pgfkeysvalueof{/tikz/bar height}/2) edge[bar arrow rect] node{#3}
      ([xshift=-arrowlengthend]year #2, \pgfkeysvalueof{/tikz/bar height}/2)
      (year #1,0) edge[line to, tips, path only] (year #2, 0)
      [bar marker={#1}]}},
  bar marker/.style={
    insert path={
      node[purple!50!black, rotate=90, above, scale=.6] at (year #1, 0) {#1}
      [behind path](year #1, -\pgfkeysvalueof{/tikz/bar height}/2) coordinate(@)
                    edge[bar marker style={#1}] (@|-start)}},
  %
  bar diagram/.style={
    y=6mm,             % controls the distance between rows
    declare function={year(\y)=\y-2000;},
    reset row counter}} % if you have more than one diagram
\begin{document}
\begin{tikzpicture}[x=\textwidth/47, bar diagram]
\draw[thick, -{Triangle[length=3mm, width=2mm]}, shorten <=+-1mm, shorten >=+-4mm]
     (year 1994,0) coordinate (start) -- (year 2040,0);
\draw[thin, xstep=1, ystep=0] (year 1994, -1.00mm) grid (year 2040, 1.00mm);
\draw[thin, xstep=5, ystep=0] (year 1994, -2.00mm) grid (year 2040, 2.00mm);
\foreach \y in {1995, 2000, ..., 2040}
  \node[below] at (year \y, -2.5mm) {\y};

\path % one path allows us to easily place the marker in the background
      % see “behind path” in style “marker”
  foreach \c/\t in {blue/1994-2020-2040:300, red/1998-2019-2039:200}{
    [increment row, edges=\c, bar with dash/.expand once=\t]
  }
  foreach \t in {2018-2040:900, 2020-2040:800, 2016-2040:20neo}{
    [increment row, bar with tip/.expand once=\t]
  };
\end{tikzpicture}
\end{document}

Ausgabe

Bildbeschreibung hier eingeben

Antwort2

  • um den Pfeil zu fixieren, mitshorten >=-4pt

  • Häkchen (Jahre) unten, um gut auszusehen, schlage ich vor, alle 5 Jahre anzuzeigen

  • Linie von den Balken zur Jahreszahl hinzufügen, mit\draw

  • Um die Lesbarkeit zu verbessern, können Sie Stile in tikzset definieren

  • Sie können auch Schleifen verwenden

  • Ich habe die letzten Takte nicht vereinfacht...

     \documentclass[border=5mm]{standalone}
     \usepackage{tikz}
     \usetikzlibrary{arrows.meta} % Arrows library
    
     \begin{document}
     \tikzset{
         myarrow/.style = {thick,-{Triangle[length=3mm, width=2mm]},shorten <=-2pt-\pgflinewidth,},
         myshade/.style = {left color=green, right color=red, middle color=yellow},
         mytext/.style = {black},
         myBigarrow/.style = {->, >=latex, shorten >=-4pt,line width=0.2cm, draw=red},
         mymark/.style = {blue},
         }
     \begin{tikzpicture}[x=\textwidth/47] % Adjusted scale
         % Draw the horizontal line with an arrow at the end, extending beyond 2040
         \draw[myarrow] (0,0) -- (47.5,0); %<-- change in 47.5  Extend line beyond 2040
    
         % Draw tick marks and label for each year from 1994 to 2040
         \foreach \year in {1994,1995,...,2040} {
             \pgfmathsetmacro{\xpos}{\year-1994}
             \draw (\xpos,0.15) -- (\xpos,-0.15);
         }
         \foreach \year in {1995,2000,...,2040} {
             \pgfmathsetmacro{\xpos}{\year-1994}
             \draw [thick](\xpos,0.25) -- (\xpos,-0.25) node[below] {\tiny \year};
         }
    
         % Additional gradient bar from 2016 to 2040
         \foreach \x/\y/\lib in {22/2.6/20neo,24/1.4/800,26/2/900}%
             {
                 \shade[myshade] (\x,\y) rectangle (45.4,\y+0.4) node[midway]{\lib};
                 \draw[myBigarrow] (46.2,\y+0.2) -- +(1,0);        
                 \draw [mymark](\x,\y) -- (\x,0);
                 }
    
         % Draw colored bar (red) from 1998 to 2019 for A330-200
         \fill[red] (4,0.8) rectangle (25,1.2);
         % Add text inside the red colored bar
         \node[text=white] at (14.5,1.0) {200};
         % Draw a dashed line at the level and height of the red colored bar from 2019 to 2039
         \draw[dashed, red, line width=0.4cm] (25,1.0) -- (45,1.0); % Line from 2019 to 2039
    
    
         % Draw a blue colored bar from 1994 to 2020 above the horizontal line
         \fill[blue] (0,0.3) rectangle (26,0.7);
         % Add text inside the blue colored bar
         \node[text=white] at (13,0.5) {300};
         % Draw a dashed blue line from 2020 to 2040 at the level and height of the first colored bar
         \draw[dashed, blue, line width=0.4cm] (26,0.5) -- (46,0.5); % Line up to 2040
     \end{tikzpicture}
     \end{document}
    

Bildbeschreibung hier eingeben

Antwort3

So kann man es machen. Einige Anmerkungen:

  1. Ich denke, Sie sollten nicht vergessen, Folgendes einzuschließen transform shape.

  2. Ich habe einige Refactorings durchgeführt gradund einen neuen Stil hinzugefügt ln, mit dem Sie das Aussehen der vertikalen Linien variieren können. Zeichnen Sie sie zuletzt, wenn sie die anderen Balken überschreiben sollen.

  3. Ich habe einen Vorschlag zu rotierten Jahreszahlen gemacht.

  4. Die schattierten Balken sehen etwas seltsam aus: Es gibt wahrscheinlich eine bessere Möglichkeit, das zu machen. Im Moment habe ich die Rechteckgröße einfach um 0,4 cm reduziert, sodass es aufhört, bevor die Spitze beginnt. Ich schlage vor, auch die spitzenbezogenen Optionen zu überarbeiten.

  5. Um auf die linken Seiten der Balken zu verweisen, merke ich mir ihre Koordinaten wie \shade[grad] (22,2.6) coordinate (S1) ... und verwende sie später.

  6. Zeichnen Sie abschließend alle Vertikalen wie \draw[ln] (S1) -- +(0,-2.6);, die Sie zu einer Schleife verkürzen könnten \foreach, die den Wert pais wie (indikativ) annimmt.S1*-2.6

Ergebnis

\documentclass[a4paper,12pt,titlepage,twoside,final,openany]{book}
\usepackage{tikz}
\usetikzlibrary{arrows.meta} % Arrows library
\usepackage[pdftex,a4paper=true,pagebackref=false]{hyperref} % with basic options
\usepackage[left=2cm,right=2cm,top=2cm,bottom=4.5cm]{geometry}% Redefine the page margins 


\begin{document}
    % <<< don't forget transform shape ~~~~~~~~~~~~~~~~~~~~~~~~~~
    \begin{tikzpicture}[x=\textwidth/47,transform shape, % Adjusted scale
        % <<< some refactoring ~~~~~~~~~~~~~~~~
        grad/.style={left color=green, right color=red, middle color=yellow},
        % <<< new ~~~~~~~~~~~~
        ln/.style={dashed,line width=3pt,teal},
    ]
        % Draw the horizontal line with an arrow at the end, extending beyond 2040
        \draw[thick, -{Triangle[length=3mm, width=2mm]}] (0,0) -- (47,0); % Extend line beyond 2040
        
        % Draw tick marks and label for each year from 1994 to 2040
        \foreach \year in {1994,1995,...,2040} {
            \pgfmathsetmacro{\xpos}{\year-1994}
            % <<< suggestion ~~~~~~~~~~~~~~~~~~~~~~~~
            \draw (\xpos,0.25) -- (\xpos,-0.25) 
                                    node[anchor=east,rotate=90] {\tiny \year};
        }
        
        
        % Additional gradient bar from 2016 to 2040
        % <<< remember left coordinates ~~~~~~~~~~~~~~~
        \shade[grad] (22,2.6) coordinate (S1) rectangle (45.6,3.0);%<<< suggestion
        % Add text inside the additional colored bar
        \node[text=black] at (36,2.8) {20neo};
        % Red dashed arrow starting at the end of the "A330-900" gradient bar
       \draw[dashed, ->, >=latex, line width=0.2cm, draw=red] (46.2,2.8) -- (47.2,2.8);
        
        
        % Gradient bar from 2020 to 2040
        \shade[grad] (26,2) coordinate (S2) rectangle (46,2.4);
        % Add text inside the additional colored bar
        \node[text=black] at (36,2.2) {800};
        % Red dashed arrow starting at the end of the "A330-800" gradient bar
        \draw[dashed, ->, >=latex, line width=0.2cm, draw=red] (46.2,2.2) -- (47.2,2.2);
        
        
        % Gradient bar from 2018 to 2040
        \shade[grad] (24,1.4) coordinate (S3) rectangle (46,1.8);
        % Add text inside the new colored bar
        \node[text=black] at (35,1.6) {900};
        % Red dashed arrow starting at the end of the "A330-900" gradient bar
        \draw[dashed, ->, >=latex, line width=0.2cm, draw=red] (46.2,1.6) -- (47.2,1.6);
        
        
        % Draw colored bar (red) from 1998 to 2019 for A330-200
        \fill[red] (4,0.8) coordinate (B1) rectangle (25,1.2);
        % Add text inside the red colored bar
        \node[text=white] at (14.5,1.0) {200};
        % Draw a dashed line at the level and height of the red colored bar from 2019 to 2039
        \draw[dashed, red, line width=0.4cm] (25,1.0) -- (45,1.0); % Line from 2019 to 2039
        
        
        % Draw a blue colored bar from 1994 to 2020 above the horizontal line
        \fill[blue] (0,0.3) coordinate (B2) rectangle (26,0.7);
        % Add text inside the blue colored bar
        \node[text=white] at (13,0.5) {300};
        % Draw a dashed blue line from 2020 to 2040 at the level and height of the first colored bar
        \draw[dashed, blue, line width=0.4cm] (26,0.5) -- (46,0.5); % Line up to 2040

        % <<< lines; you could replace it by a foreach on value-pairs ~~~~
        \draw[ln] (S1) -- +(0,-2.6);
        \draw[ln] (S2) -- +(0,-2.0);
        \draw[ln] (S3) -- +(0,-1.4);
        \draw[ln] (B1) -- +(0,-0.8);
        \draw[ln] (B2) -- +(0,-0.3);
        
        
    \end{tikzpicture}
    
\end{document}

verwandte Informationen