5

I have a master, "all-encompassing" (but non-standard) flow-diagram on the whiteboard to explain a methodology to readers of a journal article that I am writing. enter image description here

The problem is that I am unsure of how the final typeset diagram needs to look. I suspect this requires many iterations before the layout is suitable for a reader to understand this research. The layout of the algorithmic flow can potentially change from 'vertical to horizontal' and vice-versa multiple times. Also, connectivity between nodes seems very tricky. I'd like to minimise overlapping wires and avoid a spaghetti diagram.

After reading the first 300 pages of the pgf/Tikz manual, I started constructing this by hand-placement of the nodes, using the positioning library, and specifying constructs like above=of, below=of etc. and manually shifting the nodes around using xshift,yshift etc. After spending about a week on this, I am beginning to realise that this tedious approach might not work properly (i.e. there are lots of whitespace around the blocks etc.). Here's the result of my attempts so far.

Since I do not know the layout upfront using the <code>matrix</code> positioning i.e. using tables does not seem like a good idea.

I also read the section on Tikz's Algorithmic graph drawing capabilities, but I am not sure if my non-standard flow diagram approach will strictly fit into the classical 'graph' drawing approach. Certainly, it looks like I could benefit from the automated node positioning etc.

Am I using the right tool here? I shall be thankful if anyone can provide a starting idea of which section/type of graph drawing library might work best here, maybe with an MWE?

\RequirePackage[l2tabu,orthodox]{nag}
\RequirePackage{luatex85}
\documentclass[tikz,border=5mm]{standalone}
% \documentclass{amsart}
\usepackage{tikz}
\usetikzlibrary{positioning}
\usetikzlibrary{fit}
\usetikzlibrary{graphs}
\usetikzlibrary{shapes}
\usetikzlibrary{calc}
\usetikzlibrary{arrows.meta}
\usetikzlibrary{intersections}
% \usepackage{tkz-euclide}
% \usetkzobj{all}
% \usetikzlibrary{graphdrawing}
% \usegdlibrary{layered}

%\usepackage{microtype}
\usepackage{mathtools}
\usepackage{circuitikz}
% \usepackage{hyperref}
\newcommand{\speedsae}{\ensuremath{v__{{f_\text{sae}}}}}
\newcommand{\timesae}{\ensuremath{t__{{f_\text{sae}}}}}
\newcommand{\accsaefrac}{\ensuremath{\frac{\speedsae}{\timesae}}}
\newcommand{\accsae}{\ensuremath{a_{\text{{sae}}}=\accsaefrac}}
\newcommand{\speedmanuf}{\ensuremath{v__{{f_\text{manuf}}}}}
\newcommand{\timemanuf}{\ensuremath{t__{{f_\text{manuf}}}}}
\newcommand{\accmanuffrac}{\ensuremath{\frac{\speedmanuf}{\timemanuf}}}
\newcommand{\accmanuf}{\ensuremath{a_{\text{manuf}}=\accmanuffrac}}
\definecolor{lightgrey}{rgb}{0.918,0.929,0.929}
\definecolor{lightblue}{rgb}{0.828,0.933,0.984}
\def\crossoverradius{1.mm}
\newsavebox{\selectorswitch}

\begin{document}

\sbox{\selectorswitch}{
    \begin{circuitikz}
        \draw (0,0) node[spdt] (Sw) {}
        % (Sw.in) node[left] \rotatebox{-180}{in}
        % (Sw.out 1) node[right] {out 1}
        % (Sw.out 2) node[right] {out 2}
    ;\end{circuitikz}
}

