Now it's time to practice !
What I want here it's to get something flexible because it's a big graph and I think it would be very useful to scale the result. I want to adapt the dimensions and to modify the style easily.
First we need to analyse your example. We can see seven groups of nodes. The main node is Group. The nodes are linked from the left side to the right side and we can see three wrappers in gray.
The first node is easy to draw
\node[main] (shuffle) {Group};
I named this node (shuffle) and I attributed a style named main main/.style={draw,fill=yellow,inner sep=.5em}
. I give the value .5em
to inner sep
because it's more aesthetics when we change the size of the font.
The most important groups of nodes now are Reducer and Mapper. The method is the same for these groups. First we need to decide the distance between (shuffle) and Reducer. I took 48 ex
near of 8cm, the distance depends of the size of the font.
update I would like to scale so I made some modifications. It's possible to use (fit) if we use x=...
and y=...
to scale the picture but in this case I need to use values without units. I write 8 instead of 48 ex etc.
To create the node I used relative coordinate ($(shuffle)+(8,0)$)
and I named the node R0,R1+ and R1-. It's easy to understand above + below -.
\node[R] at ($(shuffle)+(8,1)$) (R1+) {Reduce};
\node[R] at ($(shuffle)+(8, 0)$) (R0) {Reduce};
\node[R] at ($(shuffle)+(8,-1)$) (R1-) {Reduce};
etc. for the Mapper group.
More complex is the first group S, because we need to use a table inside the nodes, we need to place correctly this table. I used also the relative coordinates and I decide to place the group at 9 ex before the group M. As you can see, the nodes are aligned are have the same width. I decided to use a multipart node. The code is repetitive so I created a macro \tabins
Some remarks : I try to get the same graph, so I needed to make some good choices. To place correctly the table I used [baseline=(Tab.base)
it's always the same name for each table but the objects inside this table are on the same baseline that $k_i$.
It's possible to use an array here so I don't give other explanations about this macro because inside the code is relative to TeX and not to TikZ.
Important is the style S/.style={anchor=east}
why this ? It's to align all the node to the right !
For the last nodes, problem are very similar and it's more easy.
Now, I need to draw the wrappers, there are a lot of possibilities to draw the wrappers and I don't know exactly what is the best method (It's a future question). I chose a simple method :
\begin{scope}[on background layer]
\node[fill=lightgray!50,inner sep = 4mm,fit=(shuffle),label=above:Shuffle] {};
\end{scope}
The problem with `fit', it's for scaling the picture. It was possible to create a macro because the wrapper is used three times. And a macro would be useful in another picture.
How to draw the edges. It's very easy with a \foreach
because it's always the same code.
I's important to see the difference between -- and
to`
The complete code :
% (S) -> (M) -> (V) -> (shuffle) -> (P) -> (R) - (F)
% S for Start F for Final
\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{%
calc,
fit,
shapes,
backgrounds
}
% the next macro is useful to create a table
\newcommand\tabins[3]{%
\tikz[baseline=(Tab.base)]
\node [rectangle split,
rectangle split parts=3,
draw,
align=right,
inner sep=.5em,
rectangle split horizontal] (Tab)
{\hbox to 4ex{#1}
\nodepart{two} {\hbox to 8ex{\hfill #2\$}}
\nodepart{three}{\hbox to 3ex{#3}}};
}
\begin{document}
\parindent=0pt
\begin{tikzpicture}[%
%every node/.style={transform shape},% now it's not necessary but good for a poster
x=1.25cm,y=2cm,
font=\footnotesize,
% every group of nodes have a style except for main, the style is named by a letter
main/.style={draw,fill=yellow,inner sep=.5em},
R/.style={draw,fill=purple!40!blue!30,inner sep=.5em},
M/.style={draw,fill=green!80!yellow,inner sep=.5em},
S/.style={anchor=east},
V/.style={anchor=west},
P/.style={anchor=center},
F/.style={anchor=west}
]
% main node the reference Shuffle
\node[main] (shuffle) {Group};
%group R reducer
\node[R] at ($(shuffle)+(8,1)$) (R1+) {Reduce};
\node[R] at ($(shuffle)+(8, 0)$) (R0) {Reduce};
\node[R] at ($(shuffle)+(8,-1)$) (R1-) {Reduce};
% group M Mapper
\node[M] at ($(shuffle)+(-6,+2.5)$) (M3+) {Map};
\node[M] at ($(shuffle)+(-6,+ 1.5)$) (M2+) {Map};
\node[M] at ($(shuffle)+(-6,+ .5)$) (M1+) {Map};
\node[M] at ($(shuffle)+(-6,- .5)$) (M1-) {Map};
\node[M] at ($(shuffle)+(-6,- 1.5)$) (M2-) {Map};
\node[M] at ($(shuffle)+(-6,-2.5)$) (M3-) {Map};
% group S Start the first nodes
\node[S] at ($(M3+)+(-1.5,0)$) (S3+) {\Big($k_1$,\tabins{4711}{59.90}{NY}\Big)};
\node[S] at ($(M2+)+(-1.5,0)$) (S2+) {\Big($k_2$,\tabins{4713}{142.99}{CA}\Big)};
\node[S] at ($(M1+)+(-1.5,0)$) (S1+) {\Big($k_3$,\tabins{4714}{72.00}{NY}\Big)};
\node[S] at ($(M1-)+(-1.5,0)$) (S1-) {\Big($k_4$,\tabins{4715}{108.75}{NY}\Big)};
\node[S] at ($(M2-)+(-1.5,0)$) (S2-) {\Big($k_5$,\tabins{4718}{19.89}{WA}\Big)};
\node[S] at ($(M3-)+(-1.5,0)$) (S3-) {\Big($k_6$,\tabins{4719}{36.60}{CA}\Big)};
% group V why not
\node[V] at ($(M3+)+(1.5,0)$) (V3+) {\Big(NY,59.90\$\Big)};
\node[V] at ($(M2+)+(1.5,0)$) (V2+) {\Big(CA,142.99\$\Big)};
\node[V] at ($(M1+)+(1.5,0)$) (V1+) {\Big(NY,72.00\$\Big)};
\node[V] at ($(M1-)+(1.5,0)$) (V1-) {\Big(NY,108.75\$\Big)};
\node[V] at ($(M2-)+(1.5,0)$) (V2-) {\Big(WA,19.89\$\Big)};
\node[V] at ($(M3-)+(1.5,0)$) (V3-) {\Big(CA,36.60\$\Big)};
\node[P] at ($(R1+)+(-4,0)$) (P1+) {\Big(CA,\big[142.99\$,36.60\$\big]\Big)};
\node[P] at ($(R0) +(-4,0)$) (P0) {\Big(NY,\big[59.90\$,72.00\$,108.75\big]\Big)};
\node[P] at ($(R1-)+(-4,0)$) (P1-) {\Big(WA,\big[19.89\$\big]\Big)};
\node[F] (F1+) at ($(R1+)+(1.5,0)$) {(CA,89.80\$)};
\node[F] (F0) at ($(R0) +(1.5,0)$) {(NY,80.22\$)};
\node[F] (F1-) at ($(R1-)+(1.5,0)$) {(WA,72.00\$)};
% wrappers
\begin{scope}[on background layer]
\node[fill=lightgray!50,inner sep = 4mm,fit=(shuffle),label=above:Shuffle] {};
\end{scope}
\begin{scope}[on background layer]
\node[fill=lightgray!50,inner sep = 4mm,fit=(R1+)(R1-),label=above:Reducer] {};
\end{scope}
\begin{scope}[on background layer]
\node[fill=lightgray!50,inner sep = 4mm,fit=(M3+)(M3-),label=above:Mapper] {};
\end{scope}
%edges
\foreach \indice in {3+,2+,1+,1-,2-,3-} \draw[->] (S\indice.east) -- (M\indice.west);
\foreach \indice in {3+,2+,1+,1-,2-,3-} \draw[->] (M\indice.east) -- (V\indice.west);
\foreach \indice in {3+,2+,1+,1-,2-,3-} \draw[->] (V\indice.east) to [out=0,in=180] (shuffle.west);
\foreach \indice in {1+,0,1-} \draw[->] (shuffle.east) to [out=0,in=180] (P\indice.west);
\foreach \indice in {1+,0,1-} \draw[->] (P\indice.east) -- (R\indice.west);
\foreach \indice in {1+,0,1-} \draw[->] (R\indice.east) -- (F\indice.west);
\end{tikzpicture}
\end{document}
Conclusion : 10 minutes to write the code and to get something correct, then some difficulties : the table inside the first column problem with the size and the position but it's a tex's problem not really tikz's problem. The other problem is about the wrapper because, I want to get something useful for my next pictures. Another problem not for me but for a beginner is to understand why (fit) doesn't work with scale ( some answers on this site explains the reason ).
digraph G { "a" -> "c" -> "d"; "b" -> "c" }
. Save intest.dot
and then rundot test.dot -Tsvg -o test.svg
.