然而,我发现的最接近的例子是使用自动颜色并且只提供一个环:
% 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
。我计划进一步改进这些宏,但我计划在此之前等待一些反馈。
\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
弧线中间的角度。此文本以 为弧线的中心。\WCmidangle
arc data dir
arc data pos=0.5
弧之间的间隙是通过键gap polar=5
和获得的gap radius=0.25
。
切片的键fill
和draw
在键中设置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}