10

I am trying to draw a graph (actually, generate TikZ code automatically) which has a main branch that must be straight; secondary branches must always branch on the left. On each layer there must be exactly one node, except for branches that have exactly one node (see node 17a). The order of the branches is not important, as long as the aforementioned conditions hold.

The MWE shows my problem: even manually, I cannot manage to achieve the desired result.

I have tried several combination of grow=down, grow'=down, branch left either on branching nodes when declaring the branching edge, directly on the branching edge (i.e. on the --) or in global graph options, with no result (the MWE has been polished from those not-working ugly hacks). The only thing that changes the branch order is swapping lines 17 -- 18 and 17a -- 18, but this results in a very ugly graph, so an answer that take into account this would be very appreciated (but I'll be fine even with a simpler one).

Background notes:

The graph is generated through a SAX parser, and only previous and next nodes (if any) and if the current node belong to the main branch or not is known. I know if a node is a branching point and/or joining point, so I could generate weight=0 on the branching edges (or anything else).

The graph is acyclic (all the edges actually point downwards, so arrows are superfluos and I just use --, but as long as there is no arrow, I could print '->' if this makes TikZ happier).

MWE:

\documentclass[a5paper]{article}
\usepackage{tikz}
\usepackage[default]{sourcesanspro}
\usepackage[margin=1cm]{geometry}
\usetikzlibrary{graphdrawing,graphs,calc}
\usegdlibrary{layered}
\tikzset{linehead/.style={circle, fill=white, outer sep = 0pt, inner sep = 0pt, minimum size = 5pt, thick, draw=black}}
\tikzset{linestop/.style={circle, fill=black, outer sep = 0pt, inner sep = 0pt, minimum size = 4pt}}
\tikzset{variantgraphtxt/.style={near start, left, font=\scriptsize\bfseries}}

\begin{document}
\thispagestyle{empty}
\fontsize{8.25}{9}\selectfont
\begin{tikzpicture}
\graph[layered layout, level distance=\baselineskip, sibling distance=\baselineskip,
       edges={line width=1pt, rounded corners=0.3\baselineskip}, nodes={linestop}, empty nodes, branch left]
{
  % Main branch, must be vertical
  1[linehead] --  2,
  2  --  5,
  5  --  6,
  6  --  7,
  7  --  8,
  8  --  9,
  9  -- 10,
  10 -- 11,
  11 --[minimum layers=12] 23,
  23 -- 24,
  24 -- 25,
  25 -- 26,
  26 -- 27,
  27 -- 28,
  28 -- 29,
  29 -- 30,
  30 -- 31,
  31 -- 32,
  32 -- 33,
  33 -- 34,
  34 -- 35,
  35 -- 36,
  36 -- 37,
  37 -- 38,
  38 -- 39,
  39 -- 40,
  40 -- 41,
  41 -- 42,
  42 -- 43,
  43 -- 44,
  44 -- 45[linehead],
  % all the following branches must be on the left of the main one
  2  --[weight=0, edge node={node[variantgraphtxt] {C, D}}]  3,
  3  --  4,
  4  --  5,
  10 --[weight=0,minimum layers=2,edge node={node[variantgraphtxt] {B, D}}] 12,
  12 -- 13,
  13 -- 14,
  14 -- 15,
  15 -- 16,
  16 -- 17,
  17 -- 18,
  17a[linehead,edge node={node[variantgraphtxt, at start] {B2}}] -- 18, % B2 not showing up
  19 -- 20,
  18 -- 19,
  20 -- 21,
  21 -- 22,
  22 --[weight=0] 26,
  };
\node[text=red, align=center] (text) at ($(12) + (2, \baselineskip)$) {This branch\\should be\\on the other side!};
\draw[red, ->] (text) -- ($(12) + (0.1, \baselineskip)$);
\node[text=red, align=center] (text2) at ($(17a) + (1.7, 0)$) {This branch\\should extend\\on the left as well\\ and show B2!};
\draw[red, ->] (text2) -- ($(17a) + (0.2, 0)$);
\end{tikzpicture}
\end{document}
  • Perhaps tikz trees are a better fit ? – Carel Jun 18 '16 at 1:21
  • @Carel but this is not a tree... or did I miss something? – Astrinus Jun 20 '16 at 21:02
  • In the pgfmanual version 3.0.1a there is a section on graph based trees, Chapter 29, which might be useful to you. My original comment was actually referring to Chapter 72 which is a tree only library. I should have been more specific, sorry about that. Also I'm not able to help much more at this time as my luatex isn't luatex'ing at this time. – Carel Jun 20 '16 at 21:22
