在 tikz 中创建具有多个连接环的环形图的最简单方法?

在 tikz 中创建具有多个连接环的环形图的最简单方法?

我想画一个类似附图的图形在此处输入图片描述这是来自 SSN 本体的一个例子。

然而,我发现的最接近的例子是使用自动颜色并且只提供一个环:

% A circular diagram of a TeX workflow
% Author: Stefan Kottwitz
% https://www.packtpub.com/hardware-and-creative/latex-cookbook
\documentclass[border=10pt]{standalone}
\usepackage{smartdiagram}
\begin{document}
\smartdiagram[circular diagram:clockwise]{Edit,
  pdf\LaTeX, Bib\TeX/ biber, make\-index, pdf\LaTeX}
\end{document}

在此处输入图片描述

使用 tikz 创建这种图像的最佳方法是什么?

编辑:谢谢大家!此问题线程中现在有多个运行良好的出色版本。使用 tikz 可以实现的功能非常出色!

答案1

只是为了好玩。我很好奇,是否可以通过 pgfmanual 第 103.4.2 节中的非线性变换获得这些形状\polartransform。答案是肯定的。

  • 节点形状甚至阴影都会发生改变!

  • 甚至定位也有效(除了左右可能失去意义)!

  • 一旦人们理解了从东到西(!)的“线”路径装饰上的文字就可以完成这项工作,那么弯曲文字就出奇地简单。但它不是自动的。

  • 缺点:如果以后想要引用节点的锚点,它们就会失控。我无法弄清楚如何在转换范围之外引用它们。不过,人们可以简单地将给定半径的节点之间的箭头绘制为箭头形节点。已修复@符号 1 在这里

我认为只要有耐心,就可以重新创建您展示的图表。我没有这样做,因为我不喜欢从屏幕截图中输入文本。

更新:为了缓解第二点,我创建了一个为您绘制节点的宏:

\BentNode[<options passed to the node>]{<name>}{<text>}{<options for text decoration>}{<options for the text>}

文本装饰的选项是诸如 之类的东西textcolor=white,而文本的选项是诸如\sffamily或 之类的命令\small。我计划进一步改进这些宏,但我计划在此之前等待一些反馈。

第二次更新:内置了@cfr 这里@符号 1 在这里

\documentclass[tikz,border=3.14mm]{standalone}
\usetikzlibrary{positioning,decorations.text,calc,shapes.arrows,shadows.blur}
\usepgfmodule{nonlineartransformations}
\newlength{\mywidth}

\makeatletter
% from https://tex.stackexchange.com/a/434247/121799
\tikzdeclarecoordinatesystem{polar}{
    \tikz@scan@one@point\relax(#1)
    \polartransformation
}
% from the pgfmanual
\def\polartransformation{% from the pgfmanual section 103.4.2
\pgfmathsincos@{\pgf@sys@tonumber\pgf@x}%
\pgf@x=\pgfmathresultx\pgf@y% 
\pgf@y=\pgfmathresulty\pgf@y%
} % note: the following should work with arbitrary (nonlinear) transformations
\makeatother
%from https://tex.stackexchange.com/a/433461/121799
\newsavebox\untransformedtip
\sbox\untransformedtip{\tikz{\draw [thick,-latex] (0,0) -- (0,1);}}
\begin{document}
\tikzset{rednode/.style={draw,blur shadow,fill=red!50!black,align=center,
font=\sffamily,text opacity=0},
bluenode/.style={draw,blur shadow,fill=blue!10,align=center,
font=\sffamily,text opacity=0}
}
\newcommand{\BentNode}[5][]{% see https://tex.stackexchange.com/a/56405/121799
\coordinate[#1,draw=none,opacity=0](dummy){};
\path let \p1=(dummy.center) in 
\pgfextra{\settowidth{\mywidth}{\pgfinterruptpicture #5 #3\endpgfinterruptpicture}}
node[#1,minimum width={\mywidth*(2.06*28.4/\y1}](#2){};
\fill[decoration={text along path, text={|#5| #3},
  raise=-2.5pt,#4},decorate] (#2.east) -- (#2.west);
}
\begin{tikzpicture}[scale=1,font=\sffamily]
\node[circle,draw,fill=red!50!black,align=center,drop shadow,text=white,inner
sep=1pt,font=\small\sffamily] (sensor)
{Sensor,\\ Observation,\\ Sample, and\\ Actuator\\ (SOSA)};
\begin{scope}[transform shape nonlinear=true]
\pgftransformnonlinear{\polartransformation}
% within the scope, think of the first coordinate as angle in radians rescaled 
% by the radius, i.e. an arc length, and the second as radius
% positioning is rather convenient except that "left" and "right" lose their meaning
\BentNode[rednode,minimum height=12pt,at={(3.15,2.5)}]{semantic}{%
Semantic sensor network}{text color=white}{\sffamily}
\BentNode[rednode,minimum height=12pt,left=0.3cm of semantic]{system}{%
System Capabilities}{text color=white}{\sffamily}
\BentNode[bluenode,minimum height=12pt,right=0.3cm of semantic]{sample}{%
Sample relations}{text color=black}{\sffamily}
\draw[thick,-latex] (semantic) -- (system);
\draw[thick,-latex] (semantic) -- (sample);
%
\BentNode[bluenode,minimum height=11pt,at={(9.35,3.5)}]{PROV}{%
PROV alignment module}{text color=black}{\sffamily\small} %note: special characters need to be placed in curly brackets
\BentNode[rednode,minimum height=11pt,left=0.3cm of PROV]{OM}{%
O {\&} M alignment module}{text color=white}{\sffamily\small} %note: special characters need to be placed in curly brackets
\BentNode[bluenode,minimum height=11pt,right=0.3cm of PROV]{OBOE}{%
OBOE alignment module}{text color=black}{\sffamily\small} 
\end{scope}
% this is the unfortunate part: I do not know how to properly refer to the nodes
% if I do it within the above scope, the arrow heads get messed up, if I do it
% outside, the coordinates get messed up, so I draw the arrows by hand
\draw[thick,-latex] (polar cs:semantic.south) -- (sensor);
\draw[thick,-latex] (polar cs:PROV.south) -- (sensor);
\draw[thick,-latex] (polar cs:OM.-20) -- (sensor);
\draw[thick,-latex] (polar cs:OBOE.-160) -- (sensor);
\end{tikzpicture}
\end{document}

在此处输入图片描述

答案2

这里有一个使用名为“strip”的多参数pic来定义圆形节点的方法(请参阅 tikz 手册第 18.2 节;版本 3.0.1a)。这些节点使用以下命令放置:

\pic at (0,0){strip={raduis, start angle, end angle, draw style, 
                     text colour, text}};

例如,

\pic at (0,0){strip={25mm, 16,-57,redshell, white, System Capabilities}};

要使用这个,你需要明确地计算出合适的角度,但我认为对于这样的图表来说,这可能是不可避免的。最终结果是你可以生成这样的图表:

在此处输入图片描述

使用如下代码:

\documentclass[svgnames]{article}
\usepackage{xcolor}
\usepackage{tikz}
\usetikzlibrary{decorations.text, arrows.meta}

\tikzset{
  myarrow/.style={thick, -latex},
  redshell/.style={draw=Maroon,fill=red!50!black},
  redcircle/.style={redshell,circle, align=center, font=\small\sffamily,
                    text=white, inner sep=1pt},
  blueshell/.style={draw=CornflowerBlue,fill=LightSteelBlue},
  % #1=radius, #2=start angle, #3=end angle, #4=draw style,
  % #5 text colour, #6=text
  pics/strip/.style args = {#1,#2,#3,#4,#5,#6}{
       code = {
        \draw[#4] (#2:#1-3mm) arc (#2:#3:#1-3mm)
             -- (#3:#1) -- (#3:#1+3mm) arc (#3:#2:#1+3mm)
             -- (#2:#1) -- cycle;
        \path[font=\small\sffamily,
              decoration={text along path, text color=#5, text = {#6},
                          text align = {align = center}, raise = -0.5ex},
              decorate] (#2:#1) arc (#2:#3:#1);
       }
  }
}

\begin{document}

  \begin{tikzpicture}
    \node[redcircle](SOSA) at (0,0) {Sensor,\\Observation,\\Sample, and\\Actuator\\(SOSA)};
    \draw[myarrow] (156:42mm) -- (156:28mm);
    \draw[myarrow] (120:42mm) -- (120:28mm);
    \draw[myarrow] (120:22mm) -- (SOSA);
    \draw[myarrow] (219:32mm) -- (SOSA);
    \draw[myarrow] (260:32mm) -- (SOSA);
    \draw[myarrow] (301:32mm) -- (SOSA);
    \draw[myarrow] (145:45mm) arc [start angle=145, end angle=150, radius=45mm];
    \draw[myarrow] (142:25mm) arc [start angle=142, end angle=152, radius=25mm];
    \draw[myarrow]  (16:25mm) arc [start angle=16, end angle=24, radius=25mm];
    \pic at (0,0){strip={25mm, 16,-57,redshell, white,System Capabilities}};
    \pic at (0,0){strip={25mm,142, 24,redshell, white,Semantic Sensor Network (SSN)}};
    \pic at (0,0){strip={25mm,217,152,blueshell,black,Sample Relations}};
    \pic at (0,0){strip={35mm,224,159,redshell, white,O{\&}M Alignment module}};
    \pic at (0,0){strip={35mm,295,228,blueshell,black,PROV Alignment module}};
    \pic at (0,0){strip={35mm,370,299,blueshell,black,OBOE Alignment module}};
    \pic at (0,0){strip={45mm,145, 90,blueshell,black,SSNX Alignment module}};
    \pic at (0,0){strip={45mm,220,150,blueshell,black,Docle-UltraLite Alignment module}};
  \end{tikzpicture}

\end{document}

答案3

只是为了运动,因为我来晚了,并且带着来自优秀和强大的示例的盗版代码,只有通过创建参数对象将其改变为我的方式 python 类型,并构造代码以使其可读,我希望这对另一个盗版者有用 xD。

结果: 在此处输入图片描述

梅威瑟:

\documentclass[border=5pt]{standalone}
\usepackage{xcolor}
\definecolor{ocre}{HTML}{800000}
\definecolor{sky}{HTML}{C6D9F1}
\definecolor{skybox}{HTML}{5F86B3}
\usepackage{tikz}
\usepackage{pgfmath}
\usetikzlibrary{decorations.text, arrows.meta,calc,shadows.blur,shadings}
\renewcommand*\familydefault{\sfdefault} % Set font to serif family

% arctext from Andrew code with modifications:
%Variables: 1: ID, 2:Style 3:box height 4: Radious 5:start-angl 6:end-angl 7:text {format along path} 
\def\arctext[#1][#2][#3](#4)(#5)(#6)#7{

\draw[#2] (#5:#4cm+#3) coordinate (above #1) arc (#5:#6:#4cm+#3)
             -- (#6:#4) coordinate (right #1) -- (#6:#4cm-#3) coordinate (below right #1) arc (#6:#5:#4cm-#3) coordinate (below #1)
             -- (#5:#4) coordinate (left #1) -- cycle;
            \def\a#1{#4cm+#3}
            \def\b#1{#4cm-#3}
\path[
    decoration={
        raise = -0.5ex, % Controls relavite text height position.
        text  along path,
        text = {#7},
        text align = center,        
    },
    decorate
    ]
    (#5:#4) arc (#5:#6:#4);
}

%arcarrow, this is mine, for beerware purpose...
%Function: Draw an arrow from arctex coordinate specific nodes to another 
%Arrow start at the start of arctext box and could be shifted to change the position
%to avoid go over another box.
%Var: 1:Start coordinate 2:End coordinate 3:angle to shift from acrtext box  
\def\arcarrow(#1)(#2)[#3]{
    \draw[thick,->,>=latex] 
        let \p1 = (#1), \p2 = (#2), % To access cartesian coordinates x, and y.
            \n1 = {veclen(\x1,\y1)}, % Distance from the origin
            \n2 = {veclen(\x2,\y2)}, % Distance from the origin
            \n3 = {atan2(\y1,\x1)} % Angle where acrtext starts.
        in (\n3-#3: \n1) -- (\n3-#3: \n2); % Draw the arrow.
}

\begin{document}
    \begin{tikzpicture}[
        % Environment Cfg
        font=\sf    \scriptsize,
        % Styles
        myarrow/.style={
            thick,
            -latex,
        },
        Center/.style ={
            circle,
            fill=ocre,
            text=white,
            align=center,
            font =\footnotesize\bf,
            inner sep=1pt,          
        },
        RedArc/.style ={
            color=black,
            thick,
            fill=ocre,
            blur shadow, %Tikzedt not suport online view
        },
        SkyArc/.style ={
            color=skybox,
            thick,
            fill=sky,
            blur shadow, %Tikzedt not suport online view
        },
    ]

    % Drawing the center
    \node[Center](SOSA) at (0,0) { Sensor \\ Observation, \\ Sample, and \\ Actuator \\(SOSA)};
    \coordinate (SOSA-R) at (0:1.2); % To make compatible with \arcarrow macro.

    % Drawing the Tex Arcs

    % \Arctext[ID][box-style][box-height](radious)(start-angl)(end-angl){|text-styles| Text}

    \arctext[SSN][RedArc][8pt](2.25)(180)(60){|\footnotesize\bf\color{white}| Semantic Sensor Network (SSN)};
    \arctext[SCap][RedArc][8pt](2.25)(50)(-20){|\footnotesize\bf\color{white}| System Capabilities};
    \arctext[SRel][SkyArc][8pt](2.25)(190)(255){|\footnotesize\color{black}| System Relation};
    \arctext[OMAM][RedArc][5pt](3.5)(205)(265){|\scriptsize\bf\color{white}| O{\&}M Alignment Module};
    \arctext[PROV][SkyArc][5pt](3.5)(270)(320){|\scriptsize| PROV Alignment Module};
    \arctext[OBOE][SkyArc][5pt](3.5)(-35)(20){|\scriptsize| OBOE Alignment Module};
    \arctext[DUAM][SkyArc][5pt](4.5)(215)(150){|\scriptsize| Dolce-UltraLite Alingment Module};
    \arctext[SSNX][SkyArc][5pt](4.5)(145)(80){|\scriptsize| SSNX Alingment Module};

    %ADITIONAL
    \arctext[NEW][
        color=white,
        shade,      
        upper left=red,
        upper right=black!50,
        lower left=blue,
        lower right=blue!50,
        rounded corners = 8pt
        ][8pt](5.2)(100)(-20){|\footnotesize\bf\color{white}| You can create and use all the style options for shapes and text};

    %Drawing the Arrows
    %\arcarrow(above/below ID)(abobe/below ID)[shift]
    \arcarrow(below DUAM)(above SRel)[15];
    \arcarrow(below SSNX)(above SSN)[35];
    \arcarrow(below SSN)(SOSA-R)[60];
    \arcarrow(below right OMAM)(SOSA-R)[4];
    \arcarrow(below right PROV)(SOSA-R)[25];
    \arcarrow(below OBOE)(SOSA-R)[-5];

    %Same level Arrows
    \draw[myarrow] (left SSNX) -- (right DUAM);
    \draw[myarrow] (left SSN) -- (left SRel);
    \draw[myarrow] (left SCap) -- (right SSN);

     \draw[myarrow] (-5,-3.5) coordinate (legend) -- ++(.8,0) node[anchor=west] {owl: imports (extends)};
     \draw[RedArc] (legend)++(0,-0.4) rectangle ++(.8,-.3)++(0,.2) node[anchor=west] {normative};
     \draw[SkyArc] (legend)++(0,-1) rectangle ++(.8,-.3)++(0,.2) node[anchor=west, color=black] {non-normative};

    \end{tikzpicture}

\end{document}

答案4

轮图我写的包,可以使用。

弧线中的文本被赋予键。此文本的方向取决于键中使用的arc data弧线中间的角度。此文本以 为弧线的中心。\WCmidanglearc data dirarc data pos=0.5

弧之间的间隙是通过键gap polar=5和获得的gap radius=0.25

切片的键filldraw在键中设置slices style。这些定义好像none切片的第三个变量(由给出\WCvarC)为空。

在此处输入图片描述

\documentclass[border=6pt,svgnames]{standalone}
\usepackage{etoolbox}
\usepackage{listofitems}
\readlist\WCcolorsdraw{Maroon,CornflowerBlue}
\readlist\WCcolorsfill{red!50!black,LightSteelBlue}
\readlist\WCcolorstext{white,black}
\usepackage{wheelchart}
\usetikzlibrary{decorations.text}
\begin{document}
\begin{tikzpicture}
\sffamily
\fill[{\WCcolorsfill[1]}] (0,0) circle[radius=1.5]
  node[
    {\WCcolorstext[1]},
    align=center
  ] {%
    Sensor,\\
    Observation,\\
    Sample, and\\
    Actuator\\
    (SOSA)%
  };
\pgfkeys{
  /wheelchart,
  arc data=\WCvarC,
  arc data dir={\WCmidangle<180?-1:1},
  arc data pos=0.5,
  arc data style={text color=\WCcolorstext[\WCvarB]},
  counterclockwise,
  data=,
  gap polar=5,
  gap radius=0.25,
  slices style={
    /utils/exec={
      \ifdefempty{\WCvarC}{\def\WCfill{none}\def\WCdraw{none}}{\edef\WCfill{\WCcolorsfill[\WCvarB]}\edef\WCdraw{\WCcolorsdraw[\WCvarB]}}
    },
    fill=\WCfill,
    draw=\WCdraw
  }
}
\wheelchart[
  radius={1.5}{3},
  start angle=-30
]{%
  90/1/System Capabilities,
  140/1/Semantic Sensor Network (SSN),
  80/2/Sample Relations,
  50/1/%
}
\wheelchart[
  radius={3}{4.5},
  start angle=190
]{%
  70/1/O{\&}M Alignment Module,
  70/2/PROV Alignment Module,
  70/2/OBOE Alignment Module,
  150/1/%
}
\wheelchart[
  radius={4.5}{6},
  start angle=70
]{%
  80/2/SSNX Alignment Module,
  80/2/Dolce-UltraLite Alignment Module,
  200/1/%
}
\end{tikzpicture}
\end{document}

相关内容