How to create the following figures in TikZ - Part 2
For (1), it's probably better to define coordinate
s which do not occupy space, rather than node
s which do occupy space. Loading the calc
library will allow you to calculate the coordinate just 1cm
above the node (k1)
:
\coordinate(n1)at($(k1)+(0,1cm)$);
For (2), instead of node[midway,above]{...}
, use node[midway,anchor=base,yshift=1ex]{...}
. Or, you can group the nodes into one scope
and set
\begin{scope}[every node/.append style={anchor=base,yshift=1ex}]
\draw[latex-latex] (n1) -- (n2) node[midway,] {Text 7};
\draw[latex-latex] (n2) -- (n3) node[midway,] {Text 8};
\draw[latex-latex] (n3) -- (n4) node[midway,] {Text 9};
\draw[latex-latex] (n4) -- (n5) node[midway,] {Text 10};
\draw[latex-latex] (n5) -- (n6) node[midway,] {Text 11};
\end{scope}
For (3), load the arrows
library, add
>=latex
to the tikzpicture
options, and pass the option |<->|
to \draw
(instead of latex-latex
):
\draw[|<->|] (n2) -- (n3) node[midway,above] {Text 8};
Full code
\documentclass[tikz,border=5pt]{standalone}
\usepackage[ngerman]{babel}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage[utf8]{inputenc}
%
\usepackage{tikz}
\usetikzlibrary{matrix,positioning,arrows,calc}
\begin{document}
\begin{tikzpicture}[
kreis/.style={circle,draw,minimum width=20pt},
every node/.style={align=center},
>=latex,
]
\matrix(mat)[row sep=10pt, column sep=60pt] at (0,0) {
\node[kreis](k1) {}; &
\node[kreis](k2) {}; &
\node[kreis](k3) {}; &
\node[kreis](k4) {}; &
\node[kreis](k5) {}; &
\node[kreis](k6) {}; \\ };
\draw[->] (k1) -- (k2);
\draw[->] (k2) -- (k3);
\draw[->] (k3) -- (k4);
\draw[->] (k4) -- (k5);
\draw[->] (k5) -- (k6);
\node [below,text width=2.5cm,font=\small] at (k1.south) {Text 1};
\node [below,text width=2.5cm,font=\small] at (k2.south) {Text 2};
\node [below,text width=2.5cm,font=\small] at (k3.south) {Text 3};
\node [below,text width=2.5cm,font=\small] at (k4.south) {Text 4};
\node [below,text width=2.5cm,font=\small] at (k5.south) {Text 5};
\node [below,text width=2.5cm,font=\small] at (k6.south) {Text 6};
\foreach \i in {1,...,6}
\coordinate(n\i)at($(k\i)+(0,1cm)$);
\foreach \j in {1,5,6}
\coordinate(m\j)at($(n\j)+(0,1cm)$);
\foreach \k in {1,6}
\coordinate(k\k)at($(m\k)+(0,1cm)$);
\begin{scope}[every node/.append style={anchor=base,yshift=1ex}]
\draw[|<->|] (n1) -- (n2) node[midway] {Text 7};
\draw[|<->|] (n2) -- (n3) node[midway] {Text 8};
\draw[|<->|] (n3) -- (n4) node[midway] {Text 9};
\draw[|<->|] (n4) -- (n5) node[midway] {Text 10};
\draw[|<->|] (n5) -- (n6) node[midway] {Text 11};
\draw[|<->|] (m1) -- (m5) node[midway] {Text 12};
\draw[|<->|] (m5) -- (m6) node[midway] {Text 13};
\draw[|<->|] (k1) -- (k6) node[midway] {Text 14};
\end{scope}
\end{tikzpicture}
\end{document}
With such a regular structure (and once you know how to do it) I think it's easier to create nodes
and coordinates
with just one matrix
. With row #/.style
and nodes in empty cells
options you can avoid some typing and mix coordinates
and kreis
nodes. Even text under kreis
nodes can be included as nodes' labels
. After that, just need to draw arrows between already created reference points.
\documentclass[tikz,border=5pt]{standalone}
\usepackage[ngerman]{babel}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage[utf8]{inputenc}
%
\usetikzlibrary{matrix,arrows}
\begin{document}
\begin{tikzpicture}[
kreis/.style={circle,draw,minimum width=20pt},
every node/.style={align=center},
>=latex,
]
\matrix(mat)[row sep=7mm, column sep=10pt, matrix of nodes,
nodes={coordinate},
row 4/.style={nodes={kreis},
every label/.style={rectangle, draw=none, font=\small,
text width=2.5cm,align=center}},
nodes in empty cells]
{
& & & & & & \\
& & & & & & \\
& & & & & & \\[-2mm]
|[label=below:Text 1]|&
|[label=below:Text 2]|&
|[label=below:Text 3]|&
|[label=below:Text 4]|&
|[label=below:Text 5]|&
|[label=below:Text 6]|\\
};
\foreach \i/\k [count=\j] in {2/Text 7, 3/Text 8, 4/Text 9,
5/Text 10, 6/Text 11}
{
\draw[->] (mat-4-\j)--(mat-4-\i);
\draw[|<->|] (mat-3-\j)--(mat-3-\i) node[above,midway]{\k};
}
\draw[|<->|] (mat-2-1) -- (mat-2-5) node[above,midway] {Text 12};
\draw[|<->|] (mat-2-5) -- (mat-2-6) node[above,midway] {Text 13};
\draw[|<->|] (mat-1-1) -- (mat-1-6) node[above,midway] {Text 14};
\end{tikzpicture}
\end{document}
Note:
There is a problem with labels
and nodes
in TiKZ v2.10
. The label node
takes node
name. This bug has been already solved in cvs
version, but a workaround for v2.10 is proposed in Some problems drawing linked lists with TikZ's matrix library. It consists in using name=none
in labels options. You can see how it works with:
\matrix(mat)[row sep=7mm, column sep=10pt, matrix of nodes,
nodes={coordinate},
row 4/.style={nodes={kreis},
every label/.style={rectangle, draw=none, font=\small,
text width=2.5cm,align=center}},
nodes in empty cells]
{
& & & & & & \\
& & & & & & \\
& & & & & & \\[-2mm]
|[label=below:Text 1]|&
|[label=below:Text 2]|&
|[label=below:Text 3]|&
|[label={[name=none]below:Text 4}]|&
|[label={[name=none]below:Text 5}]|&
|[label={[name=none]below:Text 6}]|\\
};
Edit: now, with version TikZ 3.0.1a
the ABOVE code gives expected result: