4

There is the need to draw graphs like the following for a specific subject, the intent is to create a template where others can be created easily.

There are some requisites

  • No need to mind about the color or the specific position.
  • tikz-external library and babel-portuguese are needed so the answer shoudnt have conflicts with these.

These are some ideas

  • It would be the best to use the auto positioning of graphs to create named nodes as vertices, so they can be used for relative positioning of labels.

Studying tikz-graphs the skeleton can be very easily created with the following:

\documentclass{standalone}

% Needed \usepackage[portuguese]{babel} % Babel

% Tikz \usepackage{tikz} \usetikzlibrary{ babel, external, % needed graphs, graphdrawing, arrows.meta, } \usegdlibrary{layered}

% External setup \tikzexternalize[ up to date check={simple}, % faster check figure list=true, % generate list of figures file ] \tikzsetfigurename{figure.\arabic{part}.\arabic{section}.} % set figure names

% Tikz graphs style \tikzstyle{mygraphsstyle}=[ % Arrows > ={Stealth[round,sep]}, shorten > =3pt, shorten < =3pt, ]

% Graphs style \tikzset{ % Graphs style graphs/every graph/.append style={ nodes={circle,draw,fill,fill opacity=0.1}, layered layout, grow'=right, level distance=6em, sibling sep=6ex, }, }

\begin{document}

\tikzset{external/remake next=true} % remake next graph \begin{tikzpicture}[mygraphsstyle] \graph{ % Layers {[same layer] 4}; {[same layer] 6,5,7}; {[same layer] 8,9}; {[same layer] 10,11,12};

    % Graph
    1 -&gt; 2 -&gt; 3 -&gt; 4 -&gt; {6,5,7};
    6 -&gt; 8 -&gt; 10 -&gt; 13;
    7 -&gt; 9 -&gt; 12 -&gt; 13;
    5 -&gt; 7;
    5 -&gt;[dashed] 8;
    9 -&gt; 11 -&gt;[dashed] 12;
};

\end{tikzpicture}

\end{document}

What we have so far

Graph generated by the code

The goal image

Project planning graph

AndréC
  • 24,137
Felipe9
  • 309
  • As I read it you can make graphs draw other nodes, described in 36.8.3 How To Generate Nodes Inside an Algorithm . Well, the "SimpleHuffman" described there is not that simple, i.e. gives a lot of chance to programming errors with long debug sessions ... – MS-SPO May 26 '23 at 04:17
  • Im sorry i might have explained badly, or i coudnt understand that section. What i actually meant when suggesting creating nodes was to have each vertice be a named node, as if graphs would create them with \node (1) at (x,y){} so that i could later use \node[draw, below=3ex] at (1){1}; for example. The main idea is to have a streamlined process, and having graphs placing the nodes position to me would be perfect. – Felipe9 May 26 '23 at 18:05

2 Answers2

3

Here's a way to do it without \graph. It's merely a sketch of the basic things you need, with room for adjustments (as given). Introducing externalization, language and templating shouldn't be a problem. Some specifics:

The basic idea is relative positioning \pics like you'd do with nodes, which comes with some extras:

    \pic                        (A) at (0,0) {el={1/0/0}};
    \pic [right=of A-x]         (B) {el={2/2/2}};

According to '\pic' in tikz it seems to be necessary to define some inner node for relative positioning, here -x, which you can refer to. The \pic is defined here, with:

\tikzset{
    pics/el/.style args={#1/#2/#3}{% allow parameters
        code={
            % adjust
            \node [draw,circle,minimum width=7mm] (-x) {#1};
            \node [draw,below=2.5mm of -x,anchor=east] {#2};
            \node [draw,below=2.5mm of -x,anchor=west] {#3};
            }   
        }
    }
  • passing 3 arguments (args in a syntax of your choice)
  • providing code to do the drawings
  • defining the inner reference point, here -x
  • doing some fine adjustments for the boxes below the circle
  • this is also the place where you can introduce coloring of shape and text, or a positioning flag for the boxes as #4, with values like u,b,l,r (however, I'd just pass an angle or a polar coordinate for positioning the boxes)

What's left to do is providing some connectors with some text labels, like so:

    \draw [->] (A-x) -- node [above] {$A_2$} (B-x);

result

\documentclass[10pt,border=3mm,tikz]{standalone}
\usepackage{tikz}
\usetikzlibrary{positioning}

\begin{document}

\tikzset{ pics/el/.style args={#1/#2/#3}{% allow parameters code={ % adjust \node [draw,circle,minimum width=7mm] (-x) {#1}; \node [draw,below=2.5mm of -x,anchor=east] {#2}; \node [draw,below=2.5mm of -x,anchor=west] {#3}; }
} }

\begin{tikzpicture}
% ~~~ pics ~~~~~~ \pic (A) at (0,0) {el={1/0/0}}; \pic [right=of A-x] (B) {el={2/2/2}}; \pic [right=of B-x] (C) {el={3/6/6}}; \pic [right=of C-x] (D) {el={4/16/16}}; \pic [above right=of D-x] (E) {el={6/22/26}}; \pic [right=of D-x] (F) {el={5/20/20}}; \pic [below right=of D-x] (G) {el={7/25/25}};

% ~~~ connectors ~~~~~~~~~
\draw [-&gt;] (A-x) -- node [above] {$A_2$} (B-x);
\draw [-&gt;] (B-x) -- (C-x);
\draw [-&gt;] (C-x) --node [below] {$C_{10}$}  (D-x);
\draw [-&gt;] (D-x) -- (E-x);
\draw [-&gt;] (D-x) -- (F-x);
\draw [-&gt;] (D-x) -- (G-x);

\end{tikzpicture}

\end{document}

MS-SPO
  • 11,519
  • Although it doesn't solve using graphs it is a middle therm that optimizes much the drawing of those graphs, i appreciate that, thanks. – Felipe9 Jun 03 '23 at 16:45
  • Would you know of a way to make linking those nodes with arrows more stream lined? like using a command such as how graphs does? for example, after creating the nodes using the \pic do something like \drawArrows[above,,below,...][$A_2$,,$C_{10}$,...]{A-x,B-x,C-x,...} – Felipe9 Jun 03 '23 at 16:51
  • 1
    You can try writing such as a macro. However, Tikz doesn't seem to cooperate with \newcommand, but seems to tolerate tex-ish \def. // Usually, just writing consistent code with nice formatting is all you need. – MS-SPO Jun 03 '23 at 17:10
  • Again, you CAN replace a graph's node text, like "1", with some complicated drawing, the code to do that is rather non-obvious, i.e. error-prone (see my previous comment). So, this approach deliberatly says good-bye to the graphs approach, allowing pdflatex again. Which route you want to take, is up to you, of course. – MS-SPO Jun 03 '23 at 17:18
3

In my opinion, if something looks like a matrix of nodes it is usually easier to position them like so instead of forcing some Lua algorithm to do that.

Here I'm using a matrix of single node graphs that install \tmng at the start of each non-empty cell which has the following argument specification:

|<annot options>|<left annotation>:<right annotation>:[<node options>]<graph specification>;

where |<annot options>| and the [<node options>] arg optional.

This means a cell entry with

|below| 37: 38: [yshift=-2em] 11;

will get transformed to

\graph{11[yshift=-2em, annot={below}{37}{38}]};

where annot is setup to produce a label of a rectangle split shape with two entries (here 37 and 38). The ; at the isn't the usual ; at the end of paths but it is just as important and leaving it out will break everything.

This doesn't necessarily needs the graph library/syntax inside the cells but it makes it a bit more lenient when it comes to spaces.

Code

\documentclass[tikz]{standalone}
\usepackage[portuguese]{babel}
\usetikzlibrary{arrows.meta, babel, graphs, shapes.multipart, quotes}
\tikzset{
  annotation/.style={
    draw=red, shape=rectangle split, rectangle split horizontal, rectangle split parts=2},
  annot/.style n args={3}{label={[direction shorthands,annotation,#1]{#2\nodepart{two}#3}}},
  matrix of single node graphs/.style={
    matrix, graphs/every graph/.append style={#1}, execute at begin cell=\tmng}}
\usepackage{xparse} % argment type u needs package
\NewDocumentCommand{\tmng}{D||{} u: u: O{} u;}
  {\graph[no placement]{#5[#4,annot={#1}{#2}{#3}]};}
\begin{document}
\tikz[>={Stealth[round, sep]}, thick, node font=\sffamily]
  \matrix[
    matrix of single node graphs={
      nodes={
        circle, draw=blue, fill=blue!25, align=center, text width=width("00")}},
    label distance=+.5ex,
    row sep={2cm,between origins},
    column sep={2cm,between origins}]{
      & & & &        22:26: 6;
      &              29:33: 8;
      &              38:42:10; \\
        |below|       0: 0: 1;
      & |below|       2: 2: 2;
      & |below|       6: 6: 3;
      & |above, anchor=south east|
                     16:16: 4;
      & |right|      20:20: 5;
      & &            38:38:12;
      & |below|      44:44:13; \\
      & & &
      & |below|      25:25: 7;
      & |below|      33:33: 9;
      & |below|      37:38:[yshift=-2em]11; \\}
  graph[
    use existing nodes,
    edge={draw=blue},
    edge quotes={auto, execute at begin node=$, execute at end node=$}
  ]{
    1 ->["A_2"]     2
      ->["B_4"]     3
      ->["C_{10}"'] 4
      ->["F_4"]     5
      ->["H_5"]     7
      ->["I_8"]     9
      ->["K_5"]    12
      ->["L_6"]    13,
    4 ->["D_6"]     6
      ->["G_7"]     8
      ->["M_9"]    10
      ->["N_2"]    13,
    4 ->["E_7"']    7,
    5 ->[dashed]    8,
    9 ->["J_4"]    11
      ->[dashed]   12
  };
\end{document}

Output

enter image description here

Qrrbrbirlbel
  • 119,821
  • Thanks, that does look like it solves it, and i have no idea how you managed to use quoted with the portuguese babel activated, it activate the char " leading to errors on my machine. As for the graphs package the intent was to use it to auto place the nodes i expected that it would make drawing easier and more readable, in the end i think i would be using some variation of the solution proposed by @MS-SPO as base plus some ideas you proposed in yours. Thanks again for the contribution. – Felipe9 Jun 05 '23 at 18:30