4

I have a code that looks something like the following, where I have arrows with text crossing over a dashed line from a rectangle.

\documentclass{article}
\usepackage[utf8]{inputenc}

\usepackage{graphicx} 
\usepackage{tikz, pgfplots}
\usetikzlibrary{positioning}

\begin{document}

\begin{tikzpicture}
   
    \draw (0,1) rectangle (2,-1) [dashed];

    \node (A) at (-1, 0) {A};
    
   \node (B) at (1, 0) {B};

    \draw [->] (-0.8, 0.1) -- (0.8, 0.1) node[above, midway] {text1};
    \draw [->] (0.8, -.1) -- (-0.8, -.1) node[below, midway] {text2};
 

    \end{tikzpicture}


\end{document}

The output of my code looks like this:

enter image description here

I would like to have the diagram arranged such that the text is layered over the rectangle. I did find that using fill opacity option for the text can fill over the rectangle, however for longer texts this also cuts out the arrow when it fills over the text, which I want to avoid:

enter image description here

I would really appreciate if someone could point me towards making an arrow with text that can just cover over the rectangle, but does not interfere with covering over other arrows/texts.

2 Answers 2

4

Just use fill=white in your nodes.
For better positioning the text, you can use yshift.
Off-topic: you can also use shift to position the arrows with respect to the nodes, instead of using absolute coordinate values.

\documentclass{article}
%\usepackage[utf8]{inputenc} non more needed

\usepackage{graphicx} 
\usepackage{tikz}
\usetikzlibrary{positioning}
\tikzset{mylabel/.style={midway, fill=white}}

\begin{document}
\begin{tikzpicture}
    \draw (0,1) rectangle (2,-1) [dashed];
    
    \node (A) at (-1, 0) {A};
    
    \node (B) at (1, 0) {B};
    
    \draw [->] (-0.8, 0.1) -- (0.8, 0.1) node[above, mylabel, yshift=.3mm] {text1};
    \draw [->] (0.8, -.1) -- (-0.8, -.1) node[below, mylabel, yshift=-.3mm] {text2};
\end{tikzpicture}
\begin{tikzpicture}
    \draw (0,1) rectangle (2,-1) [dashed];
    
    \node (A) at (-1, 0) {A};
    
    \node (B) at (1, 0) {B};
    
    \draw [->] ([shift={(-.5mm,.1cm)}]A.east) -- ([shift={(.5mm,.1cm)}]B.west) node[above, mylabel, yshift=.3mm] {text1};
    \draw [->] ([shift={(.5mm,-.1cm)}]B.west) -- ([shift={(-.5mm,-.1cm)}]A.east) node[below, mylabel, yshift=-.3mm] {text2};
\end{tikzpicture}

\vspace{1cm}

\begin{tikzpicture}
    \draw (0,1) rectangle (2,-1) [dashed];
    
    \node (A) at (-1, 0) {A};
    
    \node (B) at (1, 0) {B};
    
    \draw [->] (-0.8, 0.1) -- (0.8, 0.1) node[above, mylabel, yshift=1mm] {long text text1};
    \draw [->] (0.8, -.1) -- (-0.8, -.1) node[below, mylabel, yshift=-1mm] {long text text2};
\end{tikzpicture}
\begin{tikzpicture}
    \draw (0,1) rectangle (2,-1) [dashed];
    
    \node (A) at (-1, 0) {A};
    
    \node (B) at (1, 0) {B};
    
    \draw [->] ([shift={(-.5mm,.1cm)}]A.east) -- ([shift={(.5mm,.1cm)}]B.west) node[above, mylabel, yshift=1mm] {long text text1};
    \draw [->] ([shift={(.5mm,-.1cm)}]B.west) -- ([shift={(-.5mm,-.1cm)}]A.east) node[below, mylabel, yshift=-1mm] {long text text2};
\end{tikzpicture}
\end{document}

enter image description here

4

You could use the behind path key so that the nodes along the arrows are put behind the arrows but that won't help with them covering the previous nodes A and B.

I suggest using a non-zero outer sep. This however will mean that a line drawn to those nodes in the future will not touch the nodes but stop a bit before. A more sophisticated solution is possible by using auto = left with offset but if you don't have to reference the nodes, using outer sep is much more straight-forward.

Using the height of a capital letter (i.e. one of those in the connected nodes) we could evaluate the exact value that is needed so that the node just doesn't cover the text but the calculation aren't that straight forward because sometimes the glyphs are bigger than their reported height. (This is why I'm using -.8mm instead of -1mm. You can always just use any length here to just eyeball it.)

I've also used TikZ-CD's shift left key to draw these parallel lines without having to manually find the proper starting points. (This works best with orthongal lines and non-drawned nodes.)

Code

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{positioning}
\usetikzlibrary{cd}
\tikzset{cd/.code=\tikzcdset{#1}}
\begin{document}\centering
\begin{tikzpicture}
\draw (0,1) rectangle (2,-1) [dashed];
\node (A) at (-1, 0) {A}; \node (B) at ( 1, 0) {B};

\path[->, cd={shift left=1mm}, auto=left, nodes={fill=white}]
  (A) edge node {text1} (B)
  (B) edge node {text2} (A);
\end{tikzpicture}

\begin{tikzpicture}
\draw (0,1) rectangle (2,-1) [dashed];
\node (A) at (-1, 0) {A}; \node (B) at ( 1, 0) {B};

\path[->, cd={shift left=1mm}, auto=left, nodes={fill=white, behind path}]
  (A) edge node {longer text, only \texttt{behind path}} (B)
  (B) edge node {also covers other text}                 (A);
\end{tikzpicture}

\begin{tikzpicture}
\draw (0,1) rectangle (2,-1) [dashed];
\node (A) at (-1, 0) {A}; \node (B) at ( 1, 0) {B};

\path[->, cd={shift left=1mm}, auto=left,
      nodes={fill=white, behind path, outer sep=.5*height("A")-.8mm}]
  (A) edge node {longer text}            (B)
  (B) edge node {also covers other text} (A);
\end{tikzpicture}
\end{document}

Output

Here is the output with fill = yellow to highlight where the actual node lies.

enter image description here

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .