8

I'm drawing some diagrams where most of the nodes are joined to each other, but occasionally I want a break.

Here's how I thought I could do it (sorry its so big):

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{chains}
\begin{document}
\begin{tikzpicture}[%
    start chain=going below,
    every node/.style={%
        join,
        on grid,
        on chain,
        draw,
        align=center,
    },
    every join/.style={->,draw}
]

\tikzset{
  none/.style={draw=none},
}

\node (a0) {A0};
\node {B0};

\node [join=by none,right=of a0] (a1) {A1};
\node {B1};

\end{tikzpicture}
\end{document}

As you can see from the output, join=by none has no effect on the unwanted join from B0 to A1:

enter image description here

Is there a way to achieve this, either as a specific option (eg no join) or as a style option? I've searched the pgfmanual.pdf but found nothing.

  • 2
    Not sure if this would work in all cases but maybe \makeatletter\tikzset{no join/.code={\let\tikz@after@path=\pgfutil@empty}} might give a useable no join key. – Mark Wibrow Jan 17 '15 at 12:36
  • @MarkWibrow Hmm, I hadn't really considered open heart surgery on TikZ, but it's an idea!!! It works like a charm; if you'd care to make it an answer, it's the leading accept candidate! – Brent.Longborough Jan 17 '15 at 12:48
5

Unfortunately, the join option doesn't just set some option that can be changed, it appends a command using append after command. Thus, setting join twice leads to multiple joins. This is how you can join multiple nodes (e.g., \node [join=with node 1, join=with node 2] {...}). So what you really need to do is delete all the append after command commands.

Now you probably don't actually want to do that, as it could cause collateral damage. (Who knows what other options that you're relying on also make use of append after command internally?) Nonetheless, I believe in directly answering people's questions even when I don't think they should use that answer. So here you go, with a minimal working example that suppresses the join option on one of the nodes:

\documentclass[varwidth,convert]{standalone}

\usepackage{tikz}
\usetikzlibrary{chains}

\begin{document}

\makeatletter
\tikzset{reset after command/.code={\def\tikz@after@path{}}}
\makeatother

\begin{tikzpicture}[start chain=going below,
    every node/.style={fill=blue!10, draw=blue!20, on chain, join=by ->},
    node distance=1em,
  ]
\node {here};
\node {are};
\node[reset after command] {some};
\node {nodes};
\end{tikzpicture}

\end{document}

enter image description here

3

Edit: What if the background is not white? asked by egreg

So I mimic a scenario with a background to verify the logic.

enter image description here

Code

\documentclass[border=0.3cm]{standalone}
\usepackage{tikz}
\usetikzlibrary{chains,backgrounds}
\begin{document}

\begin{tikzpicture}[%
    start chain=going below,
    every node/.style={%
        join,
        on grid,
        on chain,
        draw,
        align=center,
    },
    every join/.style={->,draw}
]

\tikzset{
  none/.style={->,cyan,line width=5pt}, % remove line width see the artifact
  }

\node (a0) {A0};
\node {B0};

\begin{scope}[every join/.style={->, shorten <=5pt,shorten >=5pt}]
\node [join=by none,right=of a0] (a1) {A1};
\begin{pgfonlayer}{background} 
\draw[fill=cyan] (-0.5,-1.5) rectangle (1.5,0.5);
\end{pgfonlayer}
\end{scope}

\node {B1};

\end{tikzpicture}
\end{document}

Here is a possible solution to reverse the default mentioned in the comment by the OP. The logic behind the solution is to use a scope environment to reverse the default by drawing a shorter connection line, then draw a thick line with white color to erase the short line. The erase action is defined by the none macro.

\begin{scope}[every join/.style={->, shorten <=5pt,shorten >=5pt}]
 <node commands>
\end{scope}

 none/.style={->,white,line width=5pt},     % remove line width see the artifact

enter image description here

Code

\documentclass[border=0.3cm]{standalone}
\usepackage{tikz}
\usetikzlibrary{chains}
\begin{document}

\begin{tikzpicture}[%
    start chain=going below,
    every node/.style={%
        join,
        on grid,
        on chain,
        draw,
        align=center,
    },
    every join/.style={->,draw}
]

\tikzset{
  none/.style={->,white,line width=5pt},     % remove line width see the artifact
  }

\node (a0) {A0};
\node {B0};

\begin{scope}[every join/.style={->, shorten <=5pt,shorten >=5pt}]
\node [join=by none,right=of a0] (a1) {A1};
\end{scope}

\node {B1};

\end{tikzpicture}
\end{document}
  • 1
    What if the background is not white? – egreg Jan 17 '15 at 14:12
  • Good thinking, but based on the given data, I assume white. Well. the logic still applies to different color, is it not? Some improvisation may require thou. – Jesse Jan 17 '15 at 14:21
  • Is the active background color available in some way? – egreg Jan 17 '15 at 14:23
  • After 28 mins, I seem to understand your questions --- if I apply \begin{pgfonlayer}{background} ... \end{pgfonlayer}, I think that is what you try to address. Is that the focal point of your 2nd question? – Jesse Jan 17 '15 at 14:59
  • It seems so. Maybe an experiment with differently colored background can solve any doubt. – egreg Jan 17 '15 at 15:09
2

One way will be to use white color (or similar):

\node [join= by {white,->},right=of a0] (a1) {A1};

Equivalently using your approach:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{chains}
\begin{document}
\begin{tikzpicture}[%
    start chain=going below,
    every node/.style={%
        join,
        on grid,
        on chain,
        draw,
        align=center,
    },
    every join/.style={->,draw}
]

\tikzset{
  none/.style={draw=white},
}

\node (a0) {A0};
\node {B0};

\node [join= by {none},right=of a0] (a1) {A1};
\node {B1};

\end{tikzpicture}
\end{document}

which yields

enter image description here

Sigh, the artefacts remain.

Or use the join option on individual nodes like

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{chains}
\begin{document}
\begin{tikzpicture}[%
    start chain=going below,
    every node/.style={%
        %join,
        on grid,
        on chain,
        draw,
        align=center,
    },
    mynode/.style={%
    join
    },
    every join/.style={->,draw}
]

\node[mynode] (a0) {A0};
\node[mynode] {B0};

\node [right=of a0] (a1) {A1};    %% no join here
\node[mynode] {B1};

\end{tikzpicture}
\end{document}

enter image description here

Instead of defining mynode, we could have added just join in every node except those which needn't be joined.

  • Thank you for trying. draw=white is a bit intrusive if 'something gets in the way'. And, I could, as you say, add join to every node, but as joins are in the majority, I'd like to find a way to 'reverse the default', to minimise the amount of options, mainly for readability and mantainability. – Brent.Longborough Jan 17 '15 at 12:21

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.