1

I have difficulty adjusting the starting coordinates of the arrow line inside a TikZ node:

enter image description here

When I try to make the starting vertical coordinate of the last arrow which is beneath the mid point of the node, a bit higher vertically by subtracting 0.1 like so:

\draw[*-{Stealth},very thick] let \p1 = (B.two), \p2 = (B.center) in (\x1+\nodewidth * 0.10, \y2 -0.1) |- (C);

the starting point jumps above the mid point:

enter image description here

I have tinkered with several other options but still I couldn't position the starting points into the mid point of the node.

The code is just a bit long but it's compiled fine.

% compile with lualatex 
\documentclass[a4paper,openany,14pt]{extbook}

\usepackage{tikz}
\usetikzlibrary{shapes.multipart,chains,positioning,arrows,calc}

\usetikzlibrary{arrows.meta}
\tikzset{*->stealth}

\usetikzlibrary{fit}

\usepackage{xparse}

\makeatletter % get the dimensions of the box (node) which was formed prior
\NewDocumentCommand {\getnodedimen} {O {\nodewidth} O {\nodeheight} m} {
  \begin{pgfinterruptboundingbox}
  \begin{scope}[local bounding box=bb@temp]
    \node[inner sep=0pt, fit=(#3)] {};
  \end{scope}
  \path ($(bb@temp.north east)-(bb@temp.south west)$);
  \end{pgfinterruptboundingbox}
  \pgfgetlastxy{#1}{#2} }
\makeatother

\usepackage{fontspec}
\usetikzlibrary{matrix}

\newcommand{\columnratio}{0.62}
\newcommand{\columnseper}{12pt}

\begin{document}

\pgfmathsetlengthmacro{\ourwidth}{\columnratio * \linewidth - \columnseper}

\tikzset{kutu/.style = {rectangle split, rectangle split horizontal,rectangle split parts=2, very thick,draw=black!100, align=center,font=\footnotesize, text width=0.047 * \ourwidth,minimum width=0.040 * \ourwidth, text height=0.023 * \ourwidth,text depth=2.7pt,inner xsep=0.27cm,}} % kutu is the turkish word for "box"

\noindent\begin{tikzpicture}[start chain=1 going right,start chain=2 going right]
\tikzset{every node}=[font=\small\ttfamily]
      
\node[rectangle, on chain=1,inner xsep=0.05cm,](ORIG){\footnotesize 1511};
\node[kutu,on chain=1,right=0.0cm of ORIG] (A) 
     {\nodepart[]{one}1111 \nodepart[]{two}};

\node[kutu, on chain=1,right=0.4cm of A,] (B)
     {\nodepart[]{one} \nodepart[]{two}};

\node[kutu, on chain=1,right=0.4cm of B] (C)
     {\nodepart[]{one}2111 \nodepart[]{two}};

\node[kutu, on chain=2,below=0.8cm of B] (D) at (6.0, -0.5)
     {\nodepart[]{one}3422 \nodepart[]{two}};
     
\getnodedimen{A} % we extract the dimensions of the box we just formed, in order to position
                 % the starting coordinate of the arrow line. It gives as output the "nodewidth"

 \draw[*-{Stealth},very thick] let \p1 = (A.two), \p2 = (A.center) in (\x1+\nodewidth * 0.10, \y2) -- (B);
 \draw[*-{Stealth},very thick] let \p1 = (B.one), \p2 = (B.center) in (\x1+\nodewidth * 0.10, \y2) |- (D);
 \draw[*-{Stealth},very thick] let \p1 = (B.two), \p2 = (B.center) in (\x1+\nodewidth * 0.10, \y2) |- (C);
\end{tikzpicture}
\end{document}

How to adjust the starting points of the arrow lines precisely so that they are aligned into the mid and center points inside the TikZ node ?

UPDATE After applying this code

 \draw[very thick,red,{Circle[length=6pt,sep=-3pt]}-{Stealth}] ($(B.west)!0.25!(B.east)$) |- (D.west);
 \draw[very thick,red,{Circle[length=6pt,sep=-3pt]}-{Stealth}] ($(B.two)$) |- (C.west);

upon daleif 's comment, the situation improved greatly:

enter image description here

As such, that comment solves the problem but what is the ($(B.west)!0.25!(B.east)$) notation exactly? It looks like the math notation of TeX but I assume the expression inside $ s does arithmetic / calculates values when used whithin the context of TikZ, is that right?

8
  • I'd say that there's an issue with the *-... arrow, the * is inside the path instead of from the start. There's probably a setting for this. I'd just use \draw[thick,red] ($(B.west)!0.25!(B.east)$) |- (D.west) ; (when the dot on the arrow is fixed), IMO much simpler syntax)
    – daleif
    Apr 29 at 10:32
  • Well, given that * marks an arrow tip it does what it is suppose to, the dot touches the edge of the arrow. So it does what it is suppose to. I'd just draw the arrow without the dot, then then add the dot afterwards. There might be a setting to move the tip, but I don't know it.
    – daleif
    Apr 29 at 10:39
  • Here is one way: \draw[thick,red,{Circle[length=6pt,sep=-3pt]}->] ($(B.west)!0.25!(B.east)$) |- (D.west) ;, if you know the diameter of the dot, then a negative sep of half the radius seems to do the trick.
    – daleif
    Apr 29 at 10:42
  • 1
    The (A)!x!(B) notation is explain in the manual. It makes a new point on the line between (A) and (B). If x=0 the point is (A), i x-=1 it's (B). Additionally if (A) is a node, it has many extra points, like A.center, A.west, A.north east etc. All of these can be used in coordinate calculations.
    – daleif
    Apr 29 at 11:34
  • 1
    You'll learn along the way. The manipulation of coordinates are super useful, also defining aux coordinates to just be used in calculations are also very useful. FOr many things in tikz, there is a elegant solution that require a doctorate degree in tikz/pgf to understand, and then there is brute force method.
    – daleif
    Apr 29 at 12:27

2 Answers 2

3

With use of the chains library and define arrows start position by perpendicular coordinate systems:

\documentclass[border=3.141592,tikz]{standalone}
\usetikzlibrary{arrows.meta, 
                chains,
                positioning,
                shapes.multipart}

\begin{document}
    \begin{tikzpicture}[
node distance = 8mm and 8mm,
  start chain = A going right,
   box/.style = {rectangle split, rectangle split horizontal,
                 rectangle split parts=2,
                 draw, thick,
                 text width=3em, minimum height=3ex, 
                 align=center},
   arr/.style = {draw=#1, thick,
                 {Circle[length=6pt,sep=-3pt]}-{Stealth[width=6pt]}
                },
   arr/.default = red
                    ]
% nodes
    \begin{scope}[nodes={on chain=A}]
\node       {1511};                     % A-1
\node[box]  { 1111 \nodepart{two} };
\node[box]  {      \nodepart{two} };
\node[box]  { 2111 \nodepart{two} };    % A-4
    \end{scope}
\node[box, below=of A-4] (A-5) {3422 \nodepart{two} };
% arrows
\path[arr=black]
            (A-2.two north |- A-2.east) -- (A-3);
\path[arr]  (A-3.two north |- A-3.east) -- (A-4);
\path[arr]  (A-3.one north |- A-3.west) |- (A-5);
    \end{tikzpicture}
\end{document}

enter image description here

Addendum: Regarding to your comments:

  • You should provide this requirements already in question. It si not contain requirements for possibilities of changes node size (and eventually distances between them).

  • Conditionality for accepting this answer only if I comply with your new requirements in the answer is not polite (actually is unacceptable).

  • Anyway, on image size can be influenced on many ways:

    • by scaling of image (not recommended, font size become inconsistent)
    • by changing node distance between nodes
    • \nptw (node part text width) for text width in box style
    • both aforementioned options you can define after tikzpicture image
    • adding option for font size (if you need for example smaller fonts

Adopted MWE to this requirements can be:

\documentclass[border=3.141592,tikz]{standalone}
\usetikzlibrary{arrows.meta,
                chains,
                positioning,
                shapes.multipart}
\tikzset{mystyles/.style = {
  start chain = A going right,
   box/.style = {rectangle split, rectangle split horizontal,
                 rectangle split parts=2,
                 draw, thick,
                 text width=\nptw, minimum height=3ex, inner sep=2pt,
                 align=center},
   arr/.style = {draw=#1, thick,
                 {Circle[length=6pt,sep=-3pt]}-{Stealth[width=6pt]}
                },
   arr/.default = red}
        } % end of tikzset

\begin{document}
    \begin{tikzpicture}[mystyles,
         font = \scriptsize,    % change to desired size
node distance = 5mm and 4mm,    % <---
                        ]
\def\nptw{2em}                  % <--- define box cells width
% nodes
    \begin{scope}[nodes={on chain=A}]
\node       {1511};                     % A-1
\node[box]  { 1111 \nodepart{two} };
\node[box]  {      \nodepart{two} };
\node[box]  { 2111 \nodepart{two} };    % A-4
    \end{scope}
\node[box=\nptw, below=of A-4] (A-5) {3422 \nodepart{two} };
% arrows
\path[arr=black]
            (A-2.two north |- A-2.east) -- (A-3);
\path[arr]  (A-3.two north |- A-3.east) -- (A-4);
\path[arr]  (A-3.one north |- A-3.west) |- (A-5);
    \end{tikzpicture}
\end{document}

enter image description here

6
  • Thank you for the answer. It's got some nice bits such as defining the Circle in arr/.style so that it doesn't have to be repeated in \path or \draw However when I apply the parameters on the text width as in text width=0.047 * \ourwidth (instead of hardcoding them as in text width=3em) the texts then float to the right inside the node they almost touch the right edge making them look awkwardly unaligned. I have to apply those parameters because the whole drawing must fit in a smaller section in the page (for the book I'm writing) Apr 30 at 20:38
  • If you are interested in my selecting your answer as accepted, I'd expect this problem to be fixed. If you wish, I may post this "parameter" problem as a new question, too. Apr 30 at 20:38
  • @LarsMalmsteen, I'm not sure what you after ... Do you like to have parameter for set nodes parts widths? See addendum to answer (will appear ASAP).
    – Zarko
    Apr 30 at 21:37
  • My 2nd comment was a tad misprinted. Corrected form is below: Apr 30 at 21:55
  • In order to align the texts, I've found a neat solution: In front of say 1111 in \nodepart[]{one}1111 put \hspace*{-3pt} so that it reads: \nodepart[]{one}\hspace*{-3pt}1111 But I have to put that \hspace*{-3pt} expression manually in front of other node texts, like 2111 and 3422 In order to avoid repetition, I considered parameterizing the node text by adding \nodepart[]{one} text = {\hspace*{-3pt} #1 } and \nodepart[]{two} text = {\hspace*{-3pt} #2} into the box/.style but not surprisingly that didn't work. Apr 30 at 21:55
1

This should help you reach your goal:

\documentclass[tikz]{standalone}
\usetikzlibrary{arrows.meta}
\usetikzlibrary{calc}
\usetikzlibrary{positioning}
\usetikzlibrary{shapes.multipart}

\begin{document}
\begin{tikzpicture}[
    node distance=1cm,
    box/.style={
        draw, thick,
        rectangle split,
        rectangle split horizontal,
        rectangle split parts=2,
        text width=1.25cm,
        minimum height=.65cm,
        inner sep=0pt,
        align=center
    },
    arrow/.style={
        thick,
        {Circle[length=6pt,sep=-3pt]}-{Stealth[width=6pt]}
    }
]
    % nodes
    \node (ORIG) {1511};
    \node[box, right=.25cm of ORIG] (A) {
        1111 \nodepart{two}
    };
    \node[box, right=of A] (B) {
        \nodepart{two}
    };
    \node[box, right=of B] (C) {
        2111 \nodepart{two}
    };
    \node[box, below=of B, anchor=west] (D) {
        3422 \nodepart{two}
    };

    % arrows
    \draw[arrow] ($(A.west)!.75!(A.east)$) -- (B.west);
    \draw[arrow, red] ($(B.west)!.25!(B.east)$) |- (D.west);
    \draw[arrow, red] ($(B.west)!.75!(B.east)$) -- (C.west);

    % added to show how two entries can be used
    \node[box, right=of D, blue] (E) {
        A \nodepart{two} B
    };
    \draw[arrow, blue] ($(D.west)!.75!(D.east)$) -- (E.west);
\end{tikzpicture}
\end{document}

Result

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.