2

I'm new to TikZ and need some pointers in how I can start making diagrams like this: enter image description here

I'm trying to draw a similar diagram with the following code but it's not going very well. I'm finding it rather inefficient:

     \documentclass{standalone}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\usetikzlibrary{decorations.markings}
\usetikzlibrary{shapes.misc, positioning,intersections}

\begin{document}

\tikzset{->-/.style={decoration={
  markings,
  mark=at position .5 with {\arrow{latex}}},postaction={decorate}}}
\tikzset{-<-/.style={decoration={
  markings,
  mark=at position .5 with {\arrow{latex reversed}}},postaction={decorate}}}
    \begin{tikzpicture}
    \node[draw=black,rectangle, line width=0.2pt, minimum width=75mm, minimum height=30mm](A1) at (0,0) {};
    \draw[-<-,, transform canvas={yshift=10pt}] (A1.west) -- +(-20mm,0) node[left] (sugar) {sugar};
    \draw[-<-, transform canvas={yshift=0pt}] (A1.west) -- +(-20mm,0) node[left] (butter) {butter};
    \draw[-<-, transform canvas={yshift=-10pt}] (A1.west) -- +(-20mm,0) node[left] (egg) {egg};
    \draw[-<-, transform canvas={yshift=-20}] (A1.west) -- +(-20mm,0) node[left] (flour) {flour};

    \node[draw=black, rectangle,line width=0.2pt, minimum width=5mm, minimum height=5mm, xshift=5em,yshift=1em](mix) at (A1.west) {Mix};
    \node[draw=black, rectangle,line width=0.2pt, minimum width=5mm, minimum height=5mm, xshift=5em,yshift=-1em](beat) at (A1.west) {Beat};
    \node[draw=black, rectangle,line width=0.2pt, minimum width=5mm, minimum height=5mm, xshift=10em,yshift=0em](blend) at (A1.west) {Blend};
    \node[draw=black, rectangle,line width=0.2pt, minimum width=5mm, minimum height=5mm, xshift=17em,yshift=-1em](bake) at (A1.west) {Bake};

    \draw[->-] (A1.west) .. controls +(right:5mm) and +(up:0mm) .. (mix.west);
    \end{tikzpicture}
\end{document}
  • 1
    Hi, welcome. Could you turn your snippet into a complete, compilable example? In particular, -<- is not defined by TikZ by default. – Torbjørn T. Mar 10 '18 at 9:08
  • Here is another nice way to create a recipe with TikZ. – user121799 Mar 10 '18 at 17:05
2

I propose you a way to start to deal with this kind of diagrams, but I did not spend too much time in polishing the code (e.g. define more tikz styles, use pgf macros setting them via \pgfmathsetmacro, etc.). If you want to build on this example for future (maybe more complicated) cases, I highly encourage you to look for the feature I used that are not clear to you on the pgf manual.

A possible strategy

As you can read in the full code below, I started defining the vertex coordinates of the external frame and I tried to do everything else in a relative way to this (taking advantage of the calc and positioning tikz libraries). This can be useful if the dimensions of the external frame have to be changed. However, some hard coded length are still there and it is up to you to improve this aspect in future, if needed.

Once drawn the external frame and the internal rectangles (as nodes with a minimal size in order to take advantage of their anchors), I started defining the coordinates on the left (west) and right (east) edges of each rectangle. Here, I always did it with a \foreach loop, also if trivial, in order to have an easy-to-be-generalized code.

\pgfmathsetmacro{\dx}{3}
\foreach \y [evaluate=\y as \dy using \y/6] in {1,...,5}{
    \coordinate (W\y) at ([xshift=-\dx mm]$(SW)!\dy!(NW)$);
}

Here the idea is to place N (here above N=5) coordinates which are equidistant on the left edge of the big rectangular frame. This means to divide the left edge it in 6 parts, and each coordinate is distant 1/6, 2/6, 3/6, 4/6, 5/6 of the full length from one vertex (here the bottom one). The [xshift=-\dx mm] is needed to set the coordinate outside or inside the rectangular frame, to get later the path going beyond the edge.

Afterwards it remains to connect the created coordinate and, for this purpose, I defined the style connect,

