10

I have a tikz diagram but I think it should be simplified with foreach loop. I have try many times but I still can not get right answer!

My code as below:

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{positioning}

\begin{document}

\def\r{5pt}
\def\dy{.5cm}
\tikzstyle{c}=[draw,circle,fill=black,minimum size=\r,inner sep=0pt]
\tikzstyle{line}=[-]
\tiny
\begin{tikzpicture}[]
\node [c,label=right:$C_0$] (C0) {};
\node [c,above=\dy of C0,label=right:$C_1$] (C1) {};
\node [c,above=\dy of C1,label=right:$C_2$] (C2) {};
\node [c,above=\dy of C2,label=right:$C_3$] (C3) {};
\node [c,above=\dy of C3,label=right:$C_4$] (C4) {};

\node [c,right=\dy of C1,label=right:$C_6$] (C6) {};
\node [c,above=\dy of C6,label=right:$C_7$] (C7) {};
\node [c,above=\dy of C7,label=right:$C_8$] (C8) {};

\draw [line] (C0) -- (C1);
\draw [line] (C1) -- (C2);
\draw [line] (C2) -- (C3);
\draw [line] (C3) -- (C4);

\draw [line] (C0) -- (C6);
\draw [line] (C6) -- (C7);
\draw [line] (C7) -- (C8);
\draw [line] (C8) -- (C4);
\end{tikzpicture}

\end{document}

Output:

enter image description here

7

Something like this?

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{positioning}

\begin{document}

\def\r{5pt}
\def\dy{.5cm}
\tikzstyle{c}=[draw,circle,fill=black,minimum size=\r,inner sep=0pt, anchor=center]
\tiny
\begin{tikzpicture}
  \draw (0,0)
    node [c,label=right:$C_0$] (C0) {}
    foreach \i in {1,...,4}
      {
        -- ++(0,\dy+\r) node (C\i) [c,label=right:$C_\i$] {}
      };
  \draw (C1) ++(\dy+\r,0)
    node (C6) [c,label=right:$C_6$] {}
    foreach \i in {7,8}
      {
        -- ++(0,\dy+\r) node (C\i) [c,label=right:$C_\i$] {}
      }
    -- (C4)
    (C0) -- (C6);
\end{tikzpicture}

\end{document}

But you might also look at the chains library.

  • Thanks, one minor issue is when I remove the fill in the circle, I can see the line has draw on the circle also. I wish it only connect from circle border to border but not passthrough the circle. – Beatlej Jan 15 '15 at 3:27
  • @Beatlej I just did it the easiest way given the picture. You can change it to connect from specific anchors. However, I really think you should look at the chains library and/or the matrix of nodes suggested in the comments. These make it really easy to arrange nodes (matrix) and connect them (chains) in a grid-type layout. It will make your life much easier, I think. – cfr Jan 15 '15 at 3:37
3

This a solution with a matrix of math nodes and no chains.

\documentclass[tikz,border=2mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{matrix}

\tikzset{sha/.style={draw,circle,fill=green!20,opacity=.8,inner sep=.2pt}}

\begin{document}

\begin{tikzpicture}
\matrix (C) [matrix of math nodes, nodes={sha}, column sep=6mm, row sep=4mm]
{
C_3\\
C_2 & C_5\\
C_1 & C_4\\
C_0\\
};

\foreach \i/\j in {4/3,3/2,2/1}
    \draw [-latex] (C-\i-1)--(C-\j-1);

\draw [-latex] (C-4-1)--(C-3-2);
\draw [-latex]  (C-3-2)--(C-2-2);
\draw [-latex]  (C-2-2)--(C-1-1);
\end{tikzpicture}
\end{document}

enter image description here

  • Thanks,one question is if I need to add more nodes later, than previous ones maybe need to tweak also since matrix maybe different. – Beatlej Jan 16 '15 at 14:07
3

This is the answer you are looking for! ;-)

The other answers use chains, multiple for loops and other strange stuff. What you need is a remember your parent with an initial value of zero. Luckily this is already built into PGF, which allows this nice, condense lump of code.