\begin{tikzpicture}[accwidenode/.style={draw,semithick, minimum width = 3.8cm,
    minimum height = 1cm,inner sep=8pt,fill=lightgrey},
    accregularnode/.style={draw,fill=lightgrey,semithick, minimum width = 1.2cm, minimum height = 1cm, node distance=4mm},
    accsumnode/.style={draw,circle,semithick,minimum size=9mm,fill=lightgrey},
    accgainnode/.style={draw,isosceles triangle,semithick,minimum size=9mm,fill=lightgrey},
    commongainnode/.style={draw,isosceles triangle,semithick,minimum size=13mm},
    commonstylenode/.style={draw,semithick, minimum width = 1.2cm, minimum height = 1cm, node distance=4mm and 1.3cm},
    commonstyledecisionbox/.style={draw,semithick,shape aspect=1,diamond,minimum height=2.0cm,inner sep=2pt},
    accstyledecisionbox/.style={draw,fill=lightgrey,semithick,shape aspect=1,diamond,minimum height=2.0cm,inner sep=2pt},
    >=Stealth,auto
    ]
    \node[accwidenode,align = center]                     (manufspecs) { Acceleration Specs\\\footnotesize { (Vehicle Manufacturer)}};
    \node[accwidenode,right = of manufspecs]              (manufacc)   { \accmanuf};
    \node[accwidenode,align = center,below=of manufspecs] (saespecs)   { Acceleration Specs\\\footnotesize { (SAE J1666)}};
    \node[accwidenode,right = of saespecs]                (saeacc)     { \accsae};
    \coordinate (midway1) at ($(manufacc)!0.5!(saeacc)$);
    \node[accregularnode,right = of midway1,xshift=2.5cm]  (acccompare) {$>$};

    \draw[->] (saespecs) --   (saeacc);
    \draw[->] (manufspecs) -- (manufacc);
    \draw[->] (manufacc.east)[out=0,in=180] to (node cs:name=acccompare, angle=160);
    \draw[->] (saeacc.east)[out=0,in=180] to (node cs:name=acccompare, angle=200);

    % \node[accwidenode,above right = of acccompare,right=manufacc]  (setaccmanuf) {$v_f=\speedmanuf$};

    \node[accregularnode,below = of saespecs,anchor=east,xshift=-7mm,yshift=-5mm] (accpower) {$P_{acc}$};
    \node[accregularnode,below = of accpower] (dragpower) {$P_{drag}$};
    \node[accregularnode,below = of dragpower] (rollpower) {$P_{roll}$};
    \node[accregularnode,below = of rollpower] (gradepower) {$P_{grad}$};
    \coordinate (midway2) at ($(dragpower)!0.5!(rollpower)$);
    \node[accsumnode,right = of midway2,xshift=5mm]  (sumofpowers) {$\Sigma$};

    \coordinate (midway3) at ($(midway2)!0.5!(sumofpowers)$);
    \draw[->] (accpower.east)[out=0] -| ++(4mm,0) -- (sumofpowers);
    \draw[->] (dragpower.east)[out=0] -| ++(4mm,0) --   (node cs:name=sumofpowers, angle=160);
    \draw[->] (rollpower.east)[out=0] -| ++(4mm,0) --   (node cs:name=sumofpowers, angle=200);
    \draw[->] (gradepower.east)[out=0] -| ++(4mm,0) -- (sumofpowers);

    % \node[isosceles triangle,shape border uses incircle, draw,right = of sumofpowers,xshift=5mm]  (scalebydteff) {$\frac{1}{\eta_{_{dt}}}$};
    \node[accgainnode, draw,right = of sumofpowers,xshift=1mm]  (scalebydteff) {$\frac{1}{\eta_{_{dt}}}$};
    \draw[->] (sumofpowers)  --  (scalebydteff)node [near start,xshift=1mm] {\tiny{$P_{\text{wheels}}$}};

    \node[xscale=-1,rotate=90,commonstylenode, xshift=-1.5cm,yshift=1.0cm,below right = of scalebydteff] (powerselector) {\usebox{\selectorswitch}};
    \draw[->] (scalebydteff.east)[out=0] -| (node cs:name=powerselector,angle=-20) node [near start,xshift=1mm] {\scriptsize{$P_{\text{batt}}^\text{acc}$}};

    \draw[dash dot] (powerselector.north) -- ++(1.5cm,0) node[midway,above] {\tiny{acc/fast chg}} node[midway,below] {\tiny{selector}};
    \node[commongainnode,below right = of powerselector,yshift=-15mm,xshift=2mm]  (scalebyncells) {$\frac{1}{n_\text{\tiny cells}}$};
    \draw[->] (powerselector.west) |- (scalebyncells) node[near end]{\tiny{$P_\text{batt}$}};
    % \node[commonstylenode,below right = of scalebyncells,xshift=7mm] (scalebysurfacearea) {\large $\frac{1}{n^{(i)}}$};
    \node[commonstylenode,below right = of scalebyncells,xshift=7mm] (scalebysurfacearea) {$\div$};
    \draw[->] (scalebyncells.east)[out=0,in=180] -- ++(2mm,0) |- (node cs:name=scalebysurfacearea,angle=160)node [near end] {\tiny $P_{\text{cell}}$};
    \node[commonstylenode,below right = of scalebysurfacearea,yshift=-10mm,xshift=10mm,align=center] (lionsimba) {\small{Thermally-coupled}\\\small{P2d Simulation}};
    \draw[->] (scalebysurfacearea.east) -| (lionsimba.north)node [near start] {\tiny $P_{\text{density}}$};

    \node[commonstyledecisionbox,below = of lionsimba,align=center] (temperaturecheck) {\footnotesize{$T<T_{max}?$}};
    \node[accstyledecisionbox,below left = of temperaturecheck,align=center,yshift=-5mm,xshift=5mm] (cutoffvoltagecheck) {\footnotesize{$v<v_{min}?$}};
    \node[accstyledecisionbox,below = of cutoffvoltagecheck,align=center,yshift=0mm] (cutoffsoccheck) {\footnotesize{$z<z_{min}?$}};

    \draw[->] (lionsimba) -- (temperaturecheck);
    \draw[->] (temperaturecheck.south) -- ++(0,-2mm) -| (cutoffvoltagecheck.north) node[very near start,above] {$\scriptscriptstyle{yes}$};
    \draw[->,name path=successpath1] (cutoffvoltagecheck) -- (cutoffsoccheck) node[very near start,right] {$\scriptscriptstyle{yes}$};

    \node[commonstylenode, below=of cutoffsoccheck,yshift=-5mm] (noptaccgivenTcombo) {$n^\text{acc}_\text{opt}(\scriptscriptstyle{T^{(k)}_{\text{init}},T^{(k)}_{\text{sink}} \textstyle{)= n^{(i)}}$};
    \draw[->] (cutoffsoccheck) -- (noptaccgivenTcombo) node[very near start,right] {$\scriptscriptstyle{yes}$};
    \node[commonstylenode,double,below right=of
    noptaccgivenTcombo,anchor=north,yshift=-5mm,align=right] (noptgivenTcombo)
    {$n_\text{opt}= max(n^\text{acc}_\text{opt},n^\text{fastchg}_\text{opt}),$\\$\scriptscriptstyle\forall\ T_\text{init},T_\text{sink}$};
    \draw[->] (noptaccgivenTcombo.east) -| (noptgivenTcombo);

    \node[commongainnode,below left=of scalebysurfacearea,xshift=-8.75mm,yshift=4mm] (surfaceareacalcnode) {$A_\text{face}$ };
    \draw[->] (surfaceareacalcnode.east)[out=0,in=180] -- ++(2mm,0) |- (node cs:name=scalebysurfacearea,angle=200)node [near end,below] {\tiny $A_{\text{cell}}$};

    \node[commonstylenode,left=of surfaceareacalcnode,xshift=0mm,yshift=0mm,align=center] (iterativesearchalgo) {Iterative\\Search Algorithm\\$n_{min}\le n^{(i)}\le n_{max}$};
    \draw[->] (iterativesearchalgo) -- (surfaceareacalcnode)node [near start,above] (nooflayers) {$n^{(i)}$};

    \coordinate (cutoffvoltagecheckextension) at ($(cutoffvoltagecheck.west) + (-5mm,0)$);
    \coordinate (cutoffsoccheckextension) at ($(cutoffsoccheck.west) + (-5mm,0)$);
    \draw[semithick] (cutoffvoltagecheck) -- (cutoffvoltagecheckextension)node [near start,above] {$\scriptscriptstyle{no}$};
    \draw[semithick] (cutoffsoccheck) -- (cutoffsoccheckextension)node [near start,above] {$\scriptscriptstyle{no}$};
    \draw[semithick] (cutoffvoltagecheckextension) -- (cutoffsoccheckextension);
    \draw[semithick] (temperaturecheck) -| (cutoffvoltagecheckextension);
    \draw[semithick,dashed] (cutoffvoltagecheckextension) -| (node cs:name=iterativesearchalgo,angle=220) node[near end,sloped,above] {$\scriptstyle{i = i+1}$};

    \node[commonstylenode,align = center,above=of iterativesearchalgo,xshift=6mm,yshift=3mm,minimum height=13.5mm] (computenmin) {$n_{min}=1$};
    \draw[->] (computenmin.south) -| (node cs:name=iterativesearchalgo,angle=50);
    \node[commonstylenode,below left= of lionsimba,align=center] (computelengths) {Compute\\ $L_{neg} \ \& \  L_{pos}$};
    \node[commonstylenode,left = of computelengths] (lratio) {$l_{ratio} = \frac{\epsilon_{pos}}{\epsilon_{neg}$};
    \node[commonstylenode,align = center,left=of lratio,xshift=3.5mm,yshift=0mm,minimum height=13.5mm] (computenmax) {Compute\\ $n_{max}$};
    \draw[->] (computenmax.north) -| (node cs:name=iterativesearchalgo,angle=310);
    \draw[->] (lratio) -- (computenmax);
    \draw[->] (lratio) -- (computelengths);
    \draw[->] (nooflayers) |- ++(0,-14mm) -| (computelengths);
    \draw[->] (computelengths.east) -- (lionsimba);
    \node[commonstylenode,align = center,left=of lionsimba,xshift=0,yshift=0mm,minimum height=13.5mm] (computemcell)
    {Compute\\ $m_{cell}$};
\end{tikzpicture}

\end{document}
Bobyandbob
  • 4,899
  • [Pictures don't load for me right now] If you have iterations yet to come, the graph gives you the greatest flexibility in positioning. You just have to specify the horizontal and vertical relationships and can add fine positioning when you have decided on the details. As for the code you provided, please be so kind as to reduce it to its bare. – Huang_d Jun 12 '17 at 16:32
  • @Huang_d , thanks for your reply. I didn't realise that the code wasn't compliing for you. I shall try to fix and the update the post soon. Meanwhile, the figures do show up now. Sorry about this. – Dr Krishnakumar Gopalakrishnan Jun 12 '17 at 16:48
  • They show up now, no worries. Maybe you should change your approach: Do the graph in an external program that allows for frequent and easy changes (Mindmap, Inkscape, Illustrator…) so that you can iterate easily. Only when you and your team are sufficiently confident with the design should you put it into LaTeX. tikz is rather static, despite its efforts to the contrary. You could define coordinates and make all connections relative but it tends to be frustrating. It really depends on your situation. – Huang_d Jun 12 '17 at 17:04
  • Ah. I spent a week learning TikZ without writing a single line of code, and then I am invested one week into making this code. So, after two weeks of investment, I don't know if it's a good idea to move to another tool at this stage. Also, I don't know to use inkscape or other software. Do you think Tikz's automated graph drawing capability can help here? – Dr Krishnakumar Gopalakrishnan Jun 12 '17 at 17:06
  • Scrolling through the examples in the manual, yes it can help. But for arrangement issues and discussions, why not put it into some other program (No need to name all the things or position it absolutely; You are talking about relative positions and connections)? A quick google search brings up https://www.mindmup.com/ . Without having tested it, it may provide the functionality you need. Again, I'm saying this because you mention pending design changes. – Huang_d Jun 12 '17 at 17:18
  • It is possible to put a group of nodes etc. into a scope using [local bounding box=name] then treat the whole thing as a single node. – John Kormylo Jun 12 '17 at 18:52
  • @JohnKormylo, I am unable to visualise the benefit of doing what you suggested in this context. Perhaps, can you provide a specific example for this problem? – Dr Krishnakumar Gopalakrishnan Jun 12 '17 at 18:54
  • See https://tex.stackexchange.com/questions/358740/drawing-system-architecture-in-tikz/358808?s=1|0.8309#358808 and https://tex.stackexchange.com/questions/362307/best-practice-for-creating-tikz-pictures-with-nested-elements/362328?s=2|0.0214#362328 – John Kormylo Jun 12 '17 at 18:56
  • To be a bit unhelpful, you've positioned everything manually, so any whitespace is due to choices you've made. That said, if you'd like suggestions for improvements, it would be nice if you fixed the code so that it compiles without errors. – Torbjørn T. Jun 12 '17 at 18:59
  • @JohnKormylo, thank you. I don't think I am working with groups of items or nested items to be lumped as a single node. But I maybe missing your point completely. Sorry that I am unable to understand the context. Nevertheless, thank you for pointing to interesting resources. – Dr Krishnakumar Gopalakrishnan Jun 12 '17 at 19:02
  • @TorbjørnT. I am using Luatex with a specific latexmkrc compile line and shell-escape sequences etc (with vimtex as my text editor) and it seems to produce the pdf even though it shows up a bunch of errors. I am trying to produce a minimum working example by stripping out any unnecessary stuff, and also leaving out the edge connectors. Please give me a bit more time and I shall provide a source code that compiles without errors. – Dr Krishnakumar Gopalakrishnan Jun 12 '17 at 19:04
  • 2
    As this was pushed to the top again: Yes, you can sometimes get reasonable output even if you get errors, but that doesn't mean you should ignore errors. Sometimes you'll get entirely wrong output. Always fix errors if they occur. – Torbjørn T. Dec 13 '17 at 12:01
  • I find the graphs stuff very difficult, so perhaps I'm being overly pessimistic, but I am not sure that it is capable of laying out something like this. Perhaps it might be useful for small parts of the diagram, but it seems that you are likely to want a rather more precise layout than it provides. – cfr Dec 13 '17 at 23:54

0 Answers0