1

Note: I'm far from an expert so sorry for the lack of explanation

I know it's been long since this question was asked but I had nothing to do today, so I thought "Why not learn a little TikZ today?".

As far as I could get from the manual this graphs drawing are positioned by algorithms which take into account the options you pass them (of course... duh). So when you pass weight=5 you're saying this branch has high importance to the core of the graph, so its connection to the core is tightened. Meanwhile when you pass minimum layers=<num> it throws the node <num> layers afterwards but it also means that this branch has low importance to the core, so it loosens the connection. What I failed to understand is why when using the minimum layers key the branch is thrown to the right and not the left...

Finally, you've mentioned in your question to get the 17a -- 18 branch from the left is just swapping the positions, that's right. About the label B2, it was just defined on the wrong position. And to get the big branch to the left you have to rise the weight of the nodes in the core (and not use the minimum layer option).


The Problem: node 22 node is aligned with the 25 beacause when using minimum layers TikZ automatically shoves the branch to the right (no matter where the option is used). If someone can solve this or provides a better answer I'll hapily delete this as it's not complete.


\documentclass[border=10mm]{standalone}
\usepackage{tikz}
\usepackage[default]{sourcesanspro}
%\usepackage[margin=1cm]{geometry}
\usetikzlibrary{graphdrawing,graphs,calc}
\usegdlibrary{layered}
\tikzset{linehead/.style={circle, fill=white, outer sep = 0pt, inner sep = 0pt, minimum size = 5pt, thick, draw=black}}
\tikzset{linestop/.style={circle, fill=black, outer sep = 0pt, inner sep = 0pt, minimum size = 4pt}}
\tikzset{variantgraphtxt/.style={near start, left, font=\scriptsize\bfseries}}

\begin{document}
\thispagestyle{empty}
\fontsize{8.25}{9}\selectfont
\begin{tikzpicture}
\graph[layered layout, level distance=\baselineskip, sibling distance=\baselineskip, branch left=\baselineskip,
       edges={line width=1pt, rounded corners=0.3\baselineskip}, nodes={linestop}, empty nodes]
{
  % Main branch, must be vertical
  1[linehead] --  2,
  %First branch
    2  --[edge node={node[variantgraphtxt] {C, D}}]  3,
    3  --  4,
    4  --  5,
    %end
  2  --  5,
  5  --  6,
  6  --  7,
  7  --  8,
  8  --  9,
  9  -- 10,
%Second branch
    10 --[weight=0,minimum layers=2,edge node={node[variantgraphtxt] {B, D}}] 12,
    12 -- 13,
    13 -- 14,
    14 -- 15,
    15 -- 16,
    16 -- 17,
    % Sub branch
%       17a [linehead,edge node={node[variantgraphtxt, at start] {B2}}] -- 18, % B2 not showing up because of wrong definition
        17a [linehead] -- [edge node={node[variantgraphtxt, at start] {B2}}] 18, % << This works fine
        %end
    17 -- [weight=2] 18,
    19 -- 20,
    18 -- 19,
    20 -- 21,
    21 -- 22,
    22 -- 26,
    %end
  10 -- [weight=5] 11, % << using weight to make 10 closer to 11
  11 -- 23,            % << NOT using weight so 11 and 23 are distant
  23 -- [weight=5] 24, % << using weight to make 23 closer to 24
  24 -- [weight=5] 25, % << using weight to make 24 closer to 25
  25 -- [weight=5] 26, % << using weight to make 25 closer to 26
  26 -- 27,
  27 -- 28,
  28 -- 29,
  29 -- 30,
  30 -- 31,
  31 -- 32,
  32 -- 33,
  33 -- 34,
  34 -- 35,
  35 -- 36,
  36 -- 37,
  37 -- 38,
  38 -- 39,
  39 -- 40,
  40 -- 41,
  41 -- 42,
  42 -- 43,
  43 -- 44,
  44 -- 45[linehead],
  };
\end{tikzpicture}
\end{document}
  • I've avoided the problem using a genetic algorithm to compute node positions and then output TikZ code with explicit positioning. Thank you anyway. – Astrinus Oct 12 '16 at 9:35
  • Still I think this deserves some answer, I could not find a particular reason why tikz won't put the branches to the left, even upon Setting branch right=0pt works... – Guilherme Zanotelli Oct 12 '16 at 13:54

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.