\tikzstyle{c}=[draw,circle,fill=black,minimum size=5pt,inner sep=0pt]
\tikzstyle{line}=[-]
\tiny
\begin{tikzpicture}[node distance={.5cm}]          
\node [c,label=right:$C_0$] (C0) {};                       %% Initial Node
\foreach \l/\r %
[remember=\l as \lp (initially 0), remember=\r as \rp (initially 0)] %
in {1/4,2/5,3/6} {                                         %% <- node index for left/right
    \node [c,above=of C\lp,label=right:$C_\l$] (C\l) {};   %% place left node above its parent
    \node [c,right=of C\l,label=right:$C_\r$] (C\r) {};    %% place right node next to left one
    \draw[line] (C\lp) -- (C\l);                           %% draw lines to parents
    \draw[line] (C\rp) -- (C\r);
}
\node [c,above=of C3,label=right:$C_4$] (C4) {};           %% finish manually with node C4
\draw[line] (C3) -- (C4);
\draw[line] (C6) -- (C4);
\end{tikzpicture}

I used

  • l as left node
  • lp as left parent
  • r as right node
  • rp as right parent

The result looks exactly like your image, so I don't repeat it here. Thanks for the question, I learned a lot while looking for an answer.

2

One example using chain library.

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{chains}

\tikzstyle{sha}=[draw,circle,fill=green!20,opacity=.8,on chain,join,inner sep=.2pt]

\begin{document}

\begin{tikzpicture}[node distance=4mm and 6mm,
    every join/.style={->},>=latex,
    start chain=M going above]

\node[sha] (C0) {$C_{0}$};
% sub branch
\begin{scope}[start branch=B1 going above right]
  \node[sha] (C4) {$C_{4}$};
  \foreach \i in {5} {
    \node[sha,on chain=going above] (C\i) {$C_{\i}$};
  }
\end{scope}
% main branch
\foreach \i in {1,...,2} {
  \node [sha,on chain=going above] (C\i) {$C_{\i}$};
}
% merge node
\node [sha,on chain,join=with M/B1-end] {$C_{3}$};
\end{tikzpicture}
\end{document}

Output:

enter image description here

But I prefer to C4 and C5 at the same level, but now it's not. Still not clear about how to make it align with C4.

1

We can do it this way after summary so many good answers!

Use two branches M0 and M1, then merge it together.

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{positioning}
\usetikzlibrary{chains}

\tikzstyle{sha}=[draw,circle,fill=green!20,opacity=.8,on chain,join,inner sep=.2pt]

\begin{document}

\begin{tikzpicture}[node distance=4mm and 6mm,
    every join/.style={->},>=latex,
    start chain=M0 going above,
    start chain=M1 going above,
    ]
  % chain M0 for left part
  \foreach \i in {0,...,2} {
    \node [sha,on chain=M0] (C\i) {$C_{\i}$};
  }
  % chain M1 for right part
  \foreach \i in {4,5} {
    \ifnum\i=4
      \node[sha,on chain=M1,right=of C1,join=with C0] (C\i) {$C_{\i}$};
    \else
      \node[sha,on chain=M1] (C\i) {$C_{\i}$};
    \fi       
  }
  % merge M0 and M1-end to C3
  \node [sha,on chain=M0,join=with M1-end] (C3) {$C_{3}$};
\end{tikzpicture}
\end{document}

Output:

enter image description here

Or remove the if statement to save more lines:

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{positioning}
\usetikzlibrary{chains}

\tikzstyle{sha}=[draw,circle,fill=green!20,opacity=.8,on chain,join,inner sep=.2pt]

\begin{document}
\begin{tikzpicture}[node distance=4mm and 6mm,
    every join/.style={->},>=latex,
    start chain=M0 going above,
    start chain=M1 going above,
    ]
  % chain M0 for left part
  \foreach \i in {0,...,2} {
    \node [sha,on chain=M0] (C\i) {$C_{\i}$};
  }
  % chain M1 for right part
  \node[sha,on chain=M1,right=of C1,join=with C0] (C4) {$C_{4}$};
  \foreach \i in {5} {
      \node[sha,on chain=M1] (C\i) {$C_{\i}$};       
  }
  % merge M0 and M1-end to C3
  \node [sha,on chain=M0,join=with M1-end] (C3) {$C_{3}$};
\end{tikzpicture}
\end{document}
1

Just for fun with TikZ graph library.

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{graphs,graphdrawing,quotes}
\usegdlibrary{trees}
\begin{document}
\begin{tikzpicture}
  \graph [tree layout,grow=up,nodes={draw,thick,fill=blue!20,circle,inner sep=1pt}]
  { "$C_0$" -> {"$C_4$" -> "$C_5$", "$C_1$" -> "$C_2$"} -> "$C_3$" };
\end{tikzpicture}
\end{document}

enter image description here

  • Interesting code -:). so simple, but if I have multiple such block connected together, is it so easy? – Beatlej Jan 16 '15 at 23:31
  • @HenriMenke in this particular example, the quotes library isn't necessary. If math nodes is given as an argument to the \graph command then it is possible to specify the graph like this: C_0 -> {C_4 -> C_5, C_1 -> C_2} -> C_3 – Mark Wibrow Jan 17 '15 at 9:01
1

Finally, I got my finally result after reading so many great answers!

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{positioning}
\usetikzlibrary{chains}
\usetikzlibrary{decorations.pathreplacing}

\tikzstyle{sha}=[draw,circle,fill=white,opacity=.8,on chain,join,minimum size=14pt,inner sep=.2pt]
\tikzstyle{curly}=[gray,decorate,decoration={brace,amplitude=5pt}]

\begin{document}
\def\dx{.8cm}
\def\dy{.05cm}
\tiny
\begin{tikzpicture}[node distance=\dy and \dx,
    every join/.style={-},>=latex,
    start chain=M0 going above,
    start chain=M1 going above,
    start chain=M2 going above,
    start chain=M3 going above,
    ]

  % chain M0
  \foreach \i in {0,...,12} {
    \ifnum\i>8
      \node [sha,on chain=M0,fill=green!20] (C\i) {$C_{\i}$};
    \else
      \node [sha,on chain=M0] (C\i) {$C_{\i}$};
    \fi
  }
  % chain M1
  \node[sha,on chain=M1,right=\dx of C1,join=with C0] (C13) {$C_{13}$};
  \foreach \i in {14,15} {
      \node[sha,on chain=M1] (C\i) {$C_{\i}$};       
  }
  % chain M2
  \node[sha,on chain=M2,left=\dx of C5,join=with C4] (C16) {$C_{16}$};
  \foreach \i in {17,...,18} {
      \node[sha,on chain=M2] (C\i) {$C_{\i}$};       
  }
  % chain M3
  \node[sha,on chain=M3,fill=green!20,right=2*\dx of C7,join=with C4] (C19) {$C_{19}$};
  \foreach \i in {20,...,22} {
      \node[sha,on chain=M3,fill=green!20] (C\i) {$C_{\i}$};       
  }
  % decoration
  \draw[-latex] foreach \i/\j in {15/4,18/8}{(C\i) edge (C\j)};
  \draw [curly] (C19.west) -- (C22.west) 
    node [black,midway,xshift=-10pt] (A1) {\footnotesize $\delta$};
  \draw [curly] (C12.east) -- (C9.east) 
    node [black,midway,xshift=10pt] (A2) {\footnotesize $\delta$};
  \draw [->,>=latex,red!50] (A1)  to [out=90,in=0] 
    node [black,midway,sloped,midway,above] {git\ rebase} (A2);

\end{tikzpicture}
\end{document}

Output:

enter image description here

1

In 3 lines of TikZ code (9 total lines):

\documentclass[tikz,border=7mm]{standalone}
\usetikzlibrary{calc}
\begin{document}
  \begin{tikzpicture}
    \draw (0,0) -- (0,4) -- (1,3) -- (1,1) -- cycle;
    \foreach \i in {0,...,4,6,7,8}
      \node[circle,fill,label=right:$C_\i$] at ({div(\i,5)}, {mod(\i,5)}){};
  \end{tikzpicture}
\end{document}

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.