流程图(Tikz)中的梯形宽度不相等,如何使它们大小相同?

流程图(Tikz)中的梯形宽度不相等,如何使它们大小相同?
\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}

我在使数据节点统一方面遇到了问题。手动调整宽度(在\node命令中)没有帮助,我无法使它们的宽度大致相同。不手动调整它们也没有得到好的结果。

在此处输入图片描述

答案1

这个trapezium fixed angles形状基本上就像rectangle在两侧简单添加三角形的形状。

这意味着最小宽度不包括这些三角形。在下面的示例中,这由灰色矩形表示(通过图例label中的a data)。

无论文本大小、最小宽度或最小高度如何,此形状的节点都应始终具有指定的角度。

可以调整此形状,以便在考虑时包含三角形,minimum width但我尚未实现这一点。您可以手动减去minimum height/tan(60°),minimum width但在您的示例中,文本太宽了。(并且在某些时候,很多宽度将来自三角形,具体取决于角度。)

该形状不支持shape border rotate。新形状的代码的两部分取自原始形状的定义

代码

\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}

输出

在此处输入图片描述

答案2

以下是一种方法:

  • 用“美丽”法则来对待一切总是好的(日式风格:清理)
  • minimum height密钥 1:所有节点都相同
  • 关键 2:过度指定text width
  • 关键3:trapezium stretches=true
  • 关键 4:在适当的情况下使用数学模式
  • 关键 5:align=centertext with\\backslashes
  • 总结成几句.style
  • 建议对形状边框进行一些对比(在contr

外表:

  • 将常用样式移至新样式(contrminimum height),就像我所做的那样contr (参考:红色、绿色、重构方法)

附言:节点(surveyData)在代码中的位置很特殊。在我调整梯形之前,节点比较小,这是一个让它对齐的“技巧”。

结果

% 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}

写一条评论:改变角度时,两个梯形完全相同,而带有两条文本线的梯形却带来了惊喜:

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

结果2

避免第二行导致 3 个相同的梯形,保持所有其他代码原样:

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

结果 3

建议

  • 让梯形变得更宽
  • 或者让你的节点文本更短

魔法:你也可以用这种方法施展魔法:

  • 画一个几乎空的文本的梯形
  • 在同一位置绘制第二个节点,并添加两行文本
  • 这样你就可以(几乎)摆脱重塑相关的问题

为了实现这一点,不幸的是梯形需要一些文本:一个a可以工作,一个.会再次改变形状,short似乎可以工作,一个blank不行,一个\strut不是更好。所以最后用相同的颜色写文本会隐藏它;你甚至可以从最终的pdf中选择并复制,从而只得到两行文本。

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

魔法

答案3

另一个可能的解决方案是使用chains库及其宏join,重新定义节点的样式,以便data节点的形状与文本行数无关。 由此产生的 MWE 具有更短的流程图代码:

\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}

在此处输入图片描述

相关内容