\tikzset{
    connect/.style={mid arrow=#1, out=0, in=180, ->, >=stealth, looseness=2},
    connect/.default=6mm
}

which is used later on a path and which connects the west (out=0) of the starting point to the east (in=180) of the ending point, terminating with an arrow. Here I use, on top, the looseness key to model the shape of the path. The remaining task is to add labels along the path, but this is standard and I did it as in this other question.

To add the arrow on the edge is discussed in many questions (e.g. this or this) which address how to do so.


Full code

\documentclass[border =3mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{positioning, calc, decorations.markings}

\tikzset{
    mid arrow/.style={postaction={decorate,decoration={markings,mark=at position #1 with {\arrow{stealth}}}}},
    connect/.style={mid arrow=#1, out=0, in=180, ->, >=stealth, looseness=2},
    connect/.default=6mm
}
\begin{document}

    \begin{tikzpicture}
        \coordinate (SW) at (0,0); \coordinate (SE) at (7,0);
        \coordinate (NE) at (7,3); \coordinate (NW) at (0,3);
        %Frames
        \draw[black] (SW) rectangle (NE);
        \node[draw, minimum size=1cm] (dry) at ({$(NW)!0.25!(NE)$} |- {$(SW)!0.75!(NW)$}) {};
        \node[draw, minimum size=1cm] (wet) at ({$(NW)!0.25!(NE)$} |- {$(SW)!0.25!(NW)$}) {};
        \node[draw, minimum size=1cm] (mix) at ({$(NW)!0.75!(NE)$} |- {$(SW)!0.6!(NW)$}) {};
        %Extra coordinates for path
        \pgfmathsetmacro{\dx}{3}
        \foreach \y [evaluate=\y as \dy using \y/6] in {1,...,5}{
            \coordinate (W\y) at ([xshift=-\dx mm]$(SW)!\dy!(NW)$);
        }
        \foreach \y [evaluate=\y as \dy using \y/4] in {1,...,3}{
            \coordinate (dryW\y) at ([xshift=\dx mm]$(dry.south west)!\dy!(dry.north west)$);
        }
        \foreach \y [evaluate=\y as \dy using \y/2] in {1}{
            \coordinate (dryE\y) at ([xshift=-\dx mm]$(dry.south east)!\dy!(dry.north east)$);
        }
        \foreach \y [evaluate=\y as \dy using \y/3] in {1,2}{
            \coordinate (wetW\y) at ([xshift=\dx mm]$(wet.south west)!\dy!(wet.north west)$);
        }
        \foreach \y [evaluate=\y as \dy using \y/3] in {1,2}{
            \coordinate (wetE\y) at ([xshift=-\dx mm]$(wet.south east)!\dy!(wet.north east)$);
        }
        \foreach \y [evaluate=\y as \dy using \y/3] in {1,2}{
            \coordinate (mixW\y) at ([xshift=\dx mm]$(mix.south west)!\dy!(mix.north west)$);
        }
        \foreach \y [evaluate=\y as \dy using \y/2] in {1}{
            \coordinate (mixE\y) at ([xshift=-\dx mm]$(mix.south east)!\dy!(mix.north east)$);
        }
        \foreach \y [evaluate=\y as \dy using \y/3] in {1,2}{
            \coordinate (E\y) at ([xshift=\dx mm]$(SE)!\dy!(NE)$);
        }
        %Paths (left-right, bottom-up)
        \path[every node/.style={font=\scriptsize}]
            (W1) edge[connect] node[pos=0.0, left=3mm] {eggs} (wetW1)
            (W2) edge[connect] node[pos=0.0, left=3mm] {milk} (wetW2)
            (W3) edge[connect] node[pos=0.0, left=3mm] {salt} (dryW1)
            (W4) edge[connect] node[pos=0.0, left=3mm] {sugar} (dryW2)
            (W5) edge[connect] node[pos=0.0, left=3mm] {flour} (dryW3)
            (wetE1) edge[connect] node[pos=0.12, below] {egg yolks} node[pos=1.0, right=3mm] {egg yolks}(E1)
            (wetE2) edge[connect] node[pos=0.2, above=3mm] {wet mix} (mixW1)
            (dryE1) edge[connect] node[pos=0.2, above] {dry mix}(mixW2)
            (mixE1) edge[connect] node[pos=1.0, right=3mm] {cookie batter}(E2);
    \end{tikzpicture}

\end{document}

enter image description here

2

Another

\documentclass{standalone}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\usetikzlibrary{decorations.markings}
\usetikzlibrary{shapes.misc, positioning,intersections,calc,fit}

\begin{document}

\tikzset{->-/.style={decoration={
  markings,
  mark=at position .5 with {\arrow{latex}}},postaction={decorate}}}
\tikzset{-<-/.style={decoration={
  markings,
  mark=at position .5 with {\arrow{latex reversed}}},postaction={decorate}}}
    \begin{tikzpicture}


\coordinate(n0) at (0,0);
\node[minimum size=1cm,draw, above=0.5cm of n0] (n1) {};
\node[minimum size=1cm,draw, below=0.5cm of n0](n2){};
\node[minimum size=1cm,draw, right=5cm of n0](n3){};
\foreach \nn in {n1,n2,n3}{
    \foreach \pp in{25,33,50,67,75}{
    \coordinate (w-\nn-\pp) at ($(\nn.north west)!0.\pp!(\nn.south west) + (0.2,0)$);
    \coordinate (e-\nn-\pp) at ($(\nn.north east)!0.\pp!(\nn.south east) - (0.2,0)$);
    }
}

\draw[->-] (e-n1-50) to[out=0, in=180] node[pos=0.3,above]{dry mix} (w-n3-33);

\draw[->-] (e-n2-33) to[out=0, in=180] node[pos=0.3,above]{wet mix} (w-n3-67);

\node[draw,fit=(n1) (n2) (n3), minimum height=3.5cm, minimum width=7cm ](cadre){};

\foreach \pp in{16,33,50,67,83}{
    \coordinate (w-cadre-\pp) at ($(cadre.north west)!0.\pp!(cadre.south west) - (0.5,0)$);
    \coordinate (e-cadre-\pp) at ($(cadre.north east)!0.\pp!(cadre.south east) + (0.5,0)$);
}


\node[left] at (w-cadre-16)(flour){flour};
\node[left] at (w-cadre-33)(sugar){sugar};
\node[left] at (w-cadre-50)(salt){salt};
\node[left] at (w-cadre-67)(milk){milk};
\node[left] at (w-cadre-83)(eggs){eggs};

\node[right] at (e-cadre-33)(cookie){cookie baker};
\node[right] at (e-cadre-67)(yolks){egg yolks};

\draw[->-] (flour) to [out=0, in=180] ( w-n1-25);
\draw[->-] (sugar) to [out=0, in=180] ( w-n1-50);
\draw[->-] (salt) to [out=0, in=180] ( w-n1-75);
\draw[->-] (milk) to [out=0, in=180] ( w-n2-33);
\draw[->-] (eggs) to [out=0, in=180] ( w-n2-67);

\draw[->-] (e-n3-50) to [out=0, in=180] (cookie);

\draw[->-] (e-n2-67) to [out=0, in=180] (yolks);
    \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.