1

I am having difficulty to align label of arrows into compact and readable position. In drawing program I can easily put the text of arrow into readable places but its much difficult in tikz. Please see output of the wanted figure:

enter image description here


My simple approach:

\documentclass[tikz]{standalone}
\usetikzlibrary{shapes}
\begin{document}
\begin{tikzpicture}[>=latex,shorten >=2pt,shorten <=2pt,shape aspect=1]
    [%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        arrow/.style={->, >=stealth, very thick},
    ]%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    \node[block] (A) [cylinder, shape border rotate=90, draw,minimum height=2.5cm,minimum width=2cm]{C};
    \node[block] at (140:7) (B) [rectangle, shape border rotate=90, draw,minimum height=1cm,minimum width=3cm]{Some Program} ;
    \node[block] at (40:7) (C) [rectangle, shape border rotate=90, draw,minimum height=2cm,minimum width=3cm]{Some Program A};
    \node[block] at (90:5) (D) [circle, shape border rotate=90, draw,minimum height=1cm,minimum width=1cm]{D};
    \draw [arrow] (B) -- node[below] {latex is awesome, latex is awesome} (A) ;
    \draw [arrow] (C) -- node[below] {latex is awesome, latex is awesome} (A);
    \draw [arrow] (B) -- node[above] {latex is awesome} (D);
    \draw [arrow] (C) -- node[above] {latex is awesome} (D);
\end{tikzpicture}
\end{document}

enter image description here

Here I am unable to coordinate the label of arrows to the correct position. Add -> style into arrows.

4
  • 1
    First, you need to use only one pair of brackets after \begin{tikzpicture}. That's why your arrows don't have tips. Then you may need to use [above left] for example, instead of [above] to place your labels. You also can place your labels not in the middle of your arrow but anywhere you want like this: \draw[arrow] (A) -- (B) node[above left, pos=0.75] {your text}. Those adjustements should suffice.
    – SebGlav
    Jun 4 at 17:40
  • Can the caption width limited as well?
    – alper
    Jun 4 at 21:29
  • @alper Caption width can be set through e.g.: \draw[arrow] (A) -- (B) node[text width=2cm,above left, pos=0.75] {your text}
    – Tom
    Jun 4 at 22:34
  • can also pos make the alignment in the x-axis? seems like it shift the caption in y-axis
    – alper
    Jun 4 at 22:55

2 Answers 2

1

With use relative coordinates, library quotes for edge labels (quotes), defined picture's elements as its options and colored nodes:

\documentclass[margin=3mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{arrows.meta,
                positioning,
                quotes,
                shapes}


\begin{document}
    \begin{tikzpicture}[
node distance = 22mm and 33mm,
every edge/.style = {draw, {Stealth[scale=0.8]}-{Stealth[scale=0.8]}, semithick,
                     shorten >=2pt, shorten <=2pt},
every edge quotes/.style = {auto, font=\footnotesize, inner xsep=-1em, 
                            text width=9em, align=center},
         C/.style = {circle, draw, fill=yellow!30, minimum size=5ex},
        DB/.style = {cylinder, shape aspect=0.5,
                     shape border rotate=90,
                     draw, fill=orange!30,
                     minimum width=16mm, minimum height=8mm, inner sep=1mm, align=center,
                    },
      mpnv/.style = {rectangle split, rectangle split parts=#1,
                     draw, fill=cyan!30, inner sep=1pt,
                     text width=7em, align=flush center},
         N/.style = {draw, fill=olive!30, minimum width=7em, minimum height=5ex},
                        ]
\node (A)   [N]                 {Some Program} ;
\node (D)   [C, right=of A]     {D};
\node (C)   [mpnv=3, right=of D,
             anchor=one west]  {Some Program A
                                 \nodepart{two}     Some Program B
                                 \nodepart{three}   Some Program C
                                 };
\node (DB)  [DB, below=of D]    {C};
%
\draw   (A)     edge ["latex is awesome"]   (D)
        (D)     edge ["latex is awesome"]   (C.one west)
        (A)     edge ["{latex is awesome,
                       latex is awesome}" ']   (DB)
        (DB)    edge ["{latex is awesome,
                        latex is awesome}" ']   (C.three west)
                   ;
    \end{tikzpicture}
\end{document}

enter image description here

Addendum Regarding your comment, you can use suggestion of @unknow (see her/his comment below) or consider my comment below and accordingly slightly rewrite above propose MWE:

\documentclass[margin=3mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{arrows.meta,
                positioning,
                quotes,
                shapes}

\begin{document}
    \begin{tikzpicture}[
node distance = 22mm and 23mm,                                      % <---
  base/.style = {font=\footnotesize, draw, fill=#1,                 % <---
                 text width=7em, align=flush center,                % <---
                 minimum height=8mm},                               % <---
every edge/.style = {draw, {Stealth[scale=0.8]}-{Stealth[scale=0.8]}, semithick,
                     shorten >=2pt, shorten <=2pt},
every edge quotes/.style = {auto, font=\scriptsize, inner xsep=0pt, 
                            text width=6em, align=flush center},    % <---
         C/.style = {circle, base=yellow!30, text width =8mm=5ex},
        DB/.style = {cylinder, shape aspect=0.3,                    % <---
                     shape border rotate=90,
                     base=orange!30,                                % <---
                     text width=16mm, inner sep=1mm, align=center,
                    },
      mpnv/.style = {rectangle split, rectangle split parts=#1,
                     base=cyan!30},                  % <---
         N/.style = {base=olive!30},
                        ]
\node (A)   [N]                 {Some Program} ;
\node (D)   [C, right=of A]     {D};
\node (C)   [mpnv=3, right=of D,
             anchor=one west]  {Some Program A
                                 \nodepart{two}     Some Program B
                                 \nodepart{three}   Some Program C
                                 };
\node (DB)  [DB, below=of D]    {C};
%
\draw   (A)     edge ["latex is\\ awesome"]   (D)
        (D)     edge ["latex is\\ awesome"]   (C.one west)
        (A)     edge ["{latex is awesome,
                       latex is awesome}" ']   (DB)
        (DB)    edge ["{latex is awesome,
                        latex is awesome}" ']   (C.three west)
                   ;
    \end{tikzpicture}
\end{document}

All changes in comparison to the first MWE are marked in code by % <---. Beside changes font sizes, are changed distanced between nodes and at horizontal edges and edge quotes broken into two lines. Consequently image can be narrower -- by reducing node distance as I did in above MWE.

In the case, that you like to have all text in script size, in above MWE you only need to change in base style define font size: font=\scriptsize or consider @unknown suggestion and from style remove all font size definitions.

enter image description here

Addendum (2): In cases, that you like to have edge quotes above and below edge, you ca split it in two parts and for one of the use swap or its shortcut ':

\documentclass[margin=3mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{arrows.meta,
                positioning,
                quotes,
                shapes}

\begin{document}
    \begin{tikzpicture}[
node distance = 22mm and 23mm,                                      % <---
  base/.style = {font=\footnotesize, draw, fill=#1,                 % <---
                 text width=7em, align=flush center,                % <---
                 minimum height=8mm},                               % <---
every edge/.style = {draw, {Stealth[scale=0.8]}-{Stealth[scale=0.8]}, semithick,
                     shorten >=2pt, shorten <=2pt},
every edge quotes/.style = {auto, font=\scriptsize, inner xsep=0pt,
                            TW=#1, align=flush center},             
         C/.style = {circle, base=yellow!30, text width =8mm=5ex},
        DB/.style = {cylinder, shape aspect=0.3,                    
                     shape border rotate=90,
                     base=orange!30,                                
                     text width=16mm, inner sep=1mm, align=center,
                    },
      mpnv/.style = {rectangle split, rectangle split parts=#1,
                     base=cyan!30},                  
         N/.style = {base=olive!30},
        TW/.style = {text width=#1},
      TW/.default = {6em}
                        ]
\node (A)   [N]                 {Some Program} ;
\node (D)   [C, right=of A]     {D};
\node (C)   [mpnv=3, right=of D,
             anchor=one west]  {Some Program A
                                 \nodepart{two}     Some Program B
                                 \nodepart{three}   Some Program C
                                 };
\node (DB)  [DB, below=of D]    {C};
%
\draw   (A)     edge ["latex is\\ awesome",
                      "{here is more\\ text;
                       but do such long labels make any sense?}" ' ]   (D)    % <---
        (D)     edge ["latex is\\ awesome"]   (C.one west)
        (A)     edge ["{latex is awesome,
                       latex is awesome}" ']   (DB)
        (DB)    edge ["{latex is awesome,
                        latex is awesome}" '
                      ]   (C.three west)
                   ;
    \end{tikzpicture}
\end{document}

enter image description here

or in this special case when number of label text is evem you can define anchor for it:

\draw   (A)     edge ["{latex is\\ awesome,
                        here is more\\ text;
                        but do such long labels make any sense?}" 
                        anchor=center ]   (D)
...

enter image description here

8
  • Is it possible to apply \scriptsize for all font?
    – alper
    Jun 5 at 14:27
  • @alper You can use every node/.style = {font=\scriptsize}.
    – Unknown
    Jun 5 at 15:10
  • @alper, from your question follows, that all text in image have the same -- normal -- size of fonts. According to my taste I reduce font at edge quotes to \footnotesize. I wouldn't recommend to have all text in \scriptsize , but it is up to you. See addendum to answer.
    – Zarko
    Jun 5 at 16:49
  • @Zarko Thanks for the edit. I was trying to make it fit into double-column; should I re-size it or change the node distance = 22mm and 23mm to make it. PS: sorry for the additional questions
    – alper
    Jun 5 at 19:37
  • Can also text width=6em be wider for the text on the south-east, when I increase it, position of the latex is awesome at top misplaced.
    – alper
    Jun 5 at 19:53
1

OK, here's a quick review of your code to make what we said clear:

labels alignment

pos=0.75means place the node at 75% of the line length.

text width=3cm is pretty obvious and allows you to write on multiple lines.

I deleted the [block] style that you didn't define

Some elements remain to be made, but this was not your main question so I let them like this, maybe you could ask another questino about those specific items (split rectengle on the right, for example).

Feel free to comment and discuss.

\documentclass[tikz]{standalone}
\usetikzlibrary{shapes,positioning}

\begin{document}
    \begin{tikzpicture}[
        shape aspect=1,
        arrow/.style={->, >=stealth, very thick,shorten <=2pt,shorten >=2pt},
        ]
        \node (A) [cylinder, shape border rotate=90, draw,minimum height=2.5cm,minimum width=2cm]{C};
        \node at (140:7) (B) [rectangle, shape border rotate=90, draw,minimum height=1cm,minimum width=3cm]{Some Program} ;
        \node at (40:7) (C) [rectangle, shape border rotate=90, draw,minimum height=2cm,minimum width=3cm]{Some Program A};
        \node at (90:5) (D) [circle, shape border rotate=90, draw,minimum height=1cm,minimum width=1cm]{D};
        
    
        \draw [arrow] (B) -- (A) node[left=3mm, text width=2.7cm,align=center,red,pos=0.75] {latex is awesome, latex is awesome} ;
        
        \draw [arrow] (C) -- (A) node[right=3mm, text width=2.7cm,align=center,blue,pos=0.75] {latex is awesome, latex is awesome} ;
        
        \draw [arrow] (B) -- (D) node[above, text width=1.5cm,align=center,orange,pos=0.35] {latex is awesome} ;
        
        \draw [arrow] (C) -- (D) node[above, text width=1.5cm,align=center,pink,pos=0.35] {latex is awesome} ;
    \end{tikzpicture}
\end{document}

If you want the rectangle split, use this line:

\node at (40:7) (C) [rectangle split,rectangle split parts=3, shape border rotate=90, draw,minimum height=2cm,minimum width=3cm]{Some Program A \nodepart{two} Some Program B \nodepart{three} Some Program C};

rectangle split

3
  • Just on the rectangle right corner, I have to create additional rectangle below like the one figore on my question. For that should I create a new node as rectange below on the existing rectange that exists or inside the rectangle should I draw a horizontal line inside
    – alper
    Jun 5 at 9:54
  • Like I said, it exists an option known as rectangle split that you can use for this. I edited my post.
    – SebGlav
    Jun 5 at 12:45
  • 1
    Thanks for the edit :-) I was trying to create new node but it required many trial-error to find its correct location
    – alper
    Jun 5 at 12:51

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.