3

I have this flowchart:

\documentclass[tikz]{standalone}
\usetikzlibrary{shapes,arrows,matrix,decorations.markings}

\begin{document}
\tikzset{
  base/.style={draw,minimum width=2cm,minimum height=1cm},
  start/.style={base,rectangle},
  test/.style={base,diamond,aspect=2},
  end/.style={base,rectangle},
  link/.style={->},
  label/.style={link,%
    postaction={decorate,transform shape,%
      decoration={markings,mark=at position 0 with {\node #1;}}}},
  true/.style={label={[rotate=90,left,anchor=north east]{T}}},
  false/.style={label={[above,anchor=south west]{F}}},
  acl/.style={matrix of nodes,column sep=1cm,row sep=1cm}
}
\begin{tikzpicture}

\matrix (href) [acl] {
  \node [start] {href}; \\
  \node [test] {Authenticated}; & & & & & \node [test] {Invert}; & \node [end] {Unauthorized}; \\
  \node [test] {Member}; & & & \node [test] {Invert}; & \node [end] {Forbidden}; & \node [test] {Grant}; & \node [end] {Unauthorized}; \\
  \node [test] {Invert}; & \node [test] {Grant}; & \node [end] {Forbidden}; & \node [test] {Grant}; & \node [end] {Forbidden}; & \node [end] {OK}; \\
  \node [end] {Forbidden}; & \node [end] {OK}; & & \node [end] {OK}; \\
};

\draw [link] (href-1-1) to (href-2-1);

\draw [true] (href-2-1) to (href-3-1);
\draw [true] (href-3-1) to (href-4-1);
\draw [true] (href-4-1) to (href-5-1);
\draw [true] (href-4-2) to (href-5-2);
\draw [true] (href-4-4) to (href-5-4);
\draw [true] (href-3-4) to (href-4-4);
\draw [true] (href-3-6) to (href-4-6);
\draw [true] (href-2-6) to (href-3-6);

\draw [false] (href-2-1) to (href-2-6);
\draw [false] (href-2-6) to (href-2-7);
\draw [false] (href-3-1) to (href-3-4);
\draw [false] (href-3-4) to (href-3-5);
\draw [false] (href-3-6) to (href-3-7);
\draw [false] (href-4-1) to (href-4-2);
\draw [false] (href-4-2) to (href-4-3);
\draw [false] (href-4-4) to (href-4-5);

\end{tikzpicture}
\end{document}

flowchart

and since I'm about to write many of these, I'd like to automate the process of drawing [true] and [false] paths, since every [test] node will connect with the first node below and the first node on its right.

  • I wonder whether the tikz-cd package is flexible enough to be used here … – Qrrbrbirlbel May 2 '13 at 23:35
3

Code

\documentclass[tikz]{standalone}
\usetikzlibrary{shapes,arrows,matrix,decorations.markings}
\makeatletter
\newif\ifqrr@tikz@rightpath@started
\def\doMyMatrixPaths{\qrr@tikz@saved@rightpaths\qrr@tikz@saved@downpaths\pgfkeysalso{/tikz/initial right and down paths}}
\tikzset{
    every picture/.append style={execute at end picture=\doMyMatrixPaths},
    every matrix/.append style={initial right and down paths},
    initial right and down paths/.code=
        \global\let\qrr@tikz@saved@rightpaths\pgfutil@empty
        \global\let\qrr@tikz@saved@downpaths\pgfutil@empty,
    start right/.code={%
        \toks@\expandafter{\qrr@tikz@saved@rightpaths\path[/tikz/every right path/.try,#1]}%
        \xdef\qrr@tikz@saved@rightpaths{\the\toks@
            (\tikzmatrixname-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn) to }%
        \global\qrr@tikz@rightpath@startedtrue
    },
    start right/.default={},
    end right/.code={%
        \ifqrr@tikz@rightpath@started
            \global\qrr@tikz@rightpath@startedfalse
            \toks@\expandafter{\qrr@tikz@saved@rightpaths}%
            \xdef\qrr@tikz@saved@rightpaths{\the\toks@
                (\tikzmatrixname-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn); }%
        \fi
    },
    start down/.code={% this goes exactly one row down
        \toks@\expandafter{\qrr@tikz@saved@downpaths\path[/tikz/every down path/.try,#1]}%
        \xdef\qrr@tikz@saved@downpaths{\the\toks@
            (\tikzmatrixname-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn) to (\tikzmatrixname-\number\numexpr\pgfmatrixcurrentrow+1\relax-\the\pgfmatrixcurrentcolumn);}%
        }
}
\makeatother
\tikzset{
  base/.style={draw,minimum width=2cm,minimum height=1cm},
  start/.style={base,rectangle},
  test/.style={base,diamond,aspect=2},
  end/.style={base,rectangle},
  link/.style={->},
  Label/.style={link,%
    postaction={decorate,transform shape,%
      decoration={markings,mark=at position 0 with {\node #1;}}}},
  true/.style={draw,Label={[rotate=90,left,anchor=north east]{T}}},
  false/.style={draw,Label={[above,anchor=south west]{F}}},
  acl/.style={matrix of nodes,column sep=1cm,row sep=1cm},
  %
  every down path/.append style={true},
  every right path/.append style={false},
  test/.append style={end right,start right,start down},% end right must appear before start right!
  end/.append style={end right}
}

\begin{document}
\begin{tikzpicture}
\matrix (href) [acl] {
  |[start]| href \\
  \node [test] {Authenticated}; & & & & & \node [test] {Invert}; & \node [end] {Unauthorized}; \\
  \node [test] {Member}; & & & \node [test] {Invert}; & \node [end] {Forbidden}; & \node [test] {Grant}; & \node [end] {Unauthorized}; \\
  \node [test] {Invert}; & \node [test] {Grant}; & \node [end] {Forbidden}; & \node [test] {Grant}; & \node [end] {Forbidden}; & \node [end] {OK}; \\
  \node [end] {Forbidden}; & \node [end] {OK}; & & \node [end] {OK}; \\
};
\draw [link] (href-1-1) to (href-2-1);

\end{tikzpicture}
\end{document}

Output

enter image description here

  • Holler if more flexibility is needed. – Qrrbrbirlbel May 3 '13 at 15:22

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.