我正在尝试实现博尔代戈尔的回答创建百分比较小的饼图。但是,使用 MWE 时,百分比会重叠,需要手动调整。
但是,我对 pos 的控制程度只有一个,我只能调整径向距离。pos{} 命令是否有更多控制来水平移动它。此外,是否可以添加图钉,以便我知道哪个百分比代表哪个切片?
平均能量损失
\documentclass[border=10pt,multi,tikz]{standalone}
\usetikzlibrary{patterns}
\definecolor{rosso}{RGB}{220,57,18}
\definecolor{giallo}{RGB}{255,153,0}
\definecolor{blu}{RGB}{102,140,217}
\definecolor{verde}{RGB}{16,150,24}
\definecolor{viola}{RGB}{153,0,153}
\makeatletter
\tikzstyle{chart}=[
legend label/.style={font={\scriptsize},anchor=west,align=left},
legend box/.style={rectangle, draw, minimum size=5pt},
axis/.style={black,semithick,->},
axis label/.style={anchor=east,font={\tiny}},
]
\tikzstyle{bar chart}=[
chart,
bar width/.code={
\pgfmathparse{##1/2}
\global\let\bar@w\pgfmathresult
},
bar/.style={very thick, draw=white},
bar label/.style={font={\bf\small},anchor=north},
bar value/.style={font={\footnotesize}},
bar width=.75,
]
\tikzstyle{pie chart}=[
chart,
slice/.style={line cap=round, line join=round, very thick,draw=white},
pie title/.style={font={\bf}},
slice type/.style 2 args={
##1/.style={fill=##2},
values of ##1/.style={}
}
]
\pgfdeclarelayer{background}
\pgfdeclarelayer{foreground}
\pgfsetlayers{background,main,foreground}
\newcommand{\pie}[3][]{
\begin{scope}[#1]
\pgfmathsetmacro{\curA}{90}
\pgfmathsetmacro{\r}{1}
\def\c{(0,0)}
\node[pie title] at (90:1.3) {#2};
\foreach \v/\s in{#3}{
\pgfmathsetmacro{\deltaA}{\v/100*360}
\pgfmathsetmacro{\nextA}{\curA + \deltaA}
\pgfmathsetmacro{\midA}{(\curA+\nextA)/2}
\path[slice,\s] \c
-- +(\curA:\r)
arc (\curA:\nextA:\r)
-- cycle;
\pgfmathsetmacro{\d}{max((\deltaA * -(.5/50) + 1) , .5)}
\begin{pgfonlayer}{foreground}
\path \c -- node[pos=\d,pie values,values of \s]{$\v\%$} +(\midA:\r);
\end{pgfonlayer}
\global\let\curA\nextA
}
\end{scope}
}
\newcommand{\legend}[2][]{
\begin{scope}[#1]
\path
\foreach \n/\s in {#2}
{
++(0,-10pt) node[\s,legend box] {} +(5pt,0) node[legend label] {\n}
}
;
\end{scope}
}
\begin{document}
\begin{tikzpicture}
[
pie chart,
slice type={comet}{blu},
slice type={legno}{rosso},
slice type={coltello}{giallo},
slice type={sedia}{viola},
slice type={caffe}{verde},
pie values/.style={font={\small}},
scale=2
]
\pie{2008}{73/comet,13/legno,7/sedia,7/coltello}
\pie[xshift=2.2cm,values of coltello/.style={pos=1.1}]%
{2009}{52/comet,23/legno,17/sedia,3/coltello,5/caffe}
\pie[xshift=4.4cm,values of sedia/.style={pos=1.1},values of coltello/.style={pos=1.25},values of caffe/.style={pos=1.35}]%
{}{62/comet,34/legno,1.5/sedia,0.5/coltello,2/caffe}
\legend[shift={(0cm,-1cm)}]{{Comet (Pordenone)}/comet, {Wood and furniture (Livenza)}/legno, {Knife (Maniago)}/coltello}
\legend[shift={(3cm,-1cm)}]{{Chair (Manzano)}/sedia, {Coffee (Trieste)}/caffe}
\end{tikzpicture}
\end{document}
答案1
我想这是答案的第一个要素:
您可以使用 pfg 数学引擎修改 \draw 调用的样式。这是您的 MWE 的修改版本,包括允许更改 \draw 中的规范的条件语句,以根据饼图扇区的值获得不同的节点定位和绘制样式。
我想有一种方法可以避免重复使用 \pgfmathparse 但目前我还不知道。
\documentclass[border=10pt,multi,tikz]{standalone}
\usetikzlibrary{patterns}
\definecolor{rosso}{RGB}{220,57,18}
\definecolor{giallo}{RGB}{255,153,0}
\definecolor{blu}{RGB}{102,140,217}
\definecolor{verde}{RGB}{16,150,24}
\definecolor{viola}{RGB}{153,0,153}
\tikzstyle{chart}=[
legend label/.style={font={\scriptsize},anchor=south,align=left},
legend box/.style={rectangle, draw, minimum size=5pt},
axis/.style={black,semithick,->},
axis label/.style={anchor=east,font={\tiny}},
]
\tikzstyle{pie chart}=[
chart,
slice/.style={line cap=round, line join=round, very thick,draw=white},
pie title/.style={font={\bf}},
slice type/.style 2 args={
##1/.style={fill=##2},
values of ##1/.style={}
}
]
\pgfdeclarelayer{background}
\pgfdeclarelayer{foreground}
\pgfsetlayers{background,main,foreground}
\newcommand{\pie}[3][]{
\begin{scope}[#1]
\pgfmathsetmacro{\curA}{90}
\pgfmathsetmacro{\r}{1}
\def\c{(0,0)}
\node[pie title] at (90:1.3) {#2};
\foreach \v/\s in{#3}{
\pgfmathsetmacro{\deltaA}{\v/100*360}
\pgfmathsetmacro{\nextA}{\curA + \deltaA}
\pgfmathsetmacro{\midA}{(\curA+\nextA)/2}
\path[slice,\s] \c
-- +(\curA:\r)
arc (\curA:\nextA:\r)
-- cycle;
% Tests on de value of \deltaA allowing to assign different values to the style parameters
\pgfmathparse{\deltaA > 50 ? \r/2 : \r}
\edef\d{\pgfmathresult}
% If the pie portion is 5% or lower the label is plotted outside of the pie else it is plotted at half the radius
\pgfmathparse{\deltaA > 50 ? \d : \r+0.2*\v}
\edef\dd{\pgfmathresult}
% If the pie portion is 5% or lower the path is plotted
\pgfmathparse{\deltaA > 50 ? "none" : "black"}
\edef\linkcolor{\pgfmathresult}
\pgfmathparse{\deltaA > 50 ? "none" : "white"}
\edef\fillcolor{\pgfmathresult}
% These last parameters allow to place the label differently around the node depending on the value of \deltaA
\pgfmathparse{\deltaA > 50 ? 0 : 1}
\edef\pos{\pgfmathresult}
\pgfmathparse{\deltaA > 50 ? 0 : 5}
\edef\shiftA{\pgfmathresult}
\pgfmathparse{\deltaA > 50 ? "center" : "west"}
\edef\anchor{\pgfmathresult}
\begin{pgfonlayer}{foreground}
\path[draw=\linkcolor] (\midA:\d) -- (\midA:\dd) -- node[pos=\pos,pie values,values of \s,draw=none,fill=\fillcolor,inner sep=0pt,anchor= \anchor]{$\v\%$}(\midA-\shiftA:\dd);
\end{pgfonlayer}
\global\let\curA\nextA
}
\end{scope}
}
\begin{document}
\begin{tikzpicture}[ pie chart, slice type={comet}{blu}, slice type={legno}{rosso}, slice type={coltello}{giallo}, slice type={sedia}{viola},slice type={caffe}{verde},pie values/.style={font={\small}},scale=2]
\pie[xshift=4.4cm]%
{}{62/comet,34/legno,1.5/sedia,0.5/coltello,2/caffe}
\end{tikzpicture}
\end{document}