1
\documentclass{standalone}
\usepackage[x11names]{xcolor}

\usepackage{tikz}
\usetikzlibrary{shapes, arrows.meta, positioning}

\begin{document}

\tikzstyle{terminator} = [rectangle, fill=SkyBlue1, text centered, rounded corners, minimum height = 1.5cm, text width = 3cm]
\tikzstyle{process} = [rectangle, fill=SkyBlue1, text centered, minimum height = 1.5cm, text width = 3cm]
\tikzstyle{decision} = [diamond, fill=SkyBlue1, text centered, minimum height = 1.5cm, text width = 3cm]
\tikzstyle{data} = [
    trapezium, 
    fill=SkyBlue1, 
    text centered, 
    trapezium left angle=60, 
    trapezium right angle=120, 
    minimum height = 1.5cm, 
    text width = 3cm, 
    minimum width = 3cm,
    inner sep=0pt, % Separation between textbox and shape box horizontal and vertical.
    inner xsep=5pt, % horizontal seperation
    inner ysep=5pt, % vertical separation
    %trapezium stretches=true
]
\tikzstyle{connector} = [draw, -latex]


\begin{tikzpicture}[node distance = 2cm]
    \node [terminator] (start) {start};
    \node [process, below of=start] (history) {literature};
    \node [data, right of=history, node distance = 5cm] (model1) {model 1};
    \path [connector] (start) -- (history);
    \path [connector] (history) -- (model1);

    \node [process, below of=history] (survey) {survey};
    \node [data, left of=survey, node distance = 5cm, text width=1.5cm] (surveyData) {\(N=\) 88};
    \path [connector] (surveyData) -- (survey);
    \path [connector] (history) -- (survey);

    \node [process, below of=survey] (stat) {statistics};
    \node [data, left of=stat, node distance = 5cm] (PDdata) {another database (\(N=\) 900)};
    \path [connector] (PDdata) -- (stat);
    \path [connector] (survey) -- (stat);
\end{tikzpicture}
 
\end{document}

I am having issues making the data nodes uniform. Adjusting the width manually (in the \node command) doesn't help, I cannot make them even roughly the same width. Not adjusting them manually has also not given good results.

enter image description here

2

3 Answers 3

1

Here's a trapezium fixed angles shape that is basically like the rectangle shape that simply adds triangles at both sides.

This means that the minimum width does not include these triangles. In the example below, this is indicated by the gray rectangles (via a label in the data key).

Nodes of this shape should always have the specified angles, irregardless of text size, minimum width or minimum height.

This shape could be adjusted so that it includes the triangles when considering the minimum width but I haven't implented this. You could manually subtract minimum height/tan(60°) from minimum width but in your example the text is too wide. (And at some point a lot of the width would come from the triangles depending on the angles.)

The shape does not support shape border rotate. A bis portion of the code for the new shape is taken from the original shape's definition

Code

\documentclass{standalone}
\usepackage[x11names]{xcolor}
\usepackage{tikz}
\usetikzlibrary{shapes.geometric, arrows.meta, graphs, chains}
\makeatletter
\pgfset{
  trapezium utils/extract points/.code n args={6}{%
    \expandafter\pgfextract@process\csname #1#2point\endcsname{%
      \centerpoint
      \advance\pgf@x#6\halfwidth\relax
      \ifdim\csname #2extension\endcsname#30pt\relax
        \advance\pgf@x#4\csname #2extension\endcsname\relax
      \fi
      \advance\pgf@y#5\halfheight\relax}},
  trapezium utils/extract miters/.code n args={5}{%
    \expandafter\pgfextract@process\csname #1borderpoint\endcsname{%
      \pgfpointadd{\csname #1point\endcsname}{%
        \pgfmathanglebetweenlines{\csname #1point\endcsname}{\csname #2point\endcsname}{\csname #1point\endcsname}{\csname #3point\endcsname}%
        \pgfmathmultiply@{\pgfmathresult}{.5}%
        \pgfmathtan@{\pgfmathresult}%
        \pgfmathreciprocal@{\pgfmathresult}%
        \pgf@x#4\outersep\relax
        \pgf@x\pgfmathresult\pgf@x
        \pgf@y#5\outersep\relax}}%
    \pgfmathanglebetweenpoints{\centerpoint}{\csname #1borderpoint\endcsname}%
    \expandafter\let\csname angleto#1\endcsname\pgfmathresult%
    \pgfmathanglebetweenpoints{\rotatedbasepoint}{\csname #1borderpoint\endcsname}%
    \expandafter\let\csname baseangleto#1\endcsname\pgfmathresult
    \pgfmathanglebetweenpoints{\rotatedmidpoint}{\csname #1borderpoint\endcsname}%
    \expandafter\let\csname midangleto#1\endcsname\pgfmathresult
    \expandafter\addtosavedmacro\csname #1point\endcsname
    \expandafter\addtosavedmacro\csname #1borderpoint\endcsname
    \expandafter\addtosavedmacro\csname angleto#1\endcsname
    \expandafter\addtosavedmacro\csname baseangleto#1\endcsname
    \expandafter\addtosavedmacro\csname midangleto#1\endcsname}}%
\pgfdeclareshape{trapezium fixed angles}{%
  \savedmacro\installtrapeziumparameters{%
    \def\rotate{0}% no support for shape border rotation
    \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/inner xsep}}%
    \advance\[email protected]\wd\pgfnodeparttextbox
    \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/inner ysep}}%
    \advance\[email protected]\ht\pgfnodeparttextbox
    \advance\[email protected]\dp\pgfnodeparttextbox
    %
    \pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/minimum height}}%
    \ifdim\pgf@y<.5\pgf@ya\pgf@y=.5\pgf@ya\fi
    \pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/minimum width}}%
    \ifdim\pgf@x<.5\pgf@xa\pgf@x=.5\pgf@xa\fi
    %
    \pgfmathmod{\pgfkeysvalueof{/pgf/trapezium left angle}}{360}%
    \ifdim\pgfmathresult pt<0pt\relax\pgfmathadd@{\pgfmathresult}{360}\fi
    \let\leftangle\pgfmathresult
    \ifdim\leftangle pt=0pt\relax
      \def\pgfmathresult{0}\else
      \pgfmathcot@{\leftangle}\fi
    \pgf@xa=2\pgf@y \pgf@xa=\pgfmathresult\pgf@xa
    \edef\leftextension{\the\pgf@xa}%
    %
    \pgfmathmod{\pgfkeysvalueof{/pgf/trapezium right angle}}{360}%
    \ifdim\pgfmathresult pt<0pt\relax\pgfmathadd@{\pgfmathresult}{360}\fi
    \let\rightangle\pgfmathresult
    \ifdim\rightangle pt=0pt\relax
      \def\pgfmathresult{0}\else
      \pgfmathcot@{\rightangle}\fi
    \pgf@xa=2\pgf@y \pgf@xa=\pgfmathresult\pgf@xa
    \edef\rightextension{\the\pgf@xa}%
    %
    \edef\halfwidth{\the\pgf@x}\edef\halfheight{\the\pgf@y}%
    %
    \pgfmathsetlength\pgf@x{\pgfkeysvalueof{/pgf/outer xsep}}%
    \pgfmathsetlength\pgf@y{\pgfkeysvalueof{/pgf/outer ysep}}%
    \ifdim\pgf@y>\pgf@x\pgf@x=\pgf@y\fi
    \edef\outersep{\the\pgf@x}%
    %
    \advance\pgf@xc2\pgf@x
    \pgf@yc\halfheight\relax
    \multiply\pgf@yc2\relax
    \advance\pgf@yc2\pgf@x
    \edef\externalradius{\ifdim\pgf@xc<\pgf@yc\the\pgf@yc\else\the\pgf@xc\fi}%
    %
    \pgfextract@process\centerpoint{%
      \[email protected]\wd\pgfnodeparttextbox
      \[email protected]\ht\pgfnodeparttextbox
      \advance\[email protected]\dp\pgfnodeparttextbox}%
    \pgfextract@process\basepoint{%
      \[email protected]\wd\pgfnodeparttextbox
      \pgf@y0pt\relax}%
    \pgfextract@process\midpoint{%
      \[email protected]\wd\pgfnodeparttextbox
      \pgfmathsetlength\pgf@y{+.5ex}}%
    %
    \let\rotatedbasepoint\basepoint
    \let\rotatedmidpoint\midpoint
    \pgfkeysgetvalue{/pgf/trapezium utils/extract points/.@cmd}\pgfkeys@temp
    \pgfutil@for\pgf@temp:={lower}{left}>---,{upper}{left}<{}{}-,%
                           {upper}{right}<-{}{}, {lower}{right}>{}-{}\do{%
      \expandafter\pgfkeys@temp\pgf@temp\pgfeov}%
    \pgfkeysgetvalue{/pgf/trapezium utils/extract miters/.@cmd}\pgfkeys@temp
    \pgfutil@for\pgf@temp:={lowerleft}{lowerright}{upperleft}--,%
      {upperleft}{lowerleft}{upperright}-{},%
      {upperright}{upperleft}{lowerright}{}{},%
      {lowerright}{upperright}{lowerleft}{}-\do{%
      \expandafter\pgfkeys@temp\pgf@temp\pgfeov}%
    \addtosavedmacro\rotate
    \addtosavedmacro\externalradius
  }%
  \savedanchor\centerpoint{%
      \[email protected]\wd\pgfnodeparttextbox
      \[email protected]\ht\pgfnodeparttextbox
      \advance\[email protected]\dp\pgfnodeparttextbox}%
  \savedanchor\basepoint{%
      \[email protected]\wd\pgfnodeparttextbox
      \pgf@y0pt\relax}%
  \savedanchor\midpoint{%
      \[email protected]\wd\pgfnodeparttextbox
      \pgfmathsetlength\pgf@y{+.5ex}}%
  \pgfutil@for\pgf@temp:=center,base,base east,base west,mid,mid east,mid west,%
    north,south,east,west,north east,south west,south east,north west,%
    bottom left corner,top left corner,top right corner, bottom right corner,%
    left side,ride side,top side,bottom side\do{%
    \inheritanchor[from=trapezium]{\pgf@temp}%
  }%
  \inheritanchorborder[from=trapezium]%
  \inheritbackgroundpath[from=trapezium]%
}
\makeatother
\begin{document}
\begin{tikzpicture}[
  node distance = 1cm,
  connector/.style={draw, -Latex},
  common/.style    ={
    fill = SkyBlue1, align = center, minimum height = 1.5cm, minimum width = 3cm},
  terminator/.style={process, rounded corners},
  process/.style   ={rectangle, common},
  data/.style      ={
    label={[label/.code=,data,rectangle,path only,draw,help lines]center:},%
    trapezium fixed angles, common,
    trapezium left angle=60, trapezium right angle=120},
  %
  start chain=going below,
]
\graph[no placement, edges = connector]{
  {[nodes={on chain, process}]
    start[terminator] -> literatur -> survey -> statistics
  },
  {[nodes=data]
    literatur -> model 1      [right=of literatur],
    survey    -> N88/$N = 88$ [left=of survey],
    statistics -> N900/another database\\$N = 900$ [left=of statistics]
  }
};
\end{tikzpicture}
\end{document}

Output

enter image description here

1

Here's a way to do it:

  • it's always a good idea to approach "beauty"-code (Japanese style: clean-up)
  • key 1: have the same minimum height for all nodes
  • key 2: overspecify text width
  • key 3: trapezium stretches=true
  • key 4: used math mode where appropriate
  • key 5: align=center and text with\\backslashes
  • summarized into a few .style statements
  • suggested some contrast for the shapes borders (in contr)

Outlook:

  • move common styles into a new one (contr, minimum height), like I did with contr (for reference: RED, GREEN, REFACTOR approach)

P.S.: node (surveyData) has a peculiar position within the code. Before I adjusted for the trapezium the node was smaller, and this was a "trick" to get it into an aligned placement.

result

% https://tex.stackexchange.com/questions/684240/trapezia-in-process-flow-chart-tikz-are-not-equal-in-width-how-do-i-make-them

\documentclass[10pt,border=3mm]{standalone}% <<<---
\usepackage[x11names]{xcolor}

\usepackage{tikz}
\usetikzlibrary{shapes.geometric, arrows.meta, positioning}% <<<---

\begin{document}


\begin{tikzpicture}
    [
    % ~~~ just for contrast settings ~~~~~~~~~~~~
    contr/.style={fill=SkyBlue1,draw=SkyBlue1!70!black},
    % ~~~ contrast, same heights, etc. ~~~~~~~~~~~~~~~~~~~~
    term/.style={contr,align=center,text width=2cm,minimum height=1.0cm,rounded corners=7pt},
    proc/.style={contr,align=center,text width=2cm,minimum height=1.0cm},
    data/.style={contr,align=center,text width=4cm,minimum height=1.0cm,
                 trapezium,trapezium left angle=80,trapezium right angle=100,
                 trapezium stretches=true
                 },
    conn/.style={draw=black,-{Stealth}}
    ]
%   \draw [help lines] (-5,-7) grid (5,0);% uncomment for a help-grid
    % ~~~ nodes ~~~~~~~~~~~~~~~~~~~~~
    \node [term]                    (start)         {start};
    \node [proc,below=of start]     (history)       {literature};
    \node [data,right=of history]   (model)         {model 1};

    \node [proc,below=of history]   (survey)        {survey};
    
    \node [proc,below=of survey]    (stat)          {statistics};
    \node [data,left=of stat]       (PDdata)        {another database\\($N=900$)};
    \node [data,above=of PDdata]    (surveyData)    {$N = 88$};
    
    % ~~~ connectors ~~~~~~~~~~~~~~~~~~~~
    \draw [conn] (start)        -- (history);
    \draw [conn] (history)      -- (survey);
    \draw [conn] (survey)       -- (stat);
    
    \draw [conn] (model)        -- (history);
    \draw [conn] (surveyData)   -- (survey);
    \draw [conn] (PDdata)       -- (stat);
    
\end{tikzpicture}
 
\end{document}

W.r.t. a comment: When changing the angles two trapezia are identical, while the one with the two text lines provides a surprise:

    data/.style={contr,align=center,text width=4cm,minimum height=1.0cm,
                 trapezium,trapezium left angle=30,trapezium right angle=120,
                 trapezium stretches=true
                 },

result2

Avoiding the second line results in 3 identical trapezia, keeping all other code as-is:

    \node [data,left=of stat]       (PDdata)        {another database};%\\($N=900$)};

result 3

Suggestions:

  • make the trapezia even wider
  • OR make your node-text shorter

Magic: You can also do some magic this way:

  • draw a trapezium with (almost) empty text
  • draw a second node at the same position with two lines of text
  • this way you get (almost) rid of reshaping related problems

To make this work, unfortunately the trapezium needs some text: an a will work, a . will change the shape again, short seems to work, a blank doesn't, a \strut isn't better. So finally writing the text in the same color hides it; you can even select and copy from the final pdf resulting in the two-lines of text only.

    ...
    % ~~~ some magic ~~~~~~~~~~~~~~~~~
    \node [data, right=of stat,text=SkyBlue1]       (magic)  (M) {short};
    \node [align=center] at (M) {another database\\($N=900$)};
    
\end{tikzpicture}

magic

3
  • Thank you, and I agree with everyone that this is not an ideal shape. Your example doesn't have uniform trapezium-angles, even though you did specify them. Commenting out trapezium stretches=true uniforms the angles, but brings back the original width issue.
    – BlueIris
    Commented Apr 29, 2023 at 14:06
  • Fine. // No problem: do better ;-) // Kindly see my update ...
    – MS-SPO
    Commented Apr 29, 2023 at 14:50
  • 1
    Maybe just \phantom{short} (or setting text width/text depth/text height to some chosen values) instead of text in the same color (text opacity is also an option but that will still leave the text copyable in the document). Commented Apr 29, 2023 at 20:18
0

Another possible solution with use chains library and its macro join, with redefining of nodes' styles so that shapes for data node are independent from number of text lines. Resulting MWE has shorter code for flowchart image:

\documentclass[10pt,border=3mm]{standalone}% <<<---
\usepackage[x11names]{xcolor}

\usepackage{tikz}
\usetikzlibrary{arrows.meta,
                chains,
                positioning,
                shapes.geometric}% <<<---

\begin{document}
    \begin{tikzpicture}[
node distance = 6mm and 12mm,
  start chain = A going below,
   arr/.style = {draw=black,-Stealth},
  base/.style = {draw=SkyBlue1!70!black, fill=SkyBlue1,
                 minimum height=3em, minimum width=#1,
                 align=flush center},
  term/.style = {base=22mm, rounded corners=7pt},
  proc/.style = {base=22mm},
  data/.style = {trapezium, trapezium stretches body,
                 trapezium left angle=60,trapezium right angle=120,
                 base=34mm,
                 label=center:#1},
every label/.append style = {align=center}
                        ]
% nodes
    \begin{scope}[nodes = {on chain=A, join=by arr}]
\node [term]    {start};        % A-1
\node [proc]    {literature};
\node [proc]    {survey};
\node [proc]    {statistics};   % A-4
    \end{scope}
\node [data=model 1, right=of A-2]  (model)         {};
\node [data=${N=88}$,left =of A-3]  (surveyData)    {};
\node [data={another database\\ ${N=900}$},left =of A-4]  (PDdata)        {};
% connections 
\draw[arr] (model)      -- (A-2);
\draw[arr] (surveyData) -- (A-3);
\draw[arr] (PDdata)     -- (A-4);
    \end{tikzpicture}
\end{document}

enter image description here

You must log in to answer this question.

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