diff options
author | Karl Berry <karl@freefriends.org> | 2023-12-05 20:45:17 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2023-12-05 20:45:17 +0000 |
commit | ad01b636b2ce47ee1b85617a39df3cdfcd2ff20e (patch) | |
tree | 37332eec97e542ecc04849708d16129a993ec6d8 /Master/texmf-dist/tex | |
parent | f4e21a780b5fa68baa2d7cc40d61724c656ff30a (diff) |
wheelchart (5dec23)
git-svn-id: svn://tug.org/texlive/trunk@69040 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex')
-rw-r--r-- | Master/texmf-dist/tex/latex/wheelchart/wheelchart.sty | 3177 |
1 files changed, 2753 insertions, 424 deletions
diff --git a/Master/texmf-dist/tex/latex/wheelchart/wheelchart.sty b/Master/texmf-dist/tex/latex/wheelchart/wheelchart.sty index c7f9fbc8bb0..af15d606540 100644 --- a/Master/texmf-dist/tex/latex/wheelchart/wheelchart.sty +++ b/Master/texmf-dist/tex/latex/wheelchart/wheelchart.sty @@ -1,5 +1,5 @@ %% wheelchart.sty -%% Copyright 2022 Matthias Floré +%% Copyright 2023 Matthias Floré % % This work may be distributed and/or modified under the % conditions of the LaTeX Project Public License, either version 1.3c @@ -16,428 +16,2757 @@ % This work consists of the files wheelchart.pdf, wheelchart.sty, % wheelchart.tex and README.md. \NeedsTeXFormat{LaTeX2e} -\ProvidesPackage{wheelchart}[2022/09/11 v1.0 Draw wheelcharts with TikZ] \RequirePackage{tikz} \usetikzlibrary{calc} -\def\wheelchart@slicesstart{} -\def\wheelchart@slicesend{} -\newif\ifwheelchart@contour -\newif\ifwheelchart@counterclockwise -\newif\ifwheelchart@definnercontour -\newif\ifwheelchart@draw -\newif\ifwheelchart@linesextfixed -\newif\ifwheelchart@middlefill -\newif\ifwheelchart@pie -\newif\ifwheelchart@slicesarcadaptangle -\newif\ifwheelchart@wheellines -\newcommand{\wheelchart@slicesarcdefmacros}[2]{ -\pgfmathsetmacro{\wheelchart@slicesarcA}{#1} -\pgfmathsetmacro{\wheelchart@slicesarcB}{#2} -\pgfmathsetmacro{\wheelchart@slicesarcradius}{(1-(\wheelchart@slicesarcB))*\n1*abs((1/(\wheelchart@slicesarcA))+(\wheelchart@slicesarcA))/2} -\wheelchart@slicesarcadaptanglefalse -\ifdim \wheelchart@slicesarcA pt<\z@ -\pgfmathsetmacro{\wheelchart@slicesarccoord}{max(\wheelchart@slicesarcB,0)} -\wheelchart@slicesarcadaptangletrue -\ifdim \wheelchart@slicesarcB pt<\z@ -\else -\pgfmathsetmacro{\wheelchart@halflengthsliceinnerstartplussliceouterstart}{veclen(\x3/\pgf@xx,\y3/\pgf@yy)} -\pgfmathsetmacro{\wheelchart@slicesarcradiusbound}{sqrt((\wheelchart@halflengthsliceinnerstartplussliceouterstart^2-((\wheelchart@gap)^2)+((\wheelchart@gap-\wheelchart@slicesarcA*(1-(\wheelchart@slicesarcB))*\n1-\wheelchart@slicesarcradius)^2))} -\pgfmathsetmacro{\wheelchart@slicesarcradiusboundminusslicesarcradius}{\wheelchart@slicesarcradiusbound-\wheelchart@slicesarcradius} -\pgfmathsetmacro{\wheelchart@slicesarcradiusboundplusslicesarcradius}{\wheelchart@slicesarcradiusbound+\wheelchart@slicesarcradius} -\ifdim \wheelchart@slicesarcradiusboundminusslicesarcradius pt>\wheelchart@innerradius pt -\ifdim \wheelchart@slicesarcradiusboundplusslicesarcradius pt<\wheelchart@outerradius pt -\wheelchart@slicesarcadaptanglefalse -\fi -\fi -\fi -\else -\pgfmathsetmacro{\wheelchart@slicesarccoord}{\wheelchart@slicesarcB} -\fi -\pgfmathsetmacro{\wheelchart@slicesarccoordtimesnone}{\wheelchart@slicesarccoord*\n1} -\ifwheelchart@slicesarcadaptangle -\pgfmathsetmacro{\wheelchart@slicesarcangle}{-acos((2*(\wheelchart@slicesarccoord-1))/((1-(\wheelchart@slicesarcB))*((1/(\wheelchart@slicesarcA))+(\wheelchart@slicesarcA))))} -\else -\pgfmathsetmacro{\wheelchart@slicesarcangle}{atan(((1/(\wheelchart@slicesarcA))-(\wheelchart@slicesarcA))/2)} -\fi -} -\newcommand{\wheelchart@slicesarrowdefmacros}[2]{ -\pgfmathsetmacro{\wheelchart@slicesarrowA}{#1} -\pgfmathsetmacro{\wheelchart@slicesarrowB}{#2} -\pgfmathsetmacro{\wheelchart@slicesarrowlength}{\n1} -\ifdim \wheelchart@slicesarrowA pt<\z@ -\pgfmathsetmacro{\wheelchart@slicesarrowcoord}{max(\wheelchart@slicesarrowB,0)} -\else -\pgfmathsetmacro{\wheelchart@slicesarrowcoord}{\wheelchart@slicesarrowB} -\fi -\pgfmathsetmacro{\wheelchart@slicesarrowtip}{(1-\wheelchart@slicesarrowcoord)*\wheelchart@slicesarrowA} -} -\pgfkeys{ -/wheelchart/.is family, -/wheelchart, -anchor xsep/.initial=5, -anchor ysep/.initial=5, -at/.initial={(0,0)}, -caption/.store in=\wheelchart@caption, -caption style/.style={caption style@options/.style={#1}}, -caption style@options/.style={}, -caption left/.store in=\wheelchart@captionleft, -caption left style/.style={caption left style@options/.style={#1}}, -caption left style@options/.style={}, -contour@boolean/.is if=wheelchart@contour, -contour/.style={contour@boolean=true,contour@options/.style={#1}}, -contour@options/.style={}, -counterclockwise/.is if=wheelchart@counterclockwise, -data/.initial={\WCvarC}, -data angle shift/.initial=0, -data sep/.initial=0.2, -data style/.style={data style@options/.style={#1}}, -data style@options/.style={}, -expand list/.is choice, -expand list/false/.code={\def\wheelchart@expandlistvalue{false}\def\wheelchart@foreachdeflist##1{\def\wheelchart@foreachlist{##1}}}, -expand list/once/.code={\def\wheelchart@expandlistvalue{true}\def\wheelchart@foreachdeflist##1{\def\wheelchart@foreachlist{\unexpanded\expandafter{##1}}}}, -expand list/true/.code={\def\wheelchart@expandlistvalue{true}\def\wheelchart@foreachdeflist##1{\def\wheelchart@foreachlist{##1}}}, -expand list=once, -explode/.initial=0, -explode/.default=0.2, -gap/.initial=0, -gap/.default=0.05, -gap polar/.initial=0, -gap polar/.default=1, -inner data/.store in=\wheelchart@innerdata, -inner data sep/.initial=0.2, -inner data style/.style={inner data style@options/.style={#1}}, -inner data style@options/.style={}, -inner radius/.initial=2, -legend/.store in=\wheelchart@legend, -legend entry/.store in=\wheelchart@legendentry, -lines/.initial=0, -lines/.default=1, -lines ext/.initial=0, -lines ext/.default=0.5, -lines ext bottom dir/.is choice, -lines ext bottom dir/left/.code={\pgfmathsetmacro{\wheelchart@linesextbottomdir}{-1}}, -lines ext bottom dir/right/.code={\pgfmathsetmacro{\wheelchart@linesextbottomdir}{1}}, -lines ext bottom dir=right, -lines ext dirsep/.initial=0, -lines ext fixed/.is if=wheelchart@linesextfixed, -lines ext left anchor/.initial={mid east}, -lines ext right anchor/.initial={mid west}, -lines ext top dir/.is choice, -lines ext top dir/left/.code={\pgfmathsetmacro{\wheelchart@linesexttopdir}{-1}}, -lines ext top dir/right/.code={\pgfmathsetmacro{\wheelchart@linesexttopdir}{1}}, -lines ext top dir=right, -lines sep/.initial=0.2, -lines style/.style={lines style@options/.style={#1}}, -lines style@options/.style={}, -middle/.store in=\wheelchart@middle, -middle fill@boolean/.is if=wheelchart@middlefill, -middle fill/.style={middle fill@boolean=true,middle fill@options/.style={#1}}, -middle fill@options/.style={}, -middle style/.style={middle style@options/.style={#1}}, -middle style@options/.style={}, -name/.code={\xdef\wheelchart@name{#1}}, -name=wheelchart@name, -outer radius/.initial=3, -perc precision/.initial=0, -pie/.is if=wheelchart@pie, -radius/.code 2 args={\pgfkeys{/wheelchart,inner radius={#1},outer radius={#2}}}, -slices/.store in=\wheelchart@slices, -slices arc/.code 2 args={\pgfkeys{/wheelchart,slices start arc={-(#1)}{#2},slices end arc={#1}{#2}}}, -slices arrow/.code 2 args={\pgfkeys{/wheelchart,slices start arrow={-(#1)}{#2},slices end arrow={#1}{#2}}}, -slices end arc/.code 2 args={\def\wheelchart@slicesend{{[shift={(wheelchart@sliceouterend)},rotate={90-atan2(\p2)},/utils/exec={\wheelchart@slicesarcdefmacros{#1}{#2}}]--({-\wheelchart@slicesarccoordtimesnone},0) arc[start angle={\wheelchart@counterorclockwise*\wheelchart@slicesarcangle},end angle={\wheelchart@counterorclockwise*(sign(#1)*180-\wheelchart@slicesarcangle)},radius={\wheelchart@slicesarcradius}]}}}, -slices end arrow/.code 2 args={\def\wheelchart@slicesend{{[shift={(wheelchart@sliceouterend)},rotate={90-atan2(\p2)},/utils/exec={\wheelchart@slicesarrowdefmacros{#1}{#2}}]--({-\wheelchart@slicesarrowcoord*\wheelchart@slicesarrowlength},0)--({-\wheelchart@slicesarrowlength},{\wheelchart@counterorclockwise*\wheelchart@slicesarrowtip*\wheelchart@slicesarrowlength})--({(\wheelchart@slicesarrowcoord-2)*\wheelchart@slicesarrowlength},0)}}}, -slices start arc/.code 2 args={\def\wheelchart@slicesstart{{[shift={(wheelchart@sliceinnerstart)},rotate={90-atan2(\p1)},/utils/exec={\wheelchart@slicesarcdefmacros{#1}{#2}}]({\wheelchart@slicesarccoordtimesnone},0) arc[start angle={-\wheelchart@counterorclockwise*(sign(#1)*180-\wheelchart@slicesarcangle)},end angle={-\wheelchart@counterorclockwise*\wheelchart@slicesarcangle},radius={\wheelchart@slicesarcradius}]}--}}, -slices start arrow/.code 2 args={\def\wheelchart@slicesstart{{[shift={(wheelchart@sliceinnerstart)},rotate={90-atan2(\p1)},/utils/exec={\wheelchart@slicesarrowdefmacros{#1}{#2}}]({\wheelchart@slicesarrowcoord*\wheelchart@slicesarrowlength},0)--({\wheelchart@slicesarrowlength},{-\wheelchart@counterorclockwise*\wheelchart@slicesarrowtip*\wheelchart@slicesarrowlength})--({(2-\wheelchart@slicesarrowcoord)*\wheelchart@slicesarrowlength},0)}--}}, -slices style/.style={slices style@options/.style={#1}}, -slices style@options/.style={}, -slices style={\WCvarB}, -start angle/.initial=90, -start half/.store in=\wheelchart@starthalf, -start half/.default=90, -title/.store in=\wheelchart@title, -title style/.style={title style@options/.style={#1}}, -title style@options/.style={}, -title left/.store in=\wheelchart@titleleft, -title left style/.style={title left style@options/.style={#1}}, -title left style@options/.style={}, -total angle/.initial=360, -total count/.code={\pgfmathsetmacro{\wheelchart@totalcount}{int(#1)}}, -value/.initial={\WCvarA}, -wheel data/.store in=\wheelchart@wheeldata, -wheel data pos/.initial=0.66, -wheel data style/.style={wheel data style@options/.style={#1}}, -wheel data style@options/.style={}, -wheel lines@boolean/.is if=wheelchart@wheellines, -wheel lines/.style={wheel lines@boolean=true,wheel lines@options/.style={#1}}, -wheel lines@options/.style={}, -} -\newcommand{\wheelchart@foreachinitial}[2]{\ifcsname wheelchart@totalcount\endcsname\ifnum\wheelchart@totalcount>1\gdef\wheelchart@foreachlist{}\foreach\wheelchart@n in {2,...,\wheelchart@totalcount}{\xdef\wheelchart@foreachlist{\wheelchart@foreachlist,}}\else\ifnum\wheelchart@totalcount=1\gdef\wheelchart@foreachlist{{}}\else\gdef\wheelchart@foreachlist{}\fi\fi\else\wheelchart@foreachdeflist{#1}\fi\foreach\WCvarA/\WCvarB/\WCvarC/\WCvarD/\WCvarE/\WCvarF/\WCvarG/\WCvarH/\WCvarI/\WCvarJ/\WCvarK/\WCvarL/\WCvarM/\WCvarN/\WCvarO/\WCvarP/\WCvarQ/\WCvarR/\WCvarS/\WCvarT/\WCvarU/\WCvarV/\WCvarW/\WCvarX/\WCvarY/\WCvarZ [count=\WCcount,expand list=\wheelchart@expandlistvalue] in \wheelchart@foreachlist{#2}} -\newcommand{\wheelchart@foreach}[2]{\pgfmathsetmacro{\wheelchart@angle}{\wheelchart@startangle}\wheelchart@foreachinitial{#1}{\pgfmathsetmacro{\wheelchart@outerradius}{\pgfkeysvalueof{/wheelchart/outer radius}} -\ifwheelchart@pie -\pgfmathsetmacro{\wheelchart@innerradius}{0} -\else -\pgfmathsetmacro{\wheelchart@innerradius}{\pgfkeysvalueof{/wheelchart/inner radius}} -\fi -\pgfmathsetmacro{\wheelchart@gap}{\pgfkeysvalueof{/wheelchart/gap}} -\pgfmathsetmacro{\wheelchart@gappolar}{\pgfkeysvalueof{/wheelchart/gap polar}} -\pgfmathsetmacro{\wheelchart@value}{\pgfkeysvalueof{/wheelchart/value}} -\pgfmathsetmacro{\wheelchart@newangle}{\wheelchart@angle+(\wheelchart@counterorclockwise*\wheelchart@value*(\wheelchart@totalangle/\WCtotalnum))} -\pgfmathsetmacro{\wheelchart@abshalfangleminusnewangle}{abs((\wheelchart@angle-\wheelchart@newangle)/2)} -\wheelchart@drawfalse -\pgfmathsetmacro{\wheelchart@abshalfangleminusnewangleminusgappolar}{\wheelchart@abshalfangleminusnewangle-\wheelchart@gappolar} -\ifdim \wheelchart@abshalfangleminusnewangleminusgappolar pt=180 pt -\pgfmathsetmacro{\wheelchart@outergap}{asin(\wheelchart@gap/\wheelchart@outerradius)} -\ifdim \wheelchart@gap pt<\wheelchart@innerradius pt -\pgfmathsetmacro{\wheelchart@innergap}{asin(\wheelchart@gap/\wheelchart@innerradius)} -\else -\pgfmathsetmacro{\wheelchart@innergap}{90} -\pgfmathsetmacro{\wheelchart@innerradius}{\wheelchart@gap} -\fi -\ifdim \wheelchart@innerradius pt<\wheelchart@outerradius pt -\wheelchart@drawtrue -\fi -\else -\ifdim \wheelchart@abshalfangleminusnewangleminusgappolar pt>\z@ -\pgfmathsetmacro{\wheelchart@outerradiustimessinabshalfangleminusnewangleminusgappolar}{\wheelchart@outerradius*sin(\wheelchart@abshalfangleminusnewangleminusgappolar)} -\ifdim \wheelchart@outerradiustimessinabshalfangleminusnewangleminusgappolar pt<\wheelchart@gap pt -\else -\pgfmathsetmacro{\wheelchart@outergap}{asin(\wheelchart@gap/\wheelchart@outerradius)+\wheelchart@gappolar} -\pgfmathsetmacro{\wheelchart@innerradiustimessinabshalfangleminusnewangleminusgappolar}{\wheelchart@innerradius*sin(\wheelchart@abshalfangleminusnewangleminusgappolar)} -\ifdim \wheelchart@innerradiustimessinabshalfangleminusnewangleminusgappolar pt>\wheelchart@gap pt -\pgfmathsetmacro{\wheelchart@innergap}{asin(\wheelchart@gap/\wheelchart@innerradius)+\wheelchart@gappolar} -\else -\pgfmathsetmacro{\wheelchart@innergap}{\wheelchart@abshalfangleminusnewangle} -\ifdim \wheelchart@innerradiustimessinabshalfangleminusnewangleminusgappolar pt<\wheelchart@gap pt -\pgfmathsetmacro{\wheelchart@innerradius}{\wheelchart@gap/sin(\wheelchart@abshalfangleminusnewangleminusgappolar)} -\fi -\fi -\ifdim \wheelchart@innerradius pt<\wheelchart@outerradius pt -\wheelchart@drawtrue -\fi -\fi -\fi -\fi -\pgfmathsetmacro{\wheelchart@explode}{\pgfkeysvalueof{/wheelchart/explode}} -\pgfmathsetmacro{\WCmidangle}{Mod((\wheelchart@angle+\wheelchart@newangle)/2,360)} -\pgfmathsetmacro{\wheelchart@dataangleshift}{\pgfkeysvalueof{/wheelchart/data angle shift}} -\pgfmathsetmacro{\WCdataangle}{Mod(\wheelchart@counterorclockwise*\wheelchart@dataangleshift+\WCmidangle,360)} -\pgfmathsetmacro{\WCpercentage}{\wheelchart@value/(\WCtotalnum/100)} -\pgfmathprintnumberto[precision=\pgfkeysvalueof{/wheelchart/perc precision}]{\WCpercentage}{\WCpercentagerounded} -\begin{scope}[shift={(\WCmidangle:\wheelchart@explode)}] -#2 -\end{scope} -\global\let\wheelchart@angle=\wheelchart@newangle}} -\AtBeginDocument{\@ifpackageloaded{siunitx}{\newcommand{\WCperc}{\qty[round-mode=places,round-precision=\pgfkeysvalueof{/wheelchart/perc precision}]{\WCpercentage}{\percent}}}{\newcommand{\WCperc}{\WCpercentagerounded\,\%}}} -\newcommand{\wheelchart@ifnotext}[3]{%%https://tex.stackexchange.com/questions/42280/expand-away-empty-macros-within-ifthenelse%https://tex.stackexchange.com/questions/44919/proper-way-to-detect-empty-blank-text -\begingroup% -\begin{pgfinterruptpicture}%%https://tex.stackexchange.com/questions/459853/savebox-within-tikzpicture-results-in-an-empty-savebox -\sbox0{#1}% -\ifdim\wd0=\z@% -\gdef\wheelchart@node{0}% -\else% -\gdef\wheelchart@node{1}% -\fi% -\end{pgfinterruptpicture}% -\endgroup% -\ifnum\wheelchart@node=0% -{#2}%%if #1 is empty -\else% -{#3}%%if #1 is not empty -\fi% -} -\newcommand{\wheelchart}[2][]{{ -\pgfkeys{/wheelchart,#1} -\begin{scope}[shift/.expanded={\pgfkeysvalueof{/wheelchart/at}},local bounding box/.expanded=\wheelchart@name] -\ifwheelchart@counterclockwise -\pgfmathsetmacro{\wheelchart@counterorclockwise}{1} -\else -\pgfmathsetmacro{\wheelchart@counterorclockwise}{-1} -\fi -\pgfmathsetmacro{\wheelchart@totalangle}{\pgfkeysvalueof{/wheelchart/total angle}} -\pgfmathsetmacro{\WCtotalnum}{0} -\wheelchart@foreachinitial{#2}{ -\pgfmathsetmacro{\wheelchart@value}{\pgfkeysvalueof{/wheelchart/value}} -\pgfmathparse{\wheelchart@value+\WCtotalnum} -\global\let\WCtotalnum=\pgfmathresult -\ifnum\WCcount=1 -\xdef\wheelchart@firstvalue{\wheelchart@value} -\fi -\xdef\WCtotalcount{\WCcount} -} -\ifcsname wheelchart@starthalf\endcsname -\pgfmathsetmacro{\wheelchart@startangle}{Mod(\wheelchart@starthalf-(\wheelchart@counterorclockwise*\wheelchart@firstvalue*0.5*(\wheelchart@totalangle/\WCtotalnum)),360)} -\else -\pgfmathsetmacro{\wheelchart@startangle}{Mod(\pgfkeysvalueof{/wheelchart/start angle},360)} -\fi -\wheelchart@definnercontourfalse -\ifwheelchart@contour -\wheelchart@definnercontourtrue -\xdef\wheelchart@outercontour{} -\wheelchart@foreach{#2}{ -\xdef\wheelchart@outercontour{(\wheelchart@newangle:\wheelchart@outerradius) arc[start angle=\wheelchart@newangle,end angle=\wheelchart@angle,radius=\wheelchart@outerradius]--\wheelchart@outercontour} -} -\else -\ifwheelchart@middlefill -\wheelchart@definnercontourtrue -\fi -\fi -\ifwheelchart@definnercontour -\xdef\wheelchart@innercontour{} -\wheelchart@foreach{#2}{ -\xdef\wheelchart@innercontour{\wheelchart@innercontour(\wheelchart@angle:\wheelchart@innerradius) arc[start angle=\wheelchart@angle,end angle=\wheelchart@newangle,radius=\wheelchart@innerradius]--} -} -\fi -\ifwheelchart@middlefill -\fill[/wheelchart/middle fill@options] -\ifdim \wheelchart@totalangle pt=360 pt -\else -(0,0)-- -\fi -\wheelchart@innercontour cycle; -\fi -\wheelchart@foreach{#2}{ -\ifcsname wheelchart@slices\endcsname -\begin{scope}[shift={(\WCmidangle:{(\wheelchart@innerradius+\wheelchart@outerradius)/2})},rotate=\WCmidangle] -\fill[/wheelchart/slices style@options] \wheelchart@slices -\end{scope} -\else -\ifwheelchart@draw -\pgfmathsetmacro{\wheelchart@sliceinnerstartangle}{\wheelchart@angle+(\wheelchart@counterorclockwise*(\wheelchart@innergap))} -\pgfmathsetmacro{\wheelchart@sliceinnerendangle}{\wheelchart@newangle-(\wheelchart@counterorclockwise*(\wheelchart@innergap))} -\pgfmathsetmacro{\wheelchart@sliceouterstartangle}{\wheelchart@angle+(\wheelchart@counterorclockwise*(\wheelchart@outergap))} -\pgfmathsetmacro{\wheelchart@sliceouterendangle}{\wheelchart@newangle-(\wheelchart@counterorclockwise*(\wheelchart@outergap))} -\coordinate (wheelchart@sliceinnerstart) at (\wheelchart@sliceinnerstartangle:\wheelchart@innerradius); -\coordinate (wheelchart@sliceinnerend) at (\wheelchart@sliceinnerendangle:\wheelchart@innerradius); -\coordinate (wheelchart@sliceouterstart) at (\wheelchart@sliceouterstartangle:\wheelchart@outerradius); -\coordinate (wheelchart@sliceouterend) at (\wheelchart@sliceouterendangle:\wheelchart@outerradius); -\fill[/wheelchart/slices style@options] let \p1=($(wheelchart@sliceouterstart)-(wheelchart@sliceinnerstart)$),\p2=($(wheelchart@sliceouterend)-(wheelchart@sliceinnerend)$),\p3=($(wheelchart@sliceinnerstart)!0.5!(wheelchart@sliceouterstart)$),\n1={veclen(\x1/\pgf@xx,\y1/\pgf@yy)/2} in \wheelchart@slicesstart(wheelchart@sliceouterstart) arc[start angle=\wheelchart@sliceouterstartangle,end angle=\wheelchart@sliceouterendangle,radius=\wheelchart@outerradius]\wheelchart@slicesend--(wheelchart@sliceinnerend) arc[start angle=\wheelchart@sliceinnerendangle,end angle=\wheelchart@sliceinnerstartangle,radius=\wheelchart@innerradius]--cycle; -\fi -\fi -} -\ifwheelchart@wheellines -\ifdim \wheelchart@totalangle pt=360 pt -\def\wheelchart@start{1} -\else -\def\wheelchart@start{0} -\fi -\wheelchart@foreach{#2}{ -\foreach\wheelchart@n in {\wheelchart@start,...,\wheelchart@value}{ -\pgfmathsetmacro{\wheelchart@anglewheellines}{\wheelchart@angle+(\wheelchart@counterorclockwise*\wheelchart@n*(\wheelchart@totalangle/\WCtotalnum))} -\draw[/wheelchart/wheel lines@options] (\wheelchart@anglewheellines:\wheelchart@innerradius)--(\wheelchart@anglewheellines:\wheelchart@outerradius); -} -\gdef\wheelchart@start{1} -} -\fi -\ifwheelchart@contour -\ifdim \wheelchart@totalangle pt=360 pt -\draw[/wheelchart/contour@options] \wheelchart@innercontour cycle; -\draw[/wheelchart/contour@options] \wheelchart@outercontour cycle; -\else -\draw[/wheelchart/contour@options] \wheelchart@innercontour\wheelchart@outercontour cycle; -\fi -\fi -\wheelchart@foreach{#2}{ -\pgfmathsetmacro{\wheelchart@datasep}{\pgfkeysvalueof{/wheelchart/data sep}} -\pgfmathsetmacro{\wheelchart@lines}{\pgfkeysvalueof{/wheelchart/lines}} -\pgfmathsetmacro{\wheelchart@linesext}{\pgfkeysvalueof{/wheelchart/lines ext}} -\pgfmathsetmacro{\wheelchart@linessep}{\pgfkeysvalueof{/wheelchart/lines sep}} -\ifdim \wheelchart@linesext pt>\z@ -\pgfmathsetmacro{\wheelchart@linesextdirsep}{\pgfkeysvalueof{/wheelchart/lines ext dirsep}} -\pgfmathparse{ -(\WCdataangle<90-\wheelchart@linesextdirsep?"1": -(\WCdataangle<=90+\wheelchart@linesextdirsep?"\wheelchart@linesexttopdir": -(\WCdataangle<270-\wheelchart@linesextdirsep?"-1": -(\WCdataangle<=270+\wheelchart@linesextdirsep?"\wheelchart@linesextbottomdir": -"1" -)))) -} -\edef\wheelchart@linesextdir{\pgfmathresult} -\draw[/wheelchart/lines style@options] let \p1=(\WCdataangle:{\wheelchart@outerradius+\wheelchart@linessep+\wheelchart@lines}) in (\WCdataangle:{\wheelchart@outerradius+\wheelchart@linessep})--(\p1) -\ifwheelchart@linesextfixed ---({\wheelchart@linesextdir*(\wheelchart@outerradius+\wheelchart@linessep+\wheelchart@lines+\wheelchart@linesext)},\y1) -\else ---++({\wheelchart@linesextdir*\wheelchart@linesext},0) -\fi -coordinate (wheelchart@datacoord); -\pgfmathparse{ -(\wheelchart@linesextdir==1?"\pgfkeysvalueof{/wheelchart/lines ext right anchor}": -(\wheelchart@linesextdir==-1?"\pgfkeysvalueof{/wheelchart/lines ext left anchor}": -)) -} -\edef\wheelchart@dataanchor{\pgfmathresult} -\else -\pgfmathsetmacro{\wheelchart@anchorxsep}{\pgfkeysvalueof{/wheelchart/anchor xsep}} -\pgfmathsetmacro{\wheelchart@anchorysep}{\pgfkeysvalueof{/wheelchart/anchor ysep}} -\pgfmathparse{ -(\WCdataangle==0?"west": -(\WCdataangle==90?"south": -(\WCdataangle==180?"east": -(\WCdataangle==270?"north": -(\WCdataangle<=\wheelchart@anchorysep?"west": -(\WCdataangle<90-\wheelchart@anchorxsep?"south west": -(\WCdataangle<=90+\wheelchart@anchorxsep?"south": -(\WCdataangle<180-\wheelchart@anchorysep?"south east": -(\WCdataangle<=180+\wheelchart@anchorysep?"east": -(\WCdataangle<270-\wheelchart@anchorxsep?"north east": -(\WCdataangle<=270+\wheelchart@anchorxsep?"north": -(\WCdataangle<360-\wheelchart@anchorysep?"north west": -"west" -)))))))))))) -} -\edef\wheelchart@dataanchor{\pgfmathresult} -\ifdim \wheelchart@lines pt>\z@ -\draw[/wheelchart/lines style@options] (\WCdataangle:{\wheelchart@outerradius+\wheelchart@linessep})--++(\WCdataangle:\wheelchart@lines) coordinate[shift={(\WCdataangle:\wheelchart@datasep)}] (wheelchart@datacoord); -\else -\coordinate (wheelchart@datacoord) at (\WCdataangle:{\wheelchart@outerradius+\wheelchart@datasep}); -\fi -\fi -\wheelchart@ifnotext{\pgfkeysvalueof{/wheelchart/data}}{}{\node[anchor=\wheelchart@dataanchor,align=left,/wheelchart/data style@options] at (wheelchart@datacoord) {\pgfkeysvalueof{/wheelchart/data}};} -\ifcsname wheelchart@innerdata\endcsname -\wheelchart@ifnotext{\wheelchart@innerdata}{}{% -\pgfmathsetmacro{\wheelchart@innerdatasep}{\pgfkeysvalueof{/wheelchart/inner data sep}}% -\node[align=left,/wheelchart/inner data style@options] at (\WCdataangle:{\wheelchart@innerradius-(\wheelchart@innerdatasep)}) {\wheelchart@innerdata};% -} -\fi -\ifcsname wheelchart@wheeldata\endcsname -\wheelchart@ifnotext{\wheelchart@wheeldata}{}{% -\pgfmathsetmacro{\wheelchart@wheeldatapos}{\pgfkeysvalueof{/wheelchart/wheel data pos}}% -\node[align=left,/wheelchart/wheel data style@options] at (\WCdataangle:{\wheelchart@wheeldatapos*\wheelchart@outerradius+(1-\wheelchart@wheeldatapos)*\wheelchart@innerradius}) {\wheelchart@wheeldata};% -} -\fi -\ifcsname wheelchart@legendentry\endcsname -\wheelchart@legendentry -\fi -} -\ifcsname wheelchart@middle\endcsname -\wheelchart@ifnotext{\wheelchart@middle}{}{% -\node[align=center,/wheelchart/middle style@options] at (0,0) {\wheelchart@middle};% -} -\fi -\ifcsname wheelchart@legend\endcsname -\wheelchart@legend -\fi -\end{scope} -\ifcsname wheelchart@captionleft\endcsname -\wheelchart@ifnotext{\wheelchart@captionleft}{}{% -\node[anchor=north west,align=left,/wheelchart/caption left style@options] at ($(\wheelchart@name.south west)-(0,0.5)$) {\wheelchart@captionleft};% -} -\fi -\ifcsname wheelchart@caption\endcsname -\wheelchart@ifnotext{\wheelchart@caption}{}{% -\coordinate[shift/.expanded={\pgfkeysvalueof{/wheelchart/at}}] (wheelchart@center) at (0,0);% -\node[anchor=north,align=center,/wheelchart/caption style@options] at ($(\wheelchart@name.south-|wheelchart@center)-(0,0.5)$) {\wheelchart@caption};% -} -\fi -\ifcsname wheelchart@titleleft\endcsname -\wheelchart@ifnotext{\wheelchart@titleleft}{}{% -\node[anchor=south west,align=left,/wheelchart/title left style@options] at ($(\wheelchart@name.north west)+(0,0.5)$) {\wheelchart@titleleft};% -} -\fi -\ifcsname wheelchart@title\endcsname -\wheelchart@ifnotext{\wheelchart@title}{}{% -\coordinate[shift/.expanded={\pgfkeysvalueof{/wheelchart/at}}] (wheelchart@center) at (0,0);% -\node[anchor=south,align=center,/wheelchart/title style@options] at ($(\wheelchart@name.north-|wheelchart@center)+(0,0.5)$) {\wheelchart@title};% -} -\fi -}} -\endinput
\ No newline at end of file +\ProvidesExplPackage{wheelchart}{2023/12/03}{2.0}{Draw wheelcharts with TikZ} + +%%> \subsection{Variables} + +\newcounter { g__wheelchart_WCcount_counter } + +\bool_new:N \l__wheelchart_arc_bool +\bool_new:N \l__wheelchart_contour_bool +\bool_new:N \g__wheelchart_def_angle_radius_shift_bool +\bool_new:N \l__wheelchart_def_inner_contour_bool +\bool_new:N \l__wheelchart_discrete_bool +\bool_new:N \l__wheelchart_etoc_use_name_bool +\bool_new:N \l__wheelchart_legend_only_bool +\bool_new:N \l__wheelchart_legend_row_bool +\bool_new:N \l__wheelchart_lines_ext_dir_bool +\bool_new:N \l__wheelchart_middle_fill_bool +\bool_new:N \l__wheelchart_pie_bool +\bool_new:N \l__wheelchart_plot_bool +\bool_new:N \l__wheelchart_slices_bool +\bool_new:N \l__wheelchart_wheel_lines_bool + +\box_new:N \l__wheelchart_arc_data_box +\box_new:N \g__wheelchart_if_text_box + +\clist_new:N \l__wheelchart_header_clist +\clist_new:N \g__wheelchart_slice_range_for_loop_clist +\clist_new:N \l__wheelchart_slice_range_local_clist + +\fp_const:Nn \c__wheelchart_arc_data_end_factor_center_fp { 0.5 } +\fp_const:Nn \c__wheelchart_arc_data_end_factor_left_fp { 1 } +\fp_const:Nn \c__wheelchart_arc_data_end_factor_right_fp { 0 } +\fp_const:Nn \c__wheelchart_arc_data_start_factor_center_fp { -0.5 } +\fp_const:Nn \c__wheelchart_arc_data_start_factor_left_fp { 0 } +\fp_const:Nn \c__wheelchart_arc_data_start_factor_right_fp { -1 } +\fp_new:N \l__wheelchart_abs_half_angle_minus_new_angle_fp +\fp_new:N \l__wheelchart_abs_half_angle_minus_new_angle_minus_gap_polar_fp +\fp_new:N \l__wheelchart_anchor_xsep_fp +\fp_new:N \l__wheelchart_anchor_ysep_fp +\fp_new:N \g__wheelchart_angle_fp +\fp_new:N \l__wheelchart_angle_wheel_lines_fp +\fp_new:N \l__wheelchart_arc_data_angle_pos_fp +\fp_new:N \l__wheelchart_arc_data_angle_shift_fp +\fp_new:N \l__wheelchart_arc_data_dir_fp +\fp_new:N \g__wheelchart_arc_data_factor_fp +\fp_new:N \l__wheelchart_arc_data_pos_fp +\fp_new:N \l__wheelchart_arc_data_sep_fp +\fp_new:N \g__wheelchart_arc_data_slice_length_fp +\fp_new:N \l__wheelchart_arc_pos_fp +\fp_new:N \l__wheelchart_arc_sep_fp +\fp_new:N \l__wheelchart_coord_determinant_fp +\fp_new:N \l__wheelchart_counter_or_clockwise_fp +\fp_new:N \l__wheelchart_data_angle_pos_fp +\fp_new:N \l__wheelchart_data_angle_shift_fp +\fp_new:N \l__wheelchart_data_pos_fp +\fp_new:N \l__wheelchart_data_sep_fp +\fp_new:N \g__wheelchart_def_angle_angle_fp +\fp_new:N \l__wheelchart_discrete_end_length_fp +\fp_new:N \l__wheelchart_discrete_factor_fp +\fp_new:N \l__wheelchart_discrete_inner_length_fp +\fp_new:N \l__wheelchart_discrete_level_fp +\fp_new:N \l__wheelchart_discrete_level_end_length_fp +\fp_new:N \l__wheelchart_discrete_level_start_length_fp +\fp_new:N \l__wheelchart_discrete_levels_sum_fp +\fp_new:N \l__wheelchart_discrete_outer_length_fp +\fp_new:N \l__wheelchart_discrete_start_length_fp +\fp_new:N \l__wheelchart_discrete_sublevel_end_length_fp +\fp_new:N \l__wheelchart_discrete_sublevel_start_length_fp +\fp_new:N \l__wheelchart_explode_fp +\fp_new:N \l__wheelchart_gap_fp +\fp_new:N \l__wheelchart_gap_max_angle_fp +\fp_new:N \l__wheelchart_gap_max_angle_def_fp +\fp_new:N \l__wheelchart_gap_polar_fp +\fp_new:N \l__wheelchart_gap_radius_fp +\fp_new:N \g__wheelchart_half_ex_over_one_cm_fp +\fp_new:N \l__wheelchart_inner_data_angle_pos_fp +\fp_new:N \l__wheelchart_inner_data_angle_shift_fp +\fp_new:N \l__wheelchart_inner_data_pos_fp +\fp_new:N \l__wheelchart_inner_data_sep_fp +\fp_new:c { l__wheelchart_inner~end_x_fp } +\fp_new:c { l__wheelchart_inner~end_y_fp } +\fp_new:N \l__wheelchart_inner_gap_fp +\fp_new:N \l__wheelchart_inner_plot_variable_fp +\fp_new:N \l__wheelchart_inner_radius_fp +\fp_new:N \l__wheelchart_inner_radius_orig_fp +\fp_new:c { l__wheelchart_inner~start_x_fp } +\fp_new:c { l__wheelchart_inner~start_y_fp } +\fp_new:N \l__wheelchart_lines_fp +\fp_new:N \l__wheelchart_lines_angle_pos_fp +\fp_new:N \l__wheelchart_lines_angle_shift_fp +\fp_new:N \l__wheelchart_lines_ext_fp +\fp_new:N \l__wheelchart_lines_ext_dirsep_fp +\fp_new:N \l__wheelchart_lines_ext_fixed_left_fp +\fp_new:N \l__wheelchart_lines_ext_fixed_right_fp +\fp_new:N \l__wheelchart_lines_pos_fp +\fp_new:N \l__wheelchart_lines_sep_fp +\fp_new:N \g__wheelchart_new_angle_fp +\fp_new:c { l__wheelchart_outer~end_x_fp } +\fp_new:c { l__wheelchart_outer~end_y_fp } +\fp_new:N \l__wheelchart_outer_gap_fp +\fp_new:N \l__wheelchart_outer_plot_variable_fp +\fp_new:N \l__wheelchart_outer_radius_fp +\fp_new:c { l__wheelchart_outer~start_x_fp } +\fp_new:c { l__wheelchart_outer~start_y_fp } +\fp_new:N \l__wheelchart_plot_variable_fp +\fp_new:N \g__wheelchart_previous_x_coord_fp +\fp_new:N \g__wheelchart_previous_y_coord_fp +\fp_new:N \l__wheelchart_samples_fp +\fp_new:N \l__wheelchart_slice_inner_end_angle_fp +\fp_new:N \l__wheelchart_slice_inner_start_angle_fp +\fp_new:N \l__wheelchart_slice_outer_end_angle_fp +\fp_new:N \l__wheelchart_slice_outer_start_angle_fp +\fp_new:N \l__wheelchart_slices_angle_fp +\fp_new:N \l__wheelchart_slices_angle_pos_fp +\fp_new:N \l__wheelchart_slices_angle_shift_fp +\fp_new:N \l__wheelchart_slices_arc_A_fp +\fp_new:N \l__wheelchart_slices_arc_A_abs_fp +\fp_new:N \l__wheelchart_slices_arc_angle_fp +\fp_new:N \l__wheelchart_slices_arc_B_fp +\fp_new:N \l__wheelchart_slices_arc_coord_fp +\fp_new:N \l__wheelchart_slices_arc_rotate_fp +\fp_new:N \l__wheelchart_slices_arrow_A_fp +\fp_new:N \l__wheelchart_slices_arrow_B_fp +\fp_new:N \l__wheelchart_slices_arrow_coord_fp +\fp_new:N \l__wheelchart_slices_inner_end_angle_shift_fp +\fp_new:N \l__wheelchart_slices_inner_start_angle_shift_fp +\fp_new:N \g__wheelchart_slices_orientation_fp +\fp_new:N \l__wheelchart_slices_orientation_new_angle_fp +\fp_new:N \l__wheelchart_slices_outer_end_angle_shift_fp +\fp_new:N \l__wheelchart_slices_outer_start_angle_shift_fp +\fp_new:N \l__wheelchart_slices_pos_fp +\fp_new:N \l__wheelchart_slices_sep_fp +\fp_new:N \l__wheelchart_start_angle_fp +\fp_new:N \l__wheelchart_total_angle_fp +\fp_new:N \l__wheelchart_total_count_fp +\fp_new:N \l__wheelchart_value_fp +\fp_new:N \g__wheelchart_value_global_fp +\fp_new:N \l__wheelchart_wheel_data_angle_pos_fp +\fp_new:N \l__wheelchart_wheel_data_angle_shift_fp +\fp_new:N \l__wheelchart_wheel_data_pos_fp +\fp_new:N \l__wheelchart_wheel_data_sep_fp +\fp_new:N \g__wheelchart_x_coord_fp +\fp_new:N \g__wheelchart_y_coord_fp + +\int_const:Nn \c__wheelchart_lines_ext_dir_left_int { -1 } +\int_const:Nn \c__wheelchart_lines_ext_dir_right_int { 1 } +\int_new:N \g__wheelchart_discrete_count_int +\int_new:N \l__wheelchart_discrete_levels_int +\int_new:N \l__wheelchart_discrete_partitioning_first_index_int +\int_new:N \l__wheelchart_discrete_partitioning_second_index_int +\int_new:N \l__wheelchart_discrete_sort_int +\int_new:N \l__wheelchart_discrete_space_at_borders_int +\int_set:Nn \l__wheelchart_discrete_space_at_borders_int { -1 } +\int_new:N \l__wheelchart_discrete_sublevels_int +\int_new:N \l__wheelchart_etoc_count_total_pages_int +\int_new:N \l__wheelchart_legend_columns_int +\int_new:N \l__wheelchart_legend_rows_int +\int_new:N \l__wheelchart_lines_ext_bottom_dir_int +\int_new:N \l__wheelchart_lines_ext_dir_int +\int_new:N \l__wheelchart_lines_ext_top_dir_int +\int_new:N \l__wheelchart_slice_range_index_int + +\seq_new:N \l__wheelchart_discrete_coefficients_first_seq +\seq_new:N \l__wheelchart_discrete_coefficients_second_seq +\seq_new:N \l__wheelchart_discrete_points_seq +\seq_new:N \l__wheelchart_list_seq +\seq_new:N \l__wheelchart_list_items_seq + +\tl_new:N \l__wheelchart_arc_data_align_tl +\tl_new:N \l__wheelchart_data_anchor_tl +\tl_new:N \l__wheelchart_etoc_level_tl +\tl_new:N \l__wheelchart_etoc_name_tl +\tl_new:N \l__wheelchart_expand_list_tl +\tl_new:N \l__wheelchart_expand_list_items_tl +\tl_new:N \g__wheelchart_inner_contour_tl +\tl_new:N \l__wheelchart_key_name_tl +\tl_new:N \l__wheelchart_key_range_tl +\tl_new:N \l__wheelchart_legend_row_tl +\tl_new:N \g__wheelchart_name_tl +\tl_new:N \g__wheelchart_outer_contour_tl +\tl_new:N \l__wheelchart_slices_tl +\tl_new:N \l__wheelchart_slices_end_tl +\tl_set:Nn \l__wheelchart_slices_end_tl + { -- ( \fp_use:c { l__wheelchart_inner~end_x_fp } , \fp_use:c { l__wheelchart_inner~end_y_fp } ) } +\tl_new:N \l__wheelchart_slices_inner_tl +\tl_set:Nn \l__wheelchart_slices_inner_tl + { + \fp_compare:nNnT { \l__wheelchart_inner_radius_fp } > { 0 } + { + \fp_compare:nNnT { \l__wheelchart_inner_gap_fp } < { \l__wheelchart_abs_half_angle_minus_new_angle_fp } + { + arc + [ + start~angle = \fp_use:N \l__wheelchart_slice_inner_end_angle_fp , + end~angle = \fp_use:N \l__wheelchart_slice_inner_start_angle_fp , + radius = \fp_use:N \l__wheelchart_inner_radius_fp + ] + } + } + } +\tl_new:N \l__wheelchart_slices_outer_tl +\tl_set:Nn \l__wheelchart_slices_outer_tl + { + arc + [ + start~angle = \fp_use:N \l__wheelchart_slice_outer_start_angle_fp , + end~angle = \fp_use:N \l__wheelchart_slice_outer_end_angle_fp , + radius = \fp_use:N \l__wheelchart_outer_radius_fp + ] + } +\tl_new:N \l__wheelchart_slices_start_tl +\tl_set:Nn \l__wheelchart_slices_start_tl { -- cycle } +\tl_new:N \l__wheelchart_type_tl +\tl_set:Nn \l__wheelchart_type_tl { default } + +%%> \subsection{Functions} + +\cs_generate_variant:Nn \seq_set_split:Nnn { Nen , Neo } +\cs_generate_variant:Nn \tl_build_put_right:Nn { NV } + +\cs_new:Npn \__wheelchart_arc_around_text:nnn #1#2#3 + { + \__wheelchart_convex_comb_coord_plot:nnnnnnn + { draw , / wheelchart / arc_style , / wheelchart / arc_#1_half } + { + \fp_eval:n + { + \l__wheelchart_arc_data_angle_pos_fp + 0.5 * \g__wheelchart_arc_data_factor_fp * + ( + sign ( \l__wheelchart_arc_data_dir_fp ) * + ( + \fp_use:c { c__wheelchart_arc_data_start_factor_\l__wheelchart_arc_data_align_tl _fp } + + \fp_use:c { c__wheelchart_arc_data_end_factor_\l__wheelchart_arc_data_align_tl _fp } + ) + + #2 + ) + } + } + {#3} + { \l__wheelchart_plot_variable_fp } + { 0 } + { \l__wheelchart_arc_pos_fp } + { \l__wheelchart_arc_sep_fp } + } + +\cs_new:Npn \__wheelchart_caption_and_title:nnnnn #1#2#3#4#5 + { + \__wheelchart_if_text:nn {#1} + { + \node [ anchor = #2 , align = #3 , / wheelchart / #1_style ] + at ( $ (#4) + ( 0 , { #5 * ( \pgfkeysvalueof { / wheelchart / #1~sep } ) } ) $ ) + { \pgfkeysvalueof { / wheelchart / #1 } } ; + } + } + +\cs_new:Npn \__wheelchart_convex_comb_coord_aux:n #1 { (#1) } + +\cs_generate_variant:Nn \__wheelchart_convex_comb_coord_aux:n { o } + +\cs_new:Npn \__wheelchart_convex_comb_coord_def:nnnn #1#2#3#4 + { + $ + ( + \__wheelchart_inner_plot:nn + { + \fp_eval:n + { + ( 1 - (#1) ) * \l__wheelchart_slice_inner_start_angle_fp + + (#1) * \l__wheelchart_slice_inner_end_angle_fp + + \l__wheelchart_counter_or_clockwise_fp * (#2) + } + } + { \fp_eval:n { \l__wheelchart_inner_radius_fp - (#4) } } + ) + ! { \fp_eval:n {#3} } ! + ( + \__wheelchart_outer_plot:nn + { + \fp_eval:n + { + ( 1 - (#1) ) * \l__wheelchart_slice_outer_start_angle_fp + + (#1) * \l__wheelchart_slice_outer_end_angle_fp + + \l__wheelchart_counter_or_clockwise_fp * (#2) + } + } + { \fp_eval:n { \l__wheelchart_outer_radius_fp + (#4) } } + ) + $%note the () around the #i's to keep these contents together + } + +\cs_new:Npn \__wheelchart_convex_comb_coord:nnnn #1#2#3#4 + { \__wheelchart_convex_comb_coord_aux:o { \__wheelchart_convex_comb_coord_def:nnnn {#1} {#2} {#3} {#4} } } + +\cs_new:Npn \__wheelchart_convex_comb_coord_plot_aux:nnnn #1#2#3#4 + { + \path [#1] plot + [ + domain = {#2} \c_colon_str {#3} , + samples = \fp_use:N \l__wheelchart_samples_fp , + variable = \l__wheelchart_plot_variable_fp + ] + ( {#4} ) ; + } + +\cs_generate_variant:Nn \__wheelchart_convex_comb_coord_plot_aux:nnnn { nnno } + +\cs_new:Npn \__wheelchart_convex_comb_coord_plot:nnnnnnn #1#2#3#4#5#6#7 + { + \__wheelchart_convex_comb_coord_plot_aux:nnno {#1} {#2} {#3} + { \__wheelchart_convex_comb_coord_def:nnnn {#4} {#5} {#6} { \g__wheelchart_half_ex_over_one_cm_fp + (#7) } } + } + +\cs_new:Npn \__wheelchart_def_angle:nnnN #1#2#3#4 + { + \path let + \p { l__wheelchart_def_angle_1 } = \__wheelchart_convex_comb_coord:nnnn {#1} {#2} { 0 } {#3} , + \p { l__wheelchart_def_angle_2 } = \__wheelchart_convex_comb_coord:nnnn {#1} {#2} { 1 } {#3} + in + [ + / utils / exec = + { + \bool_gset:Nn \g__wheelchart_def_angle_radius_shift_bool + { + \fp_compare_p:n + { + \y { l__wheelchart_def_angle_2 } - \y { l__wheelchart_def_angle_1 } == 0 + && + \x { l__wheelchart_def_angle_2 } - \x { l__wheelchart_def_angle_1 } == 0 + } + } + \bool_if:NF \g__wheelchart_def_angle_radius_shift_bool + { + \fp_gset:Nn \g__wheelchart_def_angle_angle_fp + { + atand + ( + \y { l__wheelchart_def_angle_2 } - \y { l__wheelchart_def_angle_1 } , + \x { l__wheelchart_def_angle_2 } - \x { l__wheelchart_def_angle_1 } + ) + }%here \pgf@xx and so on are not used + } + } + ] + ; + \bool_if:NT \g__wheelchart_def_angle_radius_shift_bool + { + \path let + \p { l__wheelchart_def_angle_1 } = + \__wheelchart_convex_comb_coord:nnnn {#1} {#2} { 0 } { \fp_eval:n { (#3) + 1 / \l__wheelchart_samples_fp } } , + \p { l__wheelchart_def_angle_2 } = + \__wheelchart_convex_comb_coord:nnnn {#1} {#2} { 1 } { \fp_eval:n { (#3) + 1 / \l__wheelchart_samples_fp } } + in + [ + / utils / exec = + { + \fp_gset:Nn \g__wheelchart_def_angle_angle_fp + { + atand + ( + \y { l__wheelchart_def_angle_2 } - \y { l__wheelchart_def_angle_1 } , + \x { l__wheelchart_def_angle_2 } - \x { l__wheelchart_def_angle_1 } + ) + } + } + ] + ;%here \pgf@xx and so on are not used + } + \pgfmathsetmacro {#4} { Mod ( \fp_use:N \g__wheelchart_def_angle_angle_fp , 360 ) } + } + +\cs_new:Npn \__wheelchart_def_coord_aux:nn #1#2 + { + \path let \p { l__wheelchart_coord } = ( \use:c { __wheelchart_#1_plot:nn } {#2} { \fp_use:c { l__wheelchart_#1_radius_fp } } ) + in + [ + / utils / exec = + { + \fp_gset:Nn \g__wheelchart_x_coord_fp + { + ( \pgf@yy * \x { l__wheelchart_coord } - \pgf@yx * \y { l__wheelchart_coord } ) / \l__wheelchart_coord_determinant_fp + } + \fp_gset:Nn \g__wheelchart_y_coord_fp + { + ( \pgf@xx * \y { l__wheelchart_coord } - \pgf@xy * \x { l__wheelchart_coord } ) / \l__wheelchart_coord_determinant_fp + } + } + ] + ; + } + +\cs_new:Npn \__wheelchart_def_coord:nn #1#2 + { + \__wheelchart_def_coord_aux:nn {#1} { \fp_use:c { l__wheelchart_slice_#1_#2_angle_fp } } + \fp_set_eq:cN { l__wheelchart_#1~#2_x_fp } \g__wheelchart_x_coord_fp + \fp_set_eq:cN { l__wheelchart_#1~#2_y_fp } \g__wheelchart_y_coord_fp + } + +\cs_new:Npn \__wheelchart_def_gap:NN #1#2 + { + \fp_set:Nn #1 + { + (#2) * sind ( min ( \l__wheelchart_abs_half_angle_minus_new_angle_minus_gap_polar_fp , \l__wheelchart_gap_max_angle_def_fp ) ) + < + \l__wheelchart_gap_fp + ? + min ( \l__wheelchart_abs_half_angle_minus_new_angle_fp , \l__wheelchart_gap_max_angle_def_fp ) + : + asind ( min ( \l__wheelchart_gap_fp / ( (#2) + 1 - sign (#2) ) , 1 ) ) + \l__wheelchart_gap_polar_fp + %note the min ( ... , 1 ) such that the asind is always defined + %also note the + 1 - sign (#2) such that the denominator is also nonzero if #2 = 0 + } + } + +\cs_new:Npn \__wheelchart_def_macro:Nn #1#2 + { + \str_case:enF { \pgfkeysvalueof { / wheelchart / parse } } + { + { pgfmath } + { + \pgfmathparse {#2} + \fp_set:Nn #1 { \pgfmathresult } + } + { l3fp } + { \fp_set:Nn #1 {#2} } + } + { \pgfkeys { / errors / unknown~choice~value /. expanded = { parse } { \pgfkeysvalueof { / wheelchart / parse } } } } + } + +\cs_new:Npn \__wheelchart_def_macros:n #1 + { + \str_case:enF { \pgfkeysvalueof { / wheelchart / parse } } + { + { pgfmath } + { + \clist_map_inline:nn {#1} + { + \pgfmathparse { \pgfkeysvalueof { / wheelchart / ##1 } } + \fp_set:cn { l__wheelchart_\str_map_function:nN {##1} \__wheelchart_space_to_underscore:n _fp } { \pgfmathresult } + } + } + { l3fp } + { + \clist_map_inline:nn {#1} + { + \fp_set:cn { l__wheelchart_\str_map_function:nN {##1} \__wheelchart_space_to_underscore:n _fp } + { \pgfkeysvalueof { / wheelchart / ##1 } } + } + } + } + { \pgfkeys { / errors / unknown~choice~value /. expanded = { parse } { \pgfkeysvalueof { / wheelchart / parse } } } } + } + +\cs_new:Npn \__wheelchart_def_slice_angle:nnnn #1#2#3#4 + { + \bool_if:NTF \l__wheelchart_plot_bool + { + \fp_set:cn { l__wheelchart_slice_#1_#2_angle_fp } + { + \fp_use:c { g__wheelchart_#3angle_fp } + + ( + \l__wheelchart_counter_or_clockwise_fp * + ( (#4) * \fp_use:c { l__wheelchart_#1_gap_fp } + \fp_use:c { l__wheelchart_slices_#1_#2_angle_shift_fp } ) + ) + } + } + { + \fp_set:cn { l__wheelchart_slice_#1_#2_angle_fp } + { + \fp_use:c { g__wheelchart_#3angle_fp } + + ( + \l__wheelchart_counter_or_clockwise_fp * + ( + (#4) * \fp_use:c { l__wheelchart_#1_gap_fp } + \fp_use:c { l__wheelchart_slices_#1_#2_angle_shift_fp } + - asind + ( + \l__wheelchart_inner_radius_fp * sind ( \fp_use:c { l__wheelchart_slices_#1_#2_angle_shift_fp } ) + / \l__wheelchart_outer_radius_fp + ) + ) + ) + } + } + } + +\cs_new:Npn \__wheelchart_def_slice_keys:n #1 + { + {%note the double {{...}} such that the contents is in a group + %such that pgfkeys which are specific to the current slice are local for this slice + \clist_if_in:NVT \l__wheelchart_slice_range_local_clist \WCcount + { + \pgfkeys { / wheelchart , slice_final /. expanded = { \exp_not:v { l__wheelchart_slice_\WCcount _keys_clist } } } + \pgfkeys{ / wheelchart , slice_final_style } + } + #1 + } + } + +\cs_new:Npn \__wheelchart_def_WClegend: + { + \int_set:Nn \l__wheelchart_legend_columns_int + { \fp_eval:n { ceil ( \WCtotalcount / ceil ( \WCtotalcount / ( \pgfkeysvalueof { / wheelchart / legend~columns } ) ) ) } } + \cs_set:Npn \WClegend {} + \tl_build_begin:N \WClegend + \int_compare:nNnTF { \l__wheelchart_legend_columns_int } = { 1 } + { \int_step_inline:nnn { 2 } { \WCtotalcount } { \__wheelchart_legend_append:nn {##1} { \\ } } } + { + \int_set:Nn \l__wheelchart_legend_rows_int + { \fp_eval:n { ceil ( \WCtotalcount / \l__wheelchart_legend_columns_int ) } } + \int_step_inline:nn { \l__wheelchart_legend_rows_int - 1 } + { + \int_step_inline:nn { \l__wheelchart_legend_columns_int - 2 } + { \__wheelchart_legend_append:nn { ##1 + \l__wheelchart_legend_rows_int * ####1 } { & } } + \int_compare:nNnF { ##1 + ( \l__wheelchart_legend_columns_int - 1 ) * \l__wheelchart_legend_rows_int } > { \WCtotalcount } + { + \__wheelchart_legend_append:nn + { ##1 + ( \l__wheelchart_legend_columns_int - 1 ) * \l__wheelchart_legend_rows_int } + { & } + } + \__wheelchart_legend_append:nn { ##1 + 1 } { \\ } + } + \int_step_inline:nn { \l__wheelchart_legend_columns_int - 2 } + { \__wheelchart_legend_append:nn { \l__wheelchart_legend_rows_int * ( ##1 + 1 ) } { & } } + \int_compare:nNnF { \l__wheelchart_legend_columns_int * \l__wheelchart_legend_rows_int } > { \WCtotalcount } + { \__wheelchart_legend_append:nn { \l__wheelchart_legend_columns_int * \l__wheelchart_legend_rows_int } { & } } + } + \__wheelchart_legend_append:nn { 1 } { \\ }%at the moment it is unnecessary to set g__wheelchart_WCcount_counter to 1 + %but this is done to be future-proof if the contents of \WClegend would be parsed in a way that prohibits the value for + %g__wheelchart_WCcount_counter to be larger than \WCtotalcount + \tl_build_end:N \WClegend + \cs_set:Npn \WCcount { \theg__wheelchart_WCcount_counter } + \cs_set:Npn \WCpercentage { \cs:w l__wheelchart_WCpercentage_\theg__wheelchart_WCcount_counter\cs_end: } + \cs_set:Npn \WCpercentagerounded { \cs:w l__wheelchart_WCpercentagerounded_\theg__wheelchart_WCcount_counter\cs_end: } + \str_if_eq:eeTF { \l__wheelchart_type_tl } { etoc } + { + \cs_set:Npn \WCetocthelinkedname + { \cs:w g__wheelchart_etoc_item_\l__wheelchart_etoc_name_tl _the_linked_name_\theg__wheelchart_WCcount_counter\cs_end: } + \cs_set:Npn \WCetocthelinkednumber + { \cs:w g__wheelchart_etoc_item_\l__wheelchart_etoc_name_tl _the_linked_number_\theg__wheelchart_WCcount_counter\cs_end: } + \cs_set:Npn \WCetocthelinkedpage + { \cs:w g__wheelchart_etoc_item_\l__wheelchart_etoc_name_tl _the_linked_page_\theg__wheelchart_WCcount_counter\cs_end: } + \cs_set:Npn \WCetocthename + { \cs:w g__wheelchart_etoc_item_\l__wheelchart_etoc_name_tl _the_name_\theg__wheelchart_WCcount_counter\cs_end: } + \cs_set:Npn \WCetocthenumber + { \cs:w g__wheelchart_etoc_item_\l__wheelchart_etoc_name_tl _the_number_\theg__wheelchart_WCcount_counter\cs_end: } + \cs_set:Npn \WCetocthepage + { \cs:w g__wheelchart_etoc_item_\l__wheelchart_etoc_name_tl _the_page_\theg__wheelchart_WCcount_counter\cs_end: } + \cs_set:Npn \WCetocthenumberofpages + { \cs:w g__wheelchart_etoc_item_\l__wheelchart_etoc_name_tl _the_number_of_pages_\theg__wheelchart_WCcount_counter\cs_end: } + } + { + \clist_if_empty:NTF \l__wheelchart_header_clist + { + \int_step_inline:nn { \seq_count:N \l__wheelchart_list_items_seq } + { + \cs_set:cpn { WCvar\int_to_Alph:n {##1} } + { \cs:w l__wheelchart_item_WCvar\int_to_Alph:n {##1}_\theg__wheelchart_WCcount_counter\cs_end: } + } + } + { + \int_step_inline:nn { \seq_count:N \l__wheelchart_list_items_seq } + { + \cs_set:cpn { \pgfkeysvalueof { / wheelchart / header~prefix } \clist_item:Nn \l__wheelchart_header_clist {##1} } + { + \cs:w + l__wheelchart_item_\pgfkeysvalueof { / wheelchart / header~prefix } + \clist_item:Nn \l__wheelchart_header_clist {##1}_\theg__wheelchart_WCcount_counter + \cs_end: + } + } + } + } + \setcounter { g__wheelchart_WCcount_counter } { 1 } + } + +\cs_new:Npn \__wheelchart_diff_atan:nnnn #1#2#3#4 + { + Mod + ( + \fp_eval:n + { + \g__wheelchart_slices_orientation_fp * + ( + atand + ( + \fp_use:c { l__wheelchart_#3_y_fp } - \fp_use:c { l__wheelchart_#4_y_fp } , + \fp_use:c { l__wheelchart_#3_x_fp } - \fp_use:c { l__wheelchart_#4_x_fp } + ) + - atand + ( + \fp_use:c { l__wheelchart_#1_y_fp } - \fp_use:c { l__wheelchart_#2_y_fp } , + \fp_use:c { l__wheelchart_#1_x_fp } - \fp_use:c { l__wheelchart_#2_x_fp } + ) + ) + } + , + 360 + )%note the Mod 360 because for example cos(90/2)\neq cos(-270/2) + } + +\cs_new:Npn \__wheelchart_discrete_algorithm: + { + \__wheelchart_def_macros:n { discrete~factor , gap~radius , samples } + \__wheelchart_def_macro:Nn \l__wheelchart_outer_radius_fp + { \pgfkeysvalueof { / wheelchart / outer~radius } - \fp_use:N \l__wheelchart_gap_radius_fp } + \bool_if:NTF \l__wheelchart_pie_bool + { \fp_set:Nn \l__wheelchart_inner_radius_fp { 0 } } + { + \__wheelchart_def_macro:Nn \l__wheelchart_inner_radius_fp + { \pgfkeysvalueof { / wheelchart / inner~radius } + \fp_use:N \l__wheelchart_gap_radius_fp } + } + \int_compare:nNnT { \l__wheelchart_discrete_space_at_borders_int } = { -1 } + { + \pgfkeys + { + / errors / boolean~expected /. expanded = + { discrete~space~at~borders } + { \pgfkeysvalueof { / wheelchart / discrete~space~at~borders } } + } + } + \seq_clear:N \l__wheelchart_discrete_points_seq + \bool_if:NTF \l__wheelchart_plot_bool + { + \fp_zero:N \l__wheelchart_discrete_outer_length_fp + \__wheelchart_discrete_def_coord:nn { outer } { 0 } + \int_step_inline:nn { \fp_use:N \l__wheelchart_samples_fp - 1 } + { + \__wheelchart_discrete_def_coord:nn { outer } {##1} + \fp_add:Nn \l__wheelchart_discrete_outer_length_fp + { + sqrt + ( + ( \g__wheelchart_x_coord_fp - \g__wheelchart_previous_x_coord_fp ) ^ 2 + + ( \g__wheelchart_y_coord_fp - \g__wheelchart_previous_y_coord_fp ) ^ 2 + ) + } + } + \__wheelchart_discrete_def_coord:nn { inner } { \l__wheelchart_samples_fp - 1 } + \fp_set:Nn \l__wheelchart_discrete_end_length_fp + { + sqrt + ( + ( \g__wheelchart_x_coord_fp - \g__wheelchart_previous_x_coord_fp ) ^ 2 + + ( \g__wheelchart_y_coord_fp - \g__wheelchart_previous_y_coord_fp ) ^ 2 + ) + } + \fp_zero:N \l__wheelchart_discrete_inner_length_fp + \int_step_inline:nnnn { \fp_use:N \l__wheelchart_samples_fp - 2 } { -1 } { 0 } + { + \__wheelchart_discrete_def_coord:nn { inner } {##1} + \fp_add:Nn \l__wheelchart_discrete_inner_length_fp + { + sqrt + ( + ( \g__wheelchart_x_coord_fp - \g__wheelchart_previous_x_coord_fp ) ^ 2 + + ( \g__wheelchart_y_coord_fp - \g__wheelchart_previous_y_coord_fp ) ^ 2 + ) + } + } + \__wheelchart_discrete_def_coord:nn { outer } { 0 } + \fp_set:Nn \l__wheelchart_discrete_start_length_fp + { + sqrt + ( + ( \g__wheelchart_x_coord_fp - \g__wheelchart_previous_x_coord_fp ) ^ 2 + + ( \g__wheelchart_y_coord_fp - \g__wheelchart_previous_y_coord_fp ) ^ 2 + ) + } + } + { + \fp_set:Nn \l__wheelchart_discrete_outer_length_fp + { abs ( \l__wheelchart_total_angle_fp * deg * \l__wheelchart_outer_radius_fp ) } + \fp_set:Nn \l__wheelchart_discrete_end_length_fp { abs ( \l__wheelchart_outer_radius_fp - \l__wheelchart_inner_radius_fp ) } + \fp_set:Nn \l__wheelchart_discrete_inner_length_fp + { abs ( \l__wheelchart_total_angle_fp * deg * \l__wheelchart_inner_radius_fp ) } + %note the abs ( ... ) because \l__wheelchart_total_angle_fp can be negative + %and \l__wheelchart_outer_radius_fp can be smaller than \l__wheelchart_inner_radius_fp + \fp_set_eq:NN \l__wheelchart_discrete_start_length_fp \l__wheelchart_discrete_end_length_fp + } + \str_case:enF { \pgfkeysvalueof { / wheelchart / discrete~partitioning } } + { + { radius } + { + \int_set:Nn \l__wheelchart_discrete_partitioning_first_index_int { 1 } + \int_set:Nn \l__wheelchart_discrete_partitioning_second_index_int { 2 } + \fp_set_eq:NN \l__wheelchart_discrete_level_start_length_fp \l__wheelchart_discrete_inner_length_fp + \fp_set_eq:NN \l__wheelchart_discrete_level_end_length_fp \l__wheelchart_discrete_outer_length_fp + \fp_set_eq:NN \l__wheelchart_discrete_sublevel_start_length_fp \l__wheelchart_discrete_start_length_fp + \fp_set_eq:NN \l__wheelchart_discrete_sublevel_end_length_fp \l__wheelchart_discrete_end_length_fp + } + { angle } + { + \int_set:Nn \l__wheelchart_discrete_partitioning_first_index_int { 2 } + \int_set:Nn \l__wheelchart_discrete_partitioning_second_index_int { 1 } + \fp_set_eq:NN \l__wheelchart_discrete_level_start_length_fp \l__wheelchart_discrete_start_length_fp + \fp_set_eq:NN \l__wheelchart_discrete_level_end_length_fp \l__wheelchart_discrete_end_length_fp + \fp_set_eq:NN \l__wheelchart_discrete_sublevel_start_length_fp \l__wheelchart_discrete_inner_length_fp + \fp_set_eq:NN \l__wheelchart_discrete_sublevel_end_length_fp \l__wheelchart_discrete_outer_length_fp + \int_set:Nn \l__wheelchart_discrete_sort_int { 3 - \l__wheelchart_discrete_sort_int } + } + } + { + \pgfkeys + { + / errors / unknown~choice~value /. expanded = + { discrete~partitioning } + { \pgfkeysvalueof { / wheelchart / discrete~partitioning } } + } + } + \int_set:Nn \l__wheelchart_discrete_levels_int + { + \fp_eval:n + { + max + ( + round + ( + sqrt + ( + ( + ( \l__wheelchart_discrete_sublevel_start_length_fp + \l__wheelchart_discrete_sublevel_end_length_fp ) + * \l__wheelchart_discrete_factor_fp + / ( \l__wheelchart_discrete_level_start_length_fp + \l__wheelchart_discrete_level_end_length_fp ) + ) + * \WCtotalnum + ) + ) + , + 1 + ) + } + } + \int_gzero:N \g__wheelchart_discrete_count_int + \fp_zero:N \l__wheelchart_discrete_levels_sum_fp + \int_step_inline:nn { \l__wheelchart_discrete_levels_int - 1 } + { + \fp_set:Nn \l__wheelchart_discrete_level_fp + { + ( ##1 - 0.5 * ( 1 + \l__wheelchart_discrete_space_at_borders_int ) ) + / ( \l__wheelchart_discrete_levels_int - \l__wheelchart_discrete_space_at_borders_int ) + } + \fp_add:Nn \l__wheelchart_discrete_levels_sum_fp { \l__wheelchart_discrete_level_fp } + \int_set:Nn \l__wheelchart_discrete_sublevels_int + { + \fp_eval:n + { + round + ( + ( + ( + ( ##1 ) * \l__wheelchart_discrete_level_start_length_fp + + \l__wheelchart_discrete_levels_sum_fp + * ( \l__wheelchart_discrete_level_end_length_fp - \l__wheelchart_discrete_level_start_length_fp ) + ) + / + ( + \l__wheelchart_discrete_levels_int * 0.5 + * ( \l__wheelchart_discrete_level_start_length_fp + \l__wheelchart_discrete_level_end_length_fp ) + ) + ) + * \WCtotalnum - \g__wheelchart_discrete_count_int + ) + } + } + \int_gadd:Nn \g__wheelchart_discrete_count_int { \l__wheelchart_discrete_sublevels_int } + \int_compare:nNnTF { \l__wheelchart_discrete_sublevels_int } = { 1 } + { + \seq_put_right:Ne \l__wheelchart_discrete_points_seq + { + 0.5 + / + \fp_use:N \l__wheelchart_discrete_level_fp + } + } + { + \int_step_inline:nn { \l__wheelchart_discrete_sublevels_int } + { + \seq_put_right:Ne \l__wheelchart_discrete_points_seq + { + \fp_eval:n + { + ( ####1 - 0.5 * ( 1 + \l__wheelchart_discrete_space_at_borders_int ) ) + / ( \l__wheelchart_discrete_sublevels_int - \l__wheelchart_discrete_space_at_borders_int ) + } + %the denominator is 0 if \l__wheelchart_discrete_sublevels_int = \l__wheelchart_discrete_space_at_borders_int = 1 + %thus the case when \l__wheelchart_discrete_sublevels_int = 1 is treated separately above + / + \fp_use:N \l__wheelchart_discrete_level_fp + } + } + } + } + \int_compare:nNnTF { \l__wheelchart_discrete_levels_int } = { 1 } + { \fp_set:Nn \l__wheelchart_discrete_level_fp { 0.5 } } + { + \fp_set:Nn \l__wheelchart_discrete_level_fp + { + 1 - 0.5 * ( 1 - \l__wheelchart_discrete_space_at_borders_int ) + / ( \l__wheelchart_discrete_levels_int - \l__wheelchart_discrete_space_at_borders_int ) + } + } + \int_set:Nn \l__wheelchart_discrete_sublevels_int { \fp_eval:n { round ( \WCtotalnum - \g__wheelchart_discrete_count_int ) } } + \int_compare:nNnTF { \l__wheelchart_discrete_sublevels_int } = { 1 } + { + \seq_put_right:Ne \l__wheelchart_discrete_points_seq + { + 0.5 + / + \fp_use:N \l__wheelchart_discrete_level_fp + } + } + { + \int_step_inline:nn { \l__wheelchart_discrete_sublevels_int } + { + \seq_put_right:Ne \l__wheelchart_discrete_points_seq + { + \fp_eval:n + { + ( ##1 - 0.5 * ( 1 + \l__wheelchart_discrete_space_at_borders_int ) ) + / ( \l__wheelchart_discrete_sublevels_int - \l__wheelchart_discrete_space_at_borders_int ) + } + / + \fp_use:N \l__wheelchart_discrete_level_fp + } + } + } + \seq_sort:Nn \l__wheelchart_discrete_points_seq + { + \seq_set_split:Nnn \l__wheelchart_discrete_coefficients_first_seq { / } {##1} + \seq_set_split:Nnn \l__wheelchart_discrete_coefficients_second_seq { / } {##2} + \fp_compare:nNnTF + { \seq_item:Nn \l__wheelchart_discrete_coefficients_first_seq { \l__wheelchart_discrete_sort_int } } + > + { \seq_item:Nn \l__wheelchart_discrete_coefficients_second_seq { \l__wheelchart_discrete_sort_int } } + { \sort_return_swapped: } + { \sort_return_same: } + } + \int_gzero:N \g__wheelchart_discrete_count_int + \__wheelchart_for_loop:n + { + \pgfkeysvalueof { / wheelchart / before~slices } + \int_step_inline:nn { \fp_eval:n { round ( \l__wheelchart_value_fp ) } }%note that \fp_eval:n { round ( ... ) } is necessary + %even when the value is an integer because if parse=pgfmath then .0 is added and then + %\int_step_inline:nn { \fp_use:N \l__wheelchart_value_fp } would give the messages + %Missing character: There is no . in font nullfont! Missing character: There is no 0 in font nullfont! + { + \int_gincr:N \g__wheelchart_discrete_count_int + \cs_set:Npe \WCcountdiscrete { \int_use:N \g__wheelchart_discrete_count_int } + \seq_set_split:Nne \l__wheelchart_discrete_coefficients_first_seq { / } + { \seq_item:Nn \l__wheelchart_discrete_points_seq { \g__wheelchart_discrete_count_int } } + %Naturally, an error occurs if the sum of the rounded values of the key value is + %greater than the rounded value of \WCtotalnum. + %For example if there are 2 values 1.6 and 1.7 then these numbers are 4 and 3 and then there is no 4-th item in the list. + %However only positive integer values make practical sense for this diagram. + \pic [ / wheelchart / slices_style ] at + ( + $ + ( + \__wheelchart_inner_plot:nn + { + \fp_eval:n + { + \l__wheelchart_start_angle_fp + \l__wheelchart_counter_or_clockwise_fp * \l__wheelchart_total_angle_fp * + ( + \seq_item:Nn \l__wheelchart_discrete_coefficients_first_seq + { \l__wheelchart_discrete_partitioning_first_index_int } + ) + } + } + { \fp_use:N \l__wheelchart_inner_radius_fp } + ) + ! + { + \seq_item:Nn \l__wheelchart_discrete_coefficients_first_seq + { \l__wheelchart_discrete_partitioning_second_index_int } + } + ! + ( + \__wheelchart_outer_plot:nn + { + \fp_eval:n + { + \l__wheelchart_start_angle_fp + \l__wheelchart_counter_or_clockwise_fp * \l__wheelchart_total_angle_fp * + ( + \seq_item:Nn \l__wheelchart_discrete_coefficients_first_seq + { \l__wheelchart_discrete_partitioning_first_index_int } + ) + } + } + { \fp_use:N \l__wheelchart_outer_radius_fp } + ) + $ + ) + { code = { \pgfkeysvalueof { / wheelchart / discrete~pic } } } ; + } + \pgfkeysvalueof { / wheelchart / after~slices } + } + } + +\cs_new:Npn \__wheelchart_discrete_def_coord:nn #1#2 + { + \fp_gset_eq:NN \g__wheelchart_previous_x_coord_fp \g__wheelchart_x_coord_fp + \fp_gset_eq:NN \g__wheelchart_previous_y_coord_fp \g__wheelchart_y_coord_fp + \__wheelchart_def_coord_aux:nn + {#1} + { + \fp_eval:n + { + \l__wheelchart_start_angle_fp + ( ( #2 ) / ( \l__wheelchart_samples_fp - 1 ) ) + * \l__wheelchart_counter_or_clockwise_fp * \l__wheelchart_total_angle_fp + } + } + } + +\cs_new:Npn \__wheelchart_for_loop:n #1 + { + \fp_gset_eq:NN \g__wheelchart_angle_fp \l__wheelchart_start_angle_fp + \__wheelchart_for_loop_initial:n + { + \__wheelchart_def_slice_keys:n + { + \fp_set_eq:Nc \l__wheelchart_value_fp { l__wheelchart_value_\WCcount _fp } + \cs_set_eq:Nc \WCpercentage { l__wheelchart_WCpercentage_\WCcount } + \cs_set_eq:Nc \WCpercentagerounded { l__wheelchart_WCpercentagerounded_\WCcount } + \fp_gset:Nn \g__wheelchart_new_angle_fp + { + \WCcount == \WCtotalcount + ? + \l__wheelchart_start_angle_fp + \l__wheelchart_counter_or_clockwise_fp * \l__wheelchart_total_angle_fp + : + \g__wheelchart_angle_fp + + ( + \l__wheelchart_counter_or_clockwise_fp * \l__wheelchart_value_fp + * ( \l__wheelchart_total_angle_fp / \WCtotalnum ) + ) + } + \__wheelchart_def_macros:n + { + data~angle~pos , + gap , + gap~max~angle , + gap~polar , + gap~radius , + samples , + slices~inner~end~angle~shift , + slices~inner~start~angle~shift , + slices~outer~end~angle~shift , + slices~outer~start~angle~shift + } + \__wheelchart_def_macro:Nn \l__wheelchart_outer_radius_fp + { \pgfkeysvalueof { / wheelchart / outer~radius } - \fp_use:N \l__wheelchart_gap_radius_fp } + \bool_if:NTF \l__wheelchart_pie_bool + { \fp_set:Nn \l__wheelchart_inner_radius_fp { 0 } } + { + \__wheelchart_def_macro:Nn \l__wheelchart_inner_radius_fp + { \pgfkeysvalueof { / wheelchart / inner~radius } + \fp_use:N \l__wheelchart_gap_radius_fp } + } + \fp_set_eq:NN \l__wheelchart_inner_radius_orig_fp \l__wheelchart_inner_radius_fp + \fp_set:Nn \l__wheelchart_abs_half_angle_minus_new_angle_fp + { abs ( \g__wheelchart_angle_fp - \g__wheelchart_new_angle_fp ) / 2 } + \fp_set:Nn \l__wheelchart_abs_half_angle_minus_new_angle_minus_gap_polar_fp + { \l__wheelchart_abs_half_angle_minus_new_angle_fp - \l__wheelchart_gap_polar_fp } + \bool_if:NTF \l__wheelchart_plot_bool + { + \fp_set_eq:NN \l__wheelchart_outer_gap_fp \l__wheelchart_gap_polar_fp + \fp_set_eq:NN \l__wheelchart_inner_gap_fp \l__wheelchart_gap_polar_fp + } + { + \fp_set:Nn \l__wheelchart_gap_max_angle_def_fp + { + \l__wheelchart_inner_radius_fp > 0 + ? + 90 + : + ( + sind ( \l__wheelchart_abs_half_angle_minus_new_angle_minus_gap_polar_fp ) < 0.001 + ? + ( + 90 < \l__wheelchart_gap_max_angle_fp && \l__wheelchart_gap_max_angle_fp < 180 + ? + \l__wheelchart_gap_max_angle_fp + : + 90 + ) + : + ( + \l__wheelchart_gap_max_angle_fp < 90 || \l__wheelchart_gap_max_angle_fp > 180 + ? + 180 + : + \l__wheelchart_gap_max_angle_fp + ) + ) + } + \__wheelchart_def_gap:NN \l__wheelchart_outer_gap_fp \l__wheelchart_outer_radius_fp + \__wheelchart_def_gap:NN \l__wheelchart_inner_gap_fp \l__wheelchart_inner_radius_fp + \fp_compare:nNnT { \l__wheelchart_abs_half_angle_minus_new_angle_minus_gap_polar_fp } > { 0.01 } + { + \fp_set:Nn \l__wheelchart_inner_radius_fp + { + max + ( + \l__wheelchart_gap_fp + / sind + ( + min + ( + \l__wheelchart_abs_half_angle_minus_new_angle_minus_gap_polar_fp , + \l__wheelchart_gap_max_angle_def_fp + ) + ) + , + \l__wheelchart_inner_radius_fp + ) + } + } + } + \__wheelchart_def_slice_angle:nnnn { inner } { end } { new_ } { -1 } + \__wheelchart_def_slice_angle:nnnn { inner } { start } {} { 1 } + \__wheelchart_def_slice_angle:nnnn { outer } { end } { new_ } { -1 } + \__wheelchart_def_slice_angle:nnnn { outer } { start } {} { 1 } + \__wheelchart_def_angle:nnnN { 0.5 } { 0 } { 0 } \WCmidangle + \__wheelchart_def_macros:n { data~angle~shift , data~sep } + \__wheelchart_def_angle:nnnN + { \l__wheelchart_data_angle_pos_fp } + { \l__wheelchart_data_angle_shift_fp } + { \l__wheelchart_data_sep_fp } + \WCdataangle + \__wheelchart_def_macros:n { explode } + \pgfkeysvalueof { / wheelchart / for~loop~start }%this must be placed after the definition of macros such as \WCpercentage + %such that these macros can be used in the key for loop start + \begin { scope } + [ shift = { ( \WCmidangle \c_colon_str \fp_use:N \l__wheelchart_explode_fp ) } , / wheelchart / slices_scope ] + #1 + \end { scope } + \fp_gset_eq:NN \g__wheelchart_angle_fp \g__wheelchart_new_angle_fp + \pgfkeysvalueof { / wheelchart / for~loop~end } + } + } + } + +\cs_new:Npn \__wheelchart_for_loop_initial:n #1 + { + \str_case:en { \l__wheelchart_type_tl } + { + { default } + { + \clist_if_empty:NTF \l__wheelchart_header_clist + { + \int_step_inline:nn { \WCtotalcount } + { + \cs_set:Npe \WCcount {##1} + \int_step_inline:nn { \seq_count:N \l__wheelchart_list_items_seq } + { \cs_set_eq:cc { WCvar\int_to_Alph:n {####1} } { l__wheelchart_item_WCvar\int_to_Alph:n {####1}_##1 } } + #1 + } + } + { + \int_step_inline:nn { \WCtotalcount } + { + \cs_set:Npe \WCcount {##1} + \int_step_inline:nn { \seq_count:N \l__wheelchart_list_items_seq } + { + \cs_set_eq:cc + { \pgfkeysvalueof { / wheelchart / header~prefix } \clist_item:Nn \l__wheelchart_header_clist {####1} } + { + l__wheelchart_item_\pgfkeysvalueof { / wheelchart / header~prefix } + \clist_item:Nn \l__wheelchart_header_clist {####1}_##1 + } + } + #1 + } + } + } + { totalcount } + { + \int_step_inline:nn { \WCtotalcount } + { + \cs_set:Npe \WCcount {##1} + #1 + } + } + { etoc } + { + \int_step_inline:nn { \WCtotalcount } + { + \cs_set:Npe \WCcount {##1} + \cs_set_eq:Nc \WCetocthelinkedname { g__wheelchart_etoc_item_\l__wheelchart_etoc_name_tl _the_linked_name_##1 } + \cs_set_eq:Nc \WCetocthelinkednumber { g__wheelchart_etoc_item_\l__wheelchart_etoc_name_tl _the_linked_number_##1 } + \cs_set_eq:Nc \WCetocthelinkedpage { g__wheelchart_etoc_item_\l__wheelchart_etoc_name_tl _the_linked_page_##1 } + \cs_set_eq:Nc \WCetocthename { g__wheelchart_etoc_item_\l__wheelchart_etoc_name_tl _the_name_##1 } + \cs_set_eq:Nc \WCetocthenumber { g__wheelchart_etoc_item_\l__wheelchart_etoc_name_tl _the_number_##1 } + \cs_set_eq:Nc \WCetocthepage { g__wheelchart_etoc_item_\l__wheelchart_etoc_name_tl _the_page_##1 } + \cs_set_eq:Nc \WCetocthenumberofpages { g__wheelchart_etoc_item_\l__wheelchart_etoc_name_tl _the_number_of_pages_##1 } + #1 + } + } + } + } + +\cs_new:Npn \__wheelchart_if_text:nn #1#2 + { + %https://tex.stackexchange.com/questions/42280/expand-away-empty-macros-within-ifthenelse + %https://tex.stackexchange.com/questions/44919/proper-way-to-detect-empty-blank-text + \begin { pgfinterruptpicture } + %https://tex.stackexchange.com/questions/459853/savebox-within-tikzpicture-results-in-an-empty-savebox + \hbox_gset:Nn \g__wheelchart_if_text_box { \pgfkeysvalueof { / wheelchart / #1 } } + \end { pgfinterruptpicture } + \dim_compare:nNnT { \box_wd:N \g__wheelchart_if_text_box } > { 0 pt } + { {#2} } + } + +\cs_new:Npn \__wheelchart_initial:n #1 + { + \str_case:en { \l__wheelchart_type_tl } + { + { default } + { + \tl_if_empty:nTF {#1} + { \cs_set:Npn \WCtotalcount { 0 } } + { + \use:c { seq_set_split:Ne\l__wheelchart_expand_list_tl } + \l__wheelchart_list_seq + { \pgfkeysvalueof { / wheelchart / separator~rows } } + {#1} + \cs_set:Npe \WCtotalcount { \seq_count:N \l__wheelchart_list_seq } + \seq_map_indexed_inline:Nn \l__wheelchart_list_seq + { + \use:c { seq_set_split:Ne\l__wheelchart_expand_list_items_tl } + \l__wheelchart_list_items_seq + { \pgfkeysvalueof { / wheelchart / separator~columns } } + {##2} + %make sure that the namespace l__wheelchart_item_ below is unique + \clist_if_empty:NTF \l__wheelchart_header_clist + { + \seq_map_indexed_inline:Nn \l__wheelchart_list_items_seq + { \cs_set:cpn { l__wheelchart_item_WCvar\int_to_Alph:n {####1}_##1 } {####2} } + } + { + \seq_map_indexed_inline:Nn \l__wheelchart_list_items_seq + { + \cs_set:cpn + { + l__wheelchart_item_\pgfkeysvalueof { / wheelchart / header~prefix } + \clist_item:Nn \l__wheelchart_header_clist {####1}_##1 + } + {####2} + } + } + } + } + } + { totalcount } + { + \cs_set:Npe \WCtotalcount { \fp_use:N \l__wheelchart_total_count_fp } + \cs_set:Npn \WCvarA { 1 } + \cs_set:Npn \WCvarB {} + \cs_set:Npn \WCvarC {} + } + { etoc } + { + \bool_if:NTF \l__wheelchart_etoc_use_name_bool + { + \int_if_exist:cTF { g__wheelchart_etoc_item_\l__wheelchart_etoc_name_tl _count_int } + { \cs_set:Npe \WCtotalcount { \int_use:c { g__wheelchart_etoc_item_\l__wheelchart_etoc_name_tl _count_int } } } + { \cs_set:Npn \WCtotalcount { 0 } } + } + { + \@ifpackageloaded { etoc } {} + { \PackageError { wheelchart } { The~package~etoc~must~be~loaded~to~use~the~key~etoc~level } {} } + \etocsetlevel { part } { 0 } + \etocsetlevel { chapter } { 0 } + \etocsetlevel { section } { 0 } + \etocsetlevel { subsection } { 0 } + \etocsetlevel { subsubsection } { 0 } + \etocsetlevel { paragraph } { 0 } + \etocsetlevel { subparagraph } { 0 } + \etocsetlevel { \l__wheelchart_etoc_level_tl } { -1 }%these level changes are local to the current group + \etocsetnexttocdepth { -1 }%only for the next toc + \etocsetstyle { \l__wheelchart_etoc_level_tl } {} {} + { + \int_compare:nNnT { \int_use:c { g__wheelchart_etoc_item_\l__wheelchart_etoc_name_tl _count_int } } > { 0 } + { + \cs_gset:cpe + { + g__wheelchart_etoc_item_\l__wheelchart_etoc_name_tl + _the_number_of_pages_\int_use:c { g__wheelchart_etoc_item_\l__wheelchart_etoc_name_tl _count_int } + } + { + \int_eval:n + { + \etocthepage - + \cs:w + g__wheelchart_etoc_item_\l__wheelchart_etoc_name_tl + _the_page_\int_use:c { g__wheelchart_etoc_item_\l__wheelchart_etoc_name_tl _count_int } + \cs_end: + } + } + } + \int_gincr:c { g__wheelchart_etoc_item_\l__wheelchart_etoc_name_tl _count_int } + \cs_gset_eq:cN + { + g__wheelchart_etoc_item_\l__wheelchart_etoc_name_tl + _the_linked_name_\int_use:c { g__wheelchart_etoc_item_\l__wheelchart_etoc_name_tl _count_int } + } + \etocthelinkedname + \cs_gset_eq:cN + { + g__wheelchart_etoc_item_\l__wheelchart_etoc_name_tl + _the_linked_number_\int_use:c { g__wheelchart_etoc_item_\l__wheelchart_etoc_name_tl _count_int } + } + \etocthelinkednumber + \cs_gset_eq:cN + { + g__wheelchart_etoc_item_\l__wheelchart_etoc_name_tl + _the_linked_page_\int_use:c { g__wheelchart_etoc_item_\l__wheelchart_etoc_name_tl _count_int } + } + \etocthelinkedpage + \cs_gset_eq:cN + { + g__wheelchart_etoc_item_\l__wheelchart_etoc_name_tl + _the_name_\int_use:c { g__wheelchart_etoc_item_\l__wheelchart_etoc_name_tl _count_int } + } + \etocthename + \cs_gset_eq:cN + { + g__wheelchart_etoc_item_\l__wheelchart_etoc_name_tl + _the_number_\int_use:c { g__wheelchart_etoc_item_\l__wheelchart_etoc_name_tl _count_int } + } + \etocthenumber + \cs_gset_eq:cN + { + g__wheelchart_etoc_item_\l__wheelchart_etoc_name_tl + _the_page_\int_use:c { g__wheelchart_etoc_item_\l__wheelchart_etoc_name_tl _count_int } + } + \etocthepage + } + {} + \int_gzero_new:c { g__wheelchart_etoc_item_\l__wheelchart_etoc_name_tl _count_int } + \pgfkeysvalueof { / wheelchart / etoc~code } + \int_compare:nNnT { \int_use:c { g__wheelchart_etoc_item_\l__wheelchart_etoc_name_tl _count_int } } > { 0 } + { + \cs_gset:cpe + { + g__wheelchart_etoc_item_\l__wheelchart_etoc_name_tl + _the_number_of_pages_\int_use:c { g__wheelchart_etoc_item_\l__wheelchart_etoc_name_tl _count_int } + } + { + \int_eval:n + { + \l__wheelchart_etoc_count_total_pages_int + 1 - + \cs:w + g__wheelchart_etoc_item_\l__wheelchart_etoc_name_tl + _the_page_\int_use:c { g__wheelchart_etoc_item_\l__wheelchart_etoc_name_tl _count_int } + \cs_end: + } + } + } + \cs_set:Npe \WCtotalcount { \int_use:c { g__wheelchart_etoc_item_\l__wheelchart_etoc_name_tl _count_int } } + } + } + } + \cs_set:Npn \WCtotalnum { 0 } + \__wheelchart_for_loop_initial:n + { + \__wheelchart_def_slice_keys:n + { + \__wheelchart_def_macros:n { value } + \fp_gset_eq:NN \g__wheelchart_value_global_fp \l__wheelchart_value_fp + } + \fp_zero_new:c { l__wheelchart_value_\WCcount _fp } + \fp_set_eq:cN { l__wheelchart_value_\WCcount _fp } \g__wheelchart_value_global_fp + \cs_set:Npe \WCtotalnum { \fp_eval:n { \WCtotalnum + \g__wheelchart_value_global_fp } } + } + \int_step_inline:nn { \WCtotalcount } + { + \cs_set:cpe { l__wheelchart_WCpercentage_##1 } + { \fp_eval:n { \fp_use:c { l__wheelchart_value_##1_fp } / ( \WCtotalnum / 100 ) } } + \cs_set:cpe { l__wheelchart_WCpercentagerounded_##1 } + { \fp_eval:n { round ( \cs:w l__wheelchart_WCpercentage_##1\cs_end: , \pgfkeysvalueof { / wheelchart / perc~precision } ) } } + } + } + +\cs_new:Npn \__wheelchart_inner_plot:nn #1#2 + { {#1} \c_colon_str {#2} } + +\cs_new:Npn \__wheelchart_legend_append:nn #1#2 + { + \tl_build_put_right:NV \WClegend \l__wheelchart_legend_row_tl%note the V specifier such that \WClegend can also be combined + %with an S column of the package siunitx and such that \WClegend can be used in a tblr environment of the package tabularray + %and then the option expand=\WClegend needs to be given to the tblr environment + \tl_build_put_right:Nn \WClegend { \protect \setcounter { g__wheelchart_WCcount_counter } }%note the \protect for in case that + %\WClegend would be parsed in a particular way + %note that the counter g__wheelchart_WCcount_counter is defined globally and at the end of the previous \l__wheelchart_legend_row_tl + %such that this value is defined and has the right value at the start of the next \l__wheelchart_legend_row_tl + %if \WClegend is used in a tblr environment of the package tabularray then \UseTblrLibrary{counter} is required + \tl_build_put_right:Ne \WClegend { { \int_eval:n {#1} } } + \tl_build_put_right:Nn \WClegend {#2} + } + +\cs_new:Npn \__wheelchart_outer_plot:nn #1#2 + { {#1} \c_colon_str {#2} } + +\cs_new:Npn \__wheelchart_slices_arc:nnnnnn #1#2#3#4#5#6 + { + { + [ + / utils / exec = + { + \__wheelchart_def_macro:Nn \l__wheelchart_slices_arc_A_fp {#1} + #6 + \fp_set:Nn \l__wheelchart_slices_arc_A_abs_fp { abs ( \l__wheelchart_slices_arc_A_fp ) } + \fp_compare:nNnF { \l__wheelchart_slices_arc_A_abs_fp } < { 0.01 } + { + \__wheelchart_def_macro:Nn \l__wheelchart_slices_arc_B_fp {#2} + \fp_set:Nn \l__wheelchart_slices_arc_rotate_fp + { + atand + ( + \fp_use:c { l__wheelchart_#3_y_fp } - \fp_use:c { l__wheelchart_#4_y_fp } , + \fp_use:c { l__wheelchart_#3_x_fp } - \fp_use:c { l__wheelchart_#4_x_fp } + ) + } + \fp_set:Nn \l__wheelchart_slices_arc_coord_fp + { + \l__wheelchart_slices_arc_A_fp < 0 && \l__wheelchart_slices_arc_B_fp < 0 + ? + 0 + : + \l__wheelchart_slices_arc_B_fp + } + \fp_set:Nn \l__wheelchart_slices_arc_angle_fp + { + \l__wheelchart_slices_arc_A_fp < 0 && \l__wheelchart_slices_arc_B_fp < 0 + ? + acosd + ( + 2 / + ( + ( min ( \l__wheelchart_slices_arc_B_fp , 0 ) - 1 ) + * ( ( 1 / \l__wheelchart_slices_arc_A_fp ) + \l__wheelchart_slices_arc_A_fp ) + ) + ) + : + atand ( ( \l__wheelchart_slices_arc_A_fp - ( 1 / \l__wheelchart_slices_arc_A_fp ) ) / 2 ) + }%note the min ( \l__wheelchart_slices_arc_B_fp , 0 ) such that the acosd is always defined + } + } + ] + \fp_compare:nNnTF { \l__wheelchart_slices_arc_A_abs_fp } < { 0.01 } + {#5} + { + \fp_compare:nNnT { \l__wheelchart_slices_arc_B_fp } < { 1 } + { + \fp_compare:nNnF { \l__wheelchart_slices_arc_coord_fp } = { 0 } + { + -- + ( + $ + ( \fp_use:c { l__wheelchart_#3_x_fp } , \fp_use:c { l__wheelchart_#3_y_fp } ) + ! { \fp_eval:n { \l__wheelchart_slices_arc_coord_fp / 2 } } ! + ( \fp_use:c { l__wheelchart_#4_x_fp } , \fp_use:c { l__wheelchart_#4_y_fp } ) + $ + ) + } + arc + [ + start~angle = + { + \fp_eval:n + { + \l__wheelchart_slices_arc_rotate_fp + - \g__wheelchart_slices_orientation_fp * \l__wheelchart_slices_arc_angle_fp + } + } , + end~angle = + { + \fp_eval:n + { + \l__wheelchart_slices_arc_rotate_fp + \g__wheelchart_slices_orientation_fp * + ( sign ( \l__wheelchart_slices_arc_A_fp ) * 180 + \l__wheelchart_slices_arc_angle_fp ) + } + } , + radius = + { + \fp_eval:n + { + 0.25 * ( 1 - \l__wheelchart_slices_arc_B_fp ) + * abs ( ( 1 / \l__wheelchart_slices_arc_A_fp ) + \l__wheelchart_slices_arc_A_fp ) + * sqrt + ( + ( \fp_use:c { l__wheelchart_#3_x_fp } - \fp_use:c { l__wheelchart_#4_x_fp } ) ^ 2 + + ( \fp_use:c { l__wheelchart_#3_y_fp } - \fp_use:c { l__wheelchart_#4_y_fp } ) ^ 2 + ) + } + } + ] + } + \fp_compare:nNnF { \l__wheelchart_slices_arc_coord_fp } = { 0 } + {#5} + } + } + } + +\cs_new:Npn \__wheelchart_slices_arrow:nnnnn #1#2#3#4#5 + { + { + [ + / utils / exec = + { + \__wheelchart_def_macro:Nn \l__wheelchart_slices_arrow_A_fp {#1} + \fp_compare:nNnF { \l__wheelchart_slices_arrow_A_fp } = { 0 } + { + \__wheelchart_def_macro:Nn \l__wheelchart_slices_arrow_B_fp {#2} + \fp_set:Nn \l__wheelchart_slices_arrow_coord_fp + { + \l__wheelchart_slices_arrow_A_fp < 0 && \l__wheelchart_slices_arrow_B_fp < 0 ? 0 : \l__wheelchart_slices_arrow_B_fp + } + } + } + ] + \fp_compare:nNnTF { \l__wheelchart_slices_arrow_A_fp } = { 0 } + {#5} + { + \fp_compare:nNnT { \l__wheelchart_slices_arrow_B_fp } < { 1 } + { + \fp_compare:nNnF { \l__wheelchart_slices_arrow_coord_fp } = { 0 } + { + -- + ( + $ + ( \fp_use:c { l__wheelchart_#3_x_fp } , \fp_use:c { l__wheelchart_#3_y_fp } ) + ! { \fp_eval:n { \l__wheelchart_slices_arrow_coord_fp / 2 } } ! + ( \fp_use:c { l__wheelchart_#4_x_fp } , \fp_use:c { l__wheelchart_#4_y_fp } ) + $ + ) + } + -- + ( + \fp_eval:n + { + ( + \fp_use:c { l__wheelchart_#3_x_fp } + \fp_use:c { l__wheelchart_#4_x_fp } + + ( + \g__wheelchart_slices_orientation_fp * ( \l__wheelchart_slices_arrow_coord_fp - 1 ) + * \l__wheelchart_slices_arrow_A_fp + * ( \fp_use:c { l__wheelchart_#3_y_fp } - \fp_use:c { l__wheelchart_#4_y_fp } ) + ) + ) + / 2 + } + , + \fp_eval:n + { + ( + \fp_use:c { l__wheelchart_#3_y_fp } + \fp_use:c { l__wheelchart_#4_y_fp } + + ( + \g__wheelchart_slices_orientation_fp * ( \l__wheelchart_slices_arrow_coord_fp - 1 ) + * \l__wheelchart_slices_arrow_A_fp + * ( \fp_use:c { l__wheelchart_#4_x_fp } - \fp_use:c { l__wheelchart_#3_x_fp } ) + ) + ) + / 2 + } + ) + \fp_compare:nNnF { \l__wheelchart_slices_arrow_coord_fp } = { 0 } + { + -- + ( + $ + ( \fp_use:c { l__wheelchart_#4_x_fp } , \fp_use:c { l__wheelchart_#4_y_fp } ) + ! { \fp_eval:n { \l__wheelchart_slices_arrow_coord_fp / 2 } } ! + ( \fp_use:c { l__wheelchart_#3_x_fp } , \fp_use:c { l__wheelchart_#3_y_fp } ) + $ + ) + } + } + #5 + } + } + } + +\cs_new:Npn \__wheelchart_slices_to:nn #1#2 + { + to + [ + out = { \fp_eval:n { - \g__wheelchart_slices_orientation_fp * sign ( \l__wheelchart_coord_determinant_fp ) * (#1) } } , + in = { \fp_eval:n { \g__wheelchart_slices_orientation_fp * sign ( \l__wheelchart_coord_determinant_fp ) * ( (#2) - 180 ) } } , + relative + ] + } + +\cs_new:Npn \__wheelchart_space_to_underscore:n #1 + { \str_if_eq:nnTF {#1} { ~ } { _ } {#1} } + +%%> \subsection{Pgfkeys} + +\pgfkeys + { + / wheelchart /. is~family , + / wheelchart , + after~slices /. initial = {} , + anchor~xsep /. initial = 5 , + anchor~ysep /. initial = 5 , + arc /. style = + { + bool_set_true = \l__wheelchart_arc_bool , + arc_style /. style = {#1} + } , + arc_style /. style = {} , + arc~around~text /. default = true ,%this key is not set up with /.is choice or \bool_set:Nn + %such that for example \WCvarA can be used as value for this key + arc~around~text /. initial = false , + arc~data /. initial = {} , + arc~data~align /. code = { \tl_set:Nn \l__wheelchart_arc_data_align_tl {#1} } ,%this key is not set up with /.is choice + %such that for example \WCvarA can be used as value for this key + arc~data~align = center , + arc~data~angle~pos /. initial = 0.5 , + arc~data~angle~shift /. initial = 0 , + arc~data~dir /. initial = 1 , + arc~data~pos /. initial = 1 , + arc~data~sep /. initial = 1 ex / 1 cm , + arc~data~style /. style = { arc_data_style /. style = {#1} } , + arc_data_style /. style = {} , + arc~first~half /. style = { arc_first_half /. style = {#1} } , + arc_first_half /. style = {} , + arc~pos /. initial = 1 , + arc~second~half /. style = { arc_second_half /. style = {#1} } , + arc_second_half /. style = {} , + arc~sep /. initial = 1 ex / 1 cm , + at /. initial = { ( 0 , 0 ) } , + before~slices /. initial = {} , + bool_set_true /. code = { \bool_set_true:N #1 } , + caption /. initial = {} , + caption~left /. initial = {} , + caption~left~sep /. initial = 0.5 , + caption~left~style /. style = { caption~left_style /. style = {#1} } , + caption~left_style /. style = {} , + caption~sep /. initial = 0.5 , + caption~style /. style = { caption_style /. style = {#1} } , + caption_style /. style = {} , + contour /. style = + { + bool_set_true = \l__wheelchart_contour_bool , + contour_style /. style = {#1} + } , + contour_style /. style = {} , + counterclockwise /. is~choice , + counterclockwise / false /. code = { \fp_set:Nn \l__wheelchart_counter_or_clockwise_fp { -1 } } , + counterclockwise / false /. value~forbidden , + counterclockwise / true /. code = { \fp_set:Nn \l__wheelchart_counter_or_clockwise_fp { 1 } } , + counterclockwise / true /. value~forbidden , + counterclockwise /. default = true , + counterclockwise = false , + data /. initial = { \WCvarC } , + data~angle~pos /. initial = 0.5 , + data~angle~shift /. initial = 0 , + data~pos /. initial = 1 , + data~sep /. initial = 0.2 , + data~style /. style = { data_style /. style = {#1} } , + data_style /. style = {} , + discrete /. is~choice , + discrete / false /. code = { \bool_set_false:N \l__wheelchart_discrete_bool } , + discrete / false /. value~forbidden , + discrete / true /. code = { \bool_set_true:N \l__wheelchart_discrete_bool } , + discrete / true /. value~forbidden , + discrete /. default = true , + discrete = false , + discrete~factor /. initial = 1 , + discrete~partitioning /. initial = radius , + discrete~pic /. initial = {} , + discrete~sort /. is~choice , + discrete~sort / angle /. code = { \int_set:Nn \l__wheelchart_discrete_sort_int { 1 } } , + discrete~sort / angle /. value~forbidden , + discrete~sort / radius /. code = { \int_set:Nn \l__wheelchart_discrete_sort_int { 2 } } , + discrete~sort / radius /. value~forbidden , + discrete~sort = angle , + discrete~space~at~borders /. is~choice ,%this key is not set up with /.is if because an initial value is unwanted for this key + discrete~space~at~borders / false /. code = { \int_set:Nn \l__wheelchart_discrete_space_at_borders_int { 1 } } , + discrete~space~at~borders / false /. value~forbidden , + discrete~space~at~borders / true /. code = { \int_set:Nn \l__wheelchart_discrete_space_at_borders_int { 0 } } , + discrete~space~at~borders / true /. value~forbidden , + discrete~space~at~borders /. default = true , + domain /. style~args /. expanded = { ##1 \c_colon_str ##2 } + { + counterclockwise , + start~angle = {##1} , + total~angle = { (##2) - (##1) } + } , + etoc~code /. initial = { \tableofcontents } , + etoc~count~total~pages /. code = { \int_set:Nn \l__wheelchart_etoc_count_total_pages_int {#1} } , + etoc~level /. code = + { + \tl_set:Nn \l__wheelchart_type_tl { etoc } + \tl_set:Nn \l__wheelchart_etoc_level_tl {#1} + } , + etoc~name /. code = { \tl_set:Nn \l__wheelchart_etoc_name_tl {#1} } , + etoc~name = , + etoc~use~name /. code = + { + \tl_set:Nn \l__wheelchart_etoc_name_tl {#1} + \tl_set:Nn \l__wheelchart_type_tl { etoc } + \bool_set_true:N \l__wheelchart_etoc_use_name_bool + } , + expand~list /. is~choice , + expand~list / false /. code = { \tl_set:Nn \l__wheelchart_expand_list_tl { n } } , + expand~list / false /. value~forbidden , + expand~list / once /. code = { \tl_set:Nn \l__wheelchart_expand_list_tl { o } } , + expand~list / once /. value~forbidden , + expand~list / true /. code = { \tl_set:Nn \l__wheelchart_expand_list_tl { e } } , + expand~list / true /. value~forbidden , + expand~list = once , + expand~list~items /. is~choice , + expand~list~items / false /. code = { \tl_set:Nn \l__wheelchart_expand_list_items_tl { n } } , + expand~list~items / false /. value~forbidden , + expand~list~items / once /. code = { \tl_set:Nn \l__wheelchart_expand_list_items_tl { o } } , + expand~list~items / once /. value~forbidden , + expand~list~items / true /. code = { \tl_set:Nn \l__wheelchart_expand_list_items_tl { e } } , + expand~list~items / true /. value~forbidden , + expand~list~items = false , + explode /. initial = 0 , + explode /. default = 0.2 , + for~loop~end /. initial = {} , + for~loop~start /. initial = {} , + gap /. initial = 0 , + gap /. default = 0.05 , + gap~max~angle /. initial = 180 , + gap~polar /. initial = 0 , + gap~polar /. default = 1 , + gap~radius /. initial = 0 , + gap~radius /. default = 0.05 ,%the same default value as for gap + header /. code = { \clist_set:Nn \l__wheelchart_header_clist {#1} } , + header~prefix /. initial = WC , + inner~data /. initial = {} , + inner~data~angle~pos /. initial = 0.5 , + inner~data~angle~shift /. initial = 0 , + inner~data~pos /. initial = 0 , + inner~data~sep /. initial = 0.2 , + inner~data~style /. style = { inner_data_style /. style = {#1} } , + inner_data_style /. style = {} , + inner~plot /. code = + { + \bool_set_true:N \l__wheelchart_plot_bool + \cs_set:Npn \__wheelchart_inner_plot:nn ##1##2 {#1} + \tl_set:Nn \l__wheelchart_slices_inner_tl + { + -- plot + [ + domain = + \fp_use:N \l__wheelchart_slice_inner_end_angle_fp + \c_colon_str + \fp_use:N \l__wheelchart_slice_inner_start_angle_fp , + samples = \fp_use:N \l__wheelchart_samples_fp , + variable = \l__wheelchart_inner_plot_variable_fp , + / wheelchart / inner_plot_style + ] + ( \__wheelchart_inner_plot:nn { \l__wheelchart_inner_plot_variable_fp } { \fp_use:N \l__wheelchart_inner_radius_fp } ) + } + } , + inner~plot~style /. style = { inner_plot_style /. style = {#1} } , + inner_plot_style /. style = {} , + inner~radius /. initial = 2 , + legend /. initial = {} , + legend~columns /. initial = 1 , + legend~entry /. initial = {} , + legend~only /. code = { \bool_set:Nn \l__wheelchart_legend_only_bool { \cs:w c_#1_bool\cs_end: } } , + legend~only /. default = true , + legend~only = false , + legend~row /. code = + { + \bool_set_true:N \l__wheelchart_legend_row_bool + \tl_set:Nn \l__wheelchart_legend_row_tl {#1} + } , + lines /. initial = 0 , + lines /. default = 1 , + lines~angle~pos /. initial = 0.5 , + lines~angle~shift /. initial = 0 , + lines~ext /. initial = 0 , + lines~ext /. default = 0.5 , + lines~ext~bottom~dir /. code = { \int_set_eq:Nc \l__wheelchart_lines_ext_bottom_dir_int { c__wheelchart_lines_ext_dir_#1_int } } , + lines~ext~bottom~dir = right , + lines~ext~dir /. code = + { + \bool_set_true:N \l__wheelchart_lines_ext_dir_bool + \int_set_eq:Nc \l__wheelchart_lines_ext_dir_int { c__wheelchart_lines_ext_dir_#1_int } + } , + lines~ext~dirsep /. initial = 0 , + lines~ext~fixed /. default = true ,%this key is not set up with /.is choice or \bool_set:Nn + %such that for example \WCvarA can be used as value for this key + lines~ext~fixed /. initial = false , + lines~ext~fixed~left /. initial = + { + \fp_eval:n + { + \l__wheelchart_lines_ext_dir_int + * ( \l__wheelchart_outer_radius_fp + \l__wheelchart_lines_sep_fp + \l__wheelchart_lines_fp + \l__wheelchart_lines_ext_fp ) + } + } , + lines~ext~fixed~right /. initial = + { + \fp_eval:n + { + \l__wheelchart_lines_ext_dir_int + * ( \l__wheelchart_outer_radius_fp + \l__wheelchart_lines_sep_fp + \l__wheelchart_lines_fp + \l__wheelchart_lines_ext_fp ) + } + } , + lines~ext~left~anchor /. initial = mid~east , + lines~ext~right~anchor /. initial = mid~west , + lines~ext~top~dir /. code = { \int_set_eq:Nc \l__wheelchart_lines_ext_top_dir_int { c__wheelchart_lines_ext_dir_#1_int } } , + lines~ext~top~dir = right , + lines~pos /. initial = 1 , + lines~sep /. initial = 0.2 , + lines~style /. style = { lines_style /. style = {#1} } , + lines_style /. style = {} , + middle /. initial = {} , + middle~fill /. style = + { + bool_set_true = \l__wheelchart_middle_fill_bool , + middle_fill /. style = {#1} + } , + middle_fill /. style = {} , + middle~style /. style = { middle_style /. style = {#1} } , + middle_style /. style = {} , + name /. code = { \tl_gset:Ne \g__wheelchart_name_tl {#1} } , + name = wheelchart@name , + outer~plot /. code = + { + \bool_set_true:N \l__wheelchart_plot_bool + \cs_set:Npn \__wheelchart_outer_plot:nn ##1##2 {#1} + \tl_set:Nn \l__wheelchart_slices_outer_tl + { + -- plot + [ + domain = + \fp_use:N \l__wheelchart_slice_outer_start_angle_fp + \c_colon_str + \fp_use:N \l__wheelchart_slice_outer_end_angle_fp , + samples = \fp_use:N \l__wheelchart_samples_fp , + variable = \l__wheelchart_outer_plot_variable_fp , + / wheelchart / outer_plot_style + ] + ( \__wheelchart_outer_plot:nn { \l__wheelchart_outer_plot_variable_fp } { \fp_use:N \l__wheelchart_outer_radius_fp } ) + } + } , + outer~plot~style /. style = { outer_plot_style /. style = {#1} } , + outer_plot_style /. style = {} , + outer~radius /. initial = 3 , + parse /. initial = pgfmath , + perc~precision /. initial = 0 , + pie /. code = { \bool_set:Nn \l__wheelchart_pie_bool { \cs:w c_#1_bool\cs_end: } } , + pie /. default = true , + pie = false , + plot /. style = + { + inner~plot = {#1} , + outer~plot = {#1} + } , + plot~style /. style = + { + inner~plot~style = {#1} , + outer~plot~style = {#1} + } , + radius /. style~2~args = + { + inner~radius = {#1} , + outer~radius = {#2} + } , + samples /. initial = 25 ,%the same number as /tikz/samples + separator~columns /. initial = / , + separator~rows /. initial = { , } , + slice_final /. style = { slice_final_style /. style = {#1} } , + slice_final_style /. style = {} , + slices /. code = + { + \bool_set_true:N \l__wheelchart_slices_bool + \tl_set:Nn \l__wheelchart_slices_tl {#1} + } , + slices~angle~pos /. initial = 0.5 , + slices~angle~shift /. initial = 0 , + slices~arc /. style~2~args = + { + slices~start~arc = { - (#1) } {#2} , + slices~end~arc = {#1} {#2} + } , + slices~arc~inner~end /. is~choice , + slices~arc~inner~end / false /. style = {} , + slices~arc~inner~end / false /. value~forbidden , + slices~arc~inner~end / true /. style = + { slices~arc~match = { inner } { 1 } { -1 } { 1 } { inner~end } { inner~start } { outer~end } } , + slices~arc~inner~end / true /. value~forbidden , + slices~arc~inner~end /. initial = false , + slices~arc~inner~end /. default = true , + slices~arc~inner~end~start /. is~choice , + slices~arc~inner~end~start / false /. style = {} , + slices~arc~inner~end~start / false /. value~forbidden , + slices~arc~inner~end~start / true /. style = + { slices~arc~match = { inner } { 1 } { 1 } { 1 } { inner~end } { inner~start } { outer~end } } , + slices~arc~inner~end~start / true /. value~forbidden , + slices~arc~inner~end~start /. initial = false , + slices~arc~inner~end~start /. default = true , + slices~arc~inner~start /. is~choice , + slices~arc~inner~start / false /. style = {} , + slices~arc~inner~start / false /. value~forbidden , + slices~arc~inner~start / true /. style = + { slices~arc~match = { inner } { 1 } { -1 } { -1 } { inner~start } { inner~end } { outer~start } } , + slices~arc~inner~start / true /. value~forbidden , + slices~arc~inner~start /. initial = false , + slices~arc~inner~start /. default = true , + slices~arc~inner~start~end /. is~choice , + slices~arc~inner~start~end / false /. style = {} , + slices~arc~inner~start~end / false /. value~forbidden , + slices~arc~inner~start~end / true /. style = + { slices~arc~match = { inner } { -1 } { -1 } { -1 } { inner~start } { inner~end } { outer~start } } , + slices~arc~inner~start~end / true /. value~forbidden , + slices~arc~inner~start~end /. initial = false , + slices~arc~inner~start~end /. default = true , + slices~arc~match /. style~n~args = { 7 } + { + slices~end~arc = { (#2) * tan ( \__wheelchart_diff_atan:nnnn {#7} {#6} {#5} {#6} / 2 ) } { 0 } , + slices~start~arc = { (#3) * tan ( \__wheelchart_diff_atan:nnnn {#7} {#6} {#5} {#6} / 2 ) } { 0 } , + slices~#1~arc = { (#4) * tan ( \__wheelchart_diff_atan:nnnn {#5} {#7} {#6} {#7} / 2 ) } { 0 } + } , + slices~arc~outer~end /. is~choice , + slices~arc~outer~end / false /. style = {} , + slices~arc~outer~end / false /. value~forbidden , + slices~arc~outer~end / true /. style = + { slices~arc~match = { outer } { -1 } { 1 } { -1 } { outer~end } { outer~start } { inner~end } } , + slices~arc~outer~end / true /. value~forbidden , + slices~arc~outer~end /. initial = false , + slices~arc~outer~end /. default = true , + slices~arc~outer~end~start /. is~choice , + slices~arc~outer~end~start / false /. style = {} , + slices~arc~outer~end~start / false /. value~forbidden , + slices~arc~outer~end~start / true /. style = + { slices~arc~match = { outer } { -1 } { -1 } { -1 } { outer~end } { outer~start } { inner~end } } , + slices~arc~outer~end~start / true /. value~forbidden , + slices~arc~outer~end~start /. initial = false , + slices~arc~outer~end~start /. default = true , + slices~arc~outer~start /. is~choice , + slices~arc~outer~start / false /. style = {} , + slices~arc~outer~start / false /. value~forbidden , + slices~arc~outer~start / true /. style = + { slices~arc~match = { outer } { -1 } { 1 } { 1 } { outer~start } { outer~end } { inner~start } } , + slices~arc~outer~start / true /. value~forbidden , + slices~arc~outer~start /. initial = false , + slices~arc~outer~start /. default = true , + slices~arc~outer~start~end /. is~choice , + slices~arc~outer~start~end / false /. style = {} , + slices~arc~outer~start~end / false /. value~forbidden , + slices~arc~outer~start~end / true /. style = + { slices~arc~match = { outer } { 1 } { 1 } { 1 } { outer~start } { outer~end } { inner~start } } , + slices~arc~outer~start~end / true /. value~forbidden , + slices~arc~outer~start~end /. initial = false , + slices~arc~outer~start~end /. default = true , + slices~arrow /. style~2~args = + { + slices~start~arrow = { - (#1) } {#2} , + slices~end~arrow = {#1} {#2} + } , + slices~end~arc /. code~2~args = + { + \tl_set:Nn \l__wheelchart_slices_end_tl + { + \__wheelchart_slices_arc:nnnnnn + {#1} + {#2} + { outer~end } + { inner~end } + { -- ( \fp_use:c { l__wheelchart_inner~end_x_fp } , \fp_use:c { l__wheelchart_inner~end_y_fp } ) } + {} + } + } , + slices~end~arrow /. code~2~args = + { + \tl_set:Nn \l__wheelchart_slices_end_tl + { + \__wheelchart_slices_arrow:nnnnn + {#1} + {#2} + { outer~end } + { inner~end } + { -- ( \fp_use:c { l__wheelchart_inner~end_x_fp } , \fp_use:c { l__wheelchart_inner~end_y_fp } ) } + } + } , + slices~end~to /. code~2~args = + { + \tl_set:Nn \l__wheelchart_slices_end_tl + { + \__wheelchart_slices_to:nn {#2} {#1} + ( \fp_use:c { l__wheelchart_inner~end_x_fp } , \fp_use:c { l__wheelchart_inner~end_y_fp } ) + } + } , + slices~inner~angle~reduce /. style = + { + slices~inner~end~angle~shift = { - (#1) } , + slices~inner~start~angle~shift = {#1} + } , + slices~inner~angle~shift /. style = + { + slices~inner~end~angle~shift = {#1} , + slices~inner~start~angle~shift = {#1} + } , + slices~inner~arc /. code~2~args = + { + \tl_set:Nn \l__wheelchart_slices_inner_tl + { + \__wheelchart_slices_arc:nnnnnn + {#1} + {#2} + { inner~end } + { inner~start } + { -- ( \fp_use:c { l__wheelchart_inner~start_x_fp } , \fp_use:c { l__wheelchart_inner~start_y_fp } ) } + {} + } + } , + slices~inner~arc~tangent /. is~choice , + slices~inner~arc~tangent / false /. code = {} , + slices~inner~arc~tangent / false /. value~forbidden , + slices~inner~arc~tangent / true /. code = + { + \tl_set:Nn \l__wheelchart_slices_inner_tl + { + \__wheelchart_slices_arc:nnnnnn + { \__wheelchart_diff_atan:nnnn { outer~start } { inner~start } { outer~end } { inner~end } } + { 0 } + { inner~end } + { inner~start } + { -- ( \fp_use:c { l__wheelchart_inner~start_x_fp } , \fp_use:c { l__wheelchart_inner~start_y_fp } ) } + { + \fp_compare:nNnTF { \l__wheelchart_slices_arc_A_fp } > { 359.99 } + { \fp_set:Nn \l__wheelchart_slices_arc_A_fp { 1 } } + { \fp_set:Nn \l__wheelchart_slices_arc_A_fp { tand ( 45 - \l__wheelchart_slices_arc_A_fp / 4 ) } } + } + } + } , + slices~inner~arc~tangent / true /. value~forbidden , + slices~inner~arc~tangent /. initial = false , + slices~inner~arc~tangent /. default = true , + slices~inner~arrow /. code~2~args = + { + \tl_set:Nn \l__wheelchart_slices_inner_tl + { + \__wheelchart_slices_arrow:nnnnn + {#1} + {#2} + { inner~end } + { inner~start } + { -- ( \fp_use:c { l__wheelchart_inner~start_x_fp } , \fp_use:c { l__wheelchart_inner~start_y_fp } ) } + } + } , + slices~inner~end~angle~shift /. initial = 0 , + slices~inner~start~angle~shift /. initial = 0 , + slices~inner~to /. code~2~args = + { + \tl_set:Nn \l__wheelchart_slices_inner_tl + { + \__wheelchart_slices_to:nn {#2} {#1} + ( \fp_use:c { l__wheelchart_inner~start_x_fp } , \fp_use:c { l__wheelchart_inner~start_y_fp } ) + } + } , + slices~outer~angle~reduce /. style = + { + slices~outer~end~angle~shift = { - (#1) } , + slices~outer~start~angle~shift = {#1} + } , + slices~outer~angle~shift /. style = + { + slices~outer~end~angle~shift = {#1} , + slices~outer~start~angle~shift = {#1} + } , + slices~outer~arc /. code~2~args = + { + \tl_set:Nn \l__wheelchart_slices_outer_tl + { + \__wheelchart_slices_arc:nnnnnn + {#1} + {#2} + { outer~start } + { outer~end } + { -- ( \fp_use:c { l__wheelchart_outer~end_x_fp } , \fp_use:c { l__wheelchart_outer~end_y_fp } ) } + {} + } + } , + slices~outer~arc~tangent /. is~choice , + slices~outer~arc~tangent / false /. code = {} , + slices~outer~arc~tangent / false /. value~forbidden , + slices~outer~arc~tangent / true /. code = + { + \tl_set:Nn \l__wheelchart_slices_outer_tl + { + \__wheelchart_slices_arc:nnnnnn + { \__wheelchart_diff_atan:nnnn { outer~start } { inner~start } { outer~end } { inner~end } } + { 0 } + { outer~start } + { outer~end } + { -- ( \fp_use:c { l__wheelchart_outer~end_x_fp } , \fp_use:c { l__wheelchart_outer~end_y_fp } ) } + { + \fp_compare:nNnTF { \l__wheelchart_slices_arc_A_fp } > { 359.99 } + { \fp_set:Nn \l__wheelchart_slices_arc_A_fp { 1 } } + { + \fp_compare:nNnTF { \l__wheelchart_slices_arc_A_fp } = { 180 } + { \fp_set:Nn \l__wheelchart_slices_arc_A_fp { 0 } } + { \fp_set:Nn \l__wheelchart_slices_arc_A_fp { cotd ( 45 - \l__wheelchart_slices_arc_A_fp / 4 ) } } + } + } + } + } , + slices~outer~arc~tangent / true /. value~forbidden , + slices~outer~arc~tangent /. initial = false , + slices~outer~arc~tangent /. default = true , + slices~outer~arrow /. code~2~args = + { + \tl_set:Nn \l__wheelchart_slices_outer_tl + { + \__wheelchart_slices_arrow:nnnnn + {#1} + {#2} + { outer~start } + { outer~end } + { -- ( \fp_use:c { l__wheelchart_outer~end_x_fp } , \fp_use:c { l__wheelchart_outer~end_y_fp } ) } + } + } , + slices~outer~end~angle~shift /. initial = 0 , + slices~outer~start~angle~shift /. initial = 0 , + slices~outer~to /. code~2~args = + { + \tl_set:Nn \l__wheelchart_slices_outer_tl + { + \__wheelchart_slices_to:nn {#1} {#2} + ( \fp_use:c { l__wheelchart_outer~end_x_fp } , \fp_use:c { l__wheelchart_outer~end_y_fp } ) + } + } , + slices~pos /. initial = 0.5 , + slices~scope /. style = { slices_scope /. style = {#1} } , + slices_scope /. style = {} , + slices~sep /. initial = 0 , + slices~start~arc /. code~2~args = + { + \tl_set:Nn \l__wheelchart_slices_start_tl + { + \__wheelchart_slices_arc:nnnnnn + {#1} + {#2} + { inner~start } + { outer~start } + { -- cycle } + {} + } + } , + slices~start~arrow/.code~2~args = + { + \tl_set:Nn \l__wheelchart_slices_start_tl + { + \__wheelchart_slices_arrow:nnnnn + {#1} + {#2} + { inner~start } + { outer~start } + { -- cycle } + } + } , + slices~start~to /. code~2~args = { \tl_set:Nn \l__wheelchart_slices_start_tl { \__wheelchart_slices_to:nn {#1} {#2} cycle } } , + slices~style /. style = { slices_style /. style = {#1} } , + slices_style /. style = {} , + slices~style = { \WCvarB } , + slices~to /. style~2~args = + { + slices~end~to = {#1} {#2} , + slices~start~to = { - (#1) } { - (#2) } + } , + start~angle /. initial = 90 , + start~half /. style = + { + start~angle = + { + (#1) - + \fp_eval:n + { + \l__wheelchart_counter_or_clockwise_fp * \fp_use:c { l__wheelchart_value_1_fp } * 0.5 + * ( \l__wheelchart_total_angle_fp / \WCtotalnum ) + } + } + } , + start~half /. default = 90 , + title /. initial= {} , + title~left /. initial = {} , + title~left~sep /. initial = 0.5 , + title~left~style /. style = { title~left_style /. style = {#1} } , + title~left_style /. style = {} , + title~sep /. initial = 0.5 , + title~style /. style = { title_style /. style = {#1} } , + title_style /. style = {} , + total~angle /. initial = 360 , + total~count /. code = + { + \tl_set:Nn \l__wheelchart_type_tl { totalcount } + \__wheelchart_def_macro:Nn \l__wheelchart_total_count_fp {#1} + } , + triangle~proportional~area /. style~2~args = + { + domain /. expanded = 0 \c_colon_str 1 , + plot = { { (##2) * sqrt ( 1 - (##1) ) * (#1) / 2 } , { - sqrt ( 1 - (##1) ) * (#2) } } , + radius = { -1 } { 1 } , + samples = 2 , + wheel~data~pos = 0.5 + } , + triangle~proportional~height /. style~2~args = + { + domain /. expanded = 0 \c_colon_str 1 , + plot = { { (##2) * ( 1 - (##1) ) * (#1) / 2 } , { ( (##1) - 1 ) * (#2) } } , + radius = { -1 } { 1 } , + samples = 2 , + wheel~data~pos = 0.5 + } , + value /. initial = { \WCvarA } , + WC_list /. code~2~args = + { + \cs_set:cpn {#1} + { \use:e { \clist_item:nn {#2} { \int_mod:nn { \WCcount-1 } { \clist_count:n {#2} } + 1 } } } + %note the \use:e such that \WClist<name> also works when given as an argument to pgfmath + %if the list contains a macro, for example + %\begin{tikzpicture} + %\def\n{1} + %\wheelchart[ + % value=\WClistA, + % WClistA={\n} + %]{\exampleforthismanual} + %\end{tikzpicture} + %https://tex.stackexchange.com/questions/671298/clist-item-and-pgfmathsetmacro-causing-an-error + } , + wheel~data /. initial = {} , + wheel~data~angle~pos /. initial = 0.5 , + wheel~data~angle~shift /. initial = 0 , + wheel~data~pos /. initial = 0.66 , + wheel~data~sep /. initial = 0 , + wheel~data~style /. style = { wheel_data_style /. style = {#1} } , + wheel_data_style /. style = {} , + wheel~lines /. style = + { + bool_set_true = \l__wheelchart_wheel_lines_bool , + wheel_lines /. style = {#1} + } , + wheel_lines /. style = {} , + xbar /. style~2~args = + { + domain /. expanded = 0 \c_colon_str {#1} , + plot = { {##1} , {##2} } , + radius = { 0 } {#2} , + samples = 2 , + wheel~data~pos = 0.5 + } , + ybar /. style~2~args = + { + domain /. expanded = 0 \c_colon_str {#2} , + plot = { {##2} , {##1} } , + radius = { 0 } {#1} , + samples = 2 , + wheel~data~pos = 0.5 + } , + } + +\pgfkeys + { + / wheelchart /. unknown /. code = + { + \tl_set:Ne \l__wheelchart_key_name_tl { \pgfkeyscurrentname }%it is necessary to define \l__wheelchart_key_name_tl + %because \pgfkeyscurrentname will be overwritten by / errors / unknown~key /. expanded + \regex_match:nVTF { \{(.+)\} } \l__wheelchart_key_name_tl + { + \tl_set:Ne \l__wheelchart_key_range_tl { \pgfkeyscurrentname } + \regex_replace_all:nnN { \{(.+)\} } {} \l__wheelchart_key_name_tl + \regex_replace_all:nnN { [\w\s]+\{(.+)\} } { \1 } \l__wheelchart_key_range_tl + \str_if_eq:eeTF { \l__wheelchart_key_range_tl } { list } + { + \pgfkeys { / wheelchart , WC_list = { l__wheelchart_list_\l__wheelchart_key_name_tl } {#1} } + \pgfkeys + { + / wheelchart , + \l__wheelchart_key_name_tl /. expand~once = { \cs:w l__wheelchart_list_\l__wheelchart_key_name_tl\cs_end: } + } + } + { + \clist_gclear:N \g__wheelchart_slice_range_for_loop_clist + \foreach \l__wheelchart_slice_range_index_int [ parse = true ] in \l__wheelchart_key_range_tl + { + \clist_gput_right:Ne \g__wheelchart_slice_range_for_loop_clist + { \fp_eval:n { \l__wheelchart_slice_range_index_int } } + } + \clist_map_inline:Nn \g__wheelchart_slice_range_for_loop_clist + { + \clist_put_right:Nn \l__wheelchart_slice_range_local_clist {##1} + \clist_if_exist:cF { l__wheelchart_slice_##1_keys_clist } + { \clist_new:c { l__wheelchart_slice_##1_keys_clist } } + \str_if_eq:eeTF { \l__wheelchart_key_name_tl } { slice } + { \clist_put_right:cn { l__wheelchart_slice_##1_keys_clist } {#1} } + { + \clist_put_right:ce { l__wheelchart_slice_##1_keys_clist } + { \exp_not:V \l__wheelchart_key_name_tl \exp_not:n { = {#1} } } + } + } + } + } + { + \str_if_eq:eeTF { \str_range:Nnn \l__wheelchart_key_name_tl { 1 } { 6 } } { WClist } + { \pgfkeys { / wheelchart , WC_list = { \l__wheelchart_key_name_tl } {#1} } } + { \pgfkeys { / errors / unknown~key /. expanded = { \l__wheelchart_key_name_tl } {#1} } } + } + } + }%this gives an error message if a key of the form <unknown key for wheelchart>{<range>} is given + +%%> \subsection{The command \textbackslash wheelchart} + +\NewDocumentCommand { \wheelchart } { O{} m } + { + {%note the double {{...}} such that the contents is in a group and such that & can be used in pgfmath in a tabular + \pgfkeys { / wheelchart , #1 } + \@ifpackageloaded { siunitx } + { \cs_set:Npn \WCperc { \qty { \WCpercentagerounded } { \percent } } } + { \cs_set:Npn \WCperc { \WCpercentagerounded \, \% } }%the definition of \WCperc is placed inside the command \wheelchart + %such that \WCperc is not defined outside this command + \bool_if:NTF \l__wheelchart_legend_only_bool + { + \__wheelchart_initial:n {#2} + \bool_if:NT \l__wheelchart_legend_row_bool + { \__wheelchart_def_WClegend: } + \pgfkeysvalueof { / wheelchart / legend } + } + { + \fp_set:Nn \l__wheelchart_coord_determinant_fp { \pgf@yy * \pgf@xx - \pgf@yx * \pgf@xy } + \begin { scope } [ shift /. expanded = { \pgfkeysvalueof { / wheelchart / at } } ] + \begin { scope } [ local~bounding~box /. expanded = \g__wheelchart_name_tl ] + \__wheelchart_def_macros:n { total~angle } + \__wheelchart_initial:n {#2} + \__wheelchart_def_macros:n { start~angle } + \bool_if:NF \l__wheelchart_plot_bool + { + \bool_set_false:N \l__wheelchart_def_inner_contour_bool + \bool_if:NTF \l__wheelchart_contour_bool + { + \bool_set_true:N \l__wheelchart_def_inner_contour_bool + \tl_build_gbegin:N \g__wheelchart_outer_contour_tl + \__wheelchart_for_loop:n + { + \tl_build_gput_left:Ne \g__wheelchart_outer_contour_tl + { + ( \fp_use:N \g__wheelchart_new_angle_fp \c_colon_str \fp_use:N \l__wheelchart_outer_radius_fp ) + arc + [ + start~angle = \fp_use:N \g__wheelchart_new_angle_fp , + end~angle = \fp_use:N \g__wheelchart_angle_fp , + radius = \fp_use:N \l__wheelchart_outer_radius_fp + ] + -- + } + } + \tl_build_gend:N \g__wheelchart_outer_contour_tl + } + { + \bool_if:NT \l__wheelchart_middle_fill_bool + { \bool_set_true:N \l__wheelchart_def_inner_contour_bool } + } + \bool_if:NT \l__wheelchart_def_inner_contour_bool + { + \tl_build_gbegin:N \g__wheelchart_inner_contour_tl + \__wheelchart_for_loop:n + { + \tl_build_gput_right:Ne \g__wheelchart_inner_contour_tl + { + ( \fp_use:N \g__wheelchart_angle_fp \c_colon_str \fp_use:N \l__wheelchart_inner_radius_fp ) + arc + [ + start~angle = \fp_use:N \g__wheelchart_angle_fp , + end~angle = \fp_use:N \g__wheelchart_new_angle_fp , + radius = \fp_use:N \l__wheelchart_inner_radius_fp + ] + -- + } + } + \tl_build_gend:N \g__wheelchart_inner_contour_tl + } + \bool_if:NT \l__wheelchart_middle_fill_bool + { + \fill [ / wheelchart / middle_fill ] + \fp_compare:nNnF { \l__wheelchart_total_angle_fp } = { 360 } + { ( 0 , 0 ) -- } + \g__wheelchart_inner_contour_tl cycle ; + } + } + \bool_if:NTF \l__wheelchart_discrete_bool + { \__wheelchart_discrete_algorithm: } + { + \__wheelchart_for_loop:n + { + \int_compare:nNnT { \WCcount } = { 1 } + { + %determine the orientation, this is necessary even if no plot is used, for example if + %inner radius > outer radius then \g__wheelchart_slices_orientation_fp is different from + %\l__wheelchart_counter_or_clockwise_fp + \fp_set:Nn \l__wheelchart_slices_orientation_new_angle_fp + { + \g__wheelchart_angle_fp + + ( + \g__wheelchart_new_angle_fp == \g__wheelchart_angle_fp + ? + \l__wheelchart_counter_or_clockwise_fp * \l__wheelchart_total_angle_fp + : + \g__wheelchart_new_angle_fp - \g__wheelchart_angle_fp + ) + / \l__wheelchart_samples_fp + } + \path let + \p { l__wheelchart_slices_orientation_1 } = + ( + \__wheelchart_outer_plot:nn + { \fp_use:N \g__wheelchart_angle_fp } + { \fp_use:N \l__wheelchart_outer_radius_fp } + ) , + \p { l__wheelchart_slices_orientation_2 } = + ( + \__wheelchart_outer_plot:nn + { \fp_use:N \l__wheelchart_slices_orientation_new_angle_fp } + { \fp_use:N \l__wheelchart_outer_radius_fp } + ) , + \p { l__wheelchart_slices_orientation_3 } = + ( + \__wheelchart_inner_plot:nn + { \fp_use:N \l__wheelchart_slices_orientation_new_angle_fp } + { \fp_use:N \l__wheelchart_inner_radius_fp } + ) , + \p { l__wheelchart_slices_orientation_4 } = + ( + \__wheelchart_inner_plot:nn + { \fp_use:N \g__wheelchart_angle_fp } + { \fp_use:N \l__wheelchart_inner_radius_fp } + ) + in + [ + / utils / exec = + { + \fp_gset:Nn \g__wheelchart_slices_orientation_fp + { + sign + ( + 0.1 * \y { l__wheelchart_slices_orientation_1 } + * ( \x { l__wheelchart_slices_orientation_4 } - \x { l__wheelchart_slices_orientation_2 } ) + + 0.1 * \y { l__wheelchart_slices_orientation_2 } + * ( \x { l__wheelchart_slices_orientation_1 } - \x { l__wheelchart_slices_orientation_3 } ) + + 0.1 * \y { l__wheelchart_slices_orientation_3 } + * ( \x { l__wheelchart_slices_orientation_2 } - \x { l__wheelchart_slices_orientation_4 } ) + + 0.1 * \y { l__wheelchart_slices_orientation_4 } + * ( \x { l__wheelchart_slices_orientation_3 } - \x { l__wheelchart_slices_orientation_1 } ) + ) + * sign ( \l__wheelchart_coord_determinant_fp ) + } + } + ] + ;%the terms are multiplied with 0.1 to try to avoid an overflow + \fp_compare:nNnT { \g__wheelchart_slices_orientation_fp } = { 0 } + { \fp_gset_eq:NN \g__wheelchart_slices_orientation_fp \l__wheelchart_counter_or_clockwise_fp } + } + \pgfkeysvalueof { / wheelchart / before~slices } + \bool_if:NTF \l__wheelchart_slices_bool + { + \__wheelchart_def_macros:n { slices~angle~pos , slices~angle~shift , slices~pos , slices~sep } + \__wheelchart_def_angle:nnnN + { \l__wheelchart_slices_angle_pos_fp } + { \l__wheelchart_slices_angle_shift_fp } + { \l__wheelchart_slices_sep_fp } + \l__wheelchart_slices_angle_fp + \begin { scope } + [ + shift /. expanded = + { + \__wheelchart_convex_comb_coord:nnnn + { \l__wheelchart_slices_angle_pos_fp } + { \l__wheelchart_slices_angle_shift_fp } + { \l__wheelchart_slices_pos_fp } + { \l__wheelchart_slices_sep_fp } + } , + rotate = \l__wheelchart_slices_angle_fp + ] + \fill [ / wheelchart / slices_style ] \l__wheelchart_slices_tl + \end { scope } + } + { + %Below we define x and y coordinates of the 4 points of the slice. + %We do not use the let operation in the path \fill[/wheelchart/slices_style] ... because then + %\n, \p, \x and \y can not be used as macro names inside the argument of a key which is applied + %on this path such as the key slices inner arc. + %First it is necessary to define \g__wheelchart_x_coord_fp and \g__wheelchart_y_coord_fp globally. Then we + %define local macros taking these values with an expanded definition. These are defined locally such that + %these macros do not interfere with values of another wheelchart, for example if wheelcharts would be nested. + %We do not use a \coordinate definition because this would be global which is not suited as explained above. + \__wheelchart_def_coord:nn { inner } { end } + \__wheelchart_def_coord:nn { inner } { start } + \__wheelchart_def_coord:nn { outer } { end } + \__wheelchart_def_coord:nn { outer } { start } + \fill [ / wheelchart / slices_style ] + ( \fp_use:c { l__wheelchart_outer~start_x_fp } , \fp_use:c { l__wheelchart_outer~start_y_fp } ) + \l__wheelchart_slices_outer_tl + \l__wheelchart_slices_end_tl + \l__wheelchart_slices_inner_tl + \l__wheelchart_slices_start_tl + ; + } + \pgfkeysvalueof { / wheelchart / after~slices } + } + } + \__wheelchart_for_loop:n + { + \bool_if:NT \l__wheelchart_wheel_lines_bool + %this is placed inside \__wheelchart_for_loop:n such that wheel lines can be applied for specific slices + { + \int_step_inline:nnn { 0 } { \fp_eval:n { round ( \l__wheelchart_value_fp ) } } + %note the \fp_eval:n { round ( ... ) } to avoid the messages Missing character: There is no ... in font nullfont! + { + \fp_set:Nn \l__wheelchart_angle_wheel_lines_fp + { + \g__wheelchart_angle_fp + + ( \l__wheelchart_counter_or_clockwise_fp * (####1) * ( \l__wheelchart_total_angle_fp / \WCtotalnum ) ) + } + \draw [ / wheelchart / wheel_lines ] + ( + \__wheelchart_inner_plot:nn + { \fp_use:N \l__wheelchart_angle_wheel_lines_fp } + { \fp_use:N \l__wheelchart_inner_radius_fp } + ) + -- + ( + \__wheelchart_outer_plot:nn + { \fp_use:N \l__wheelchart_angle_wheel_lines_fp } + { \fp_use:N \l__wheelchart_outer_radius_fp } + ) + ; + } + } + } + \bool_if:NF \l__wheelchart_plot_bool + { + \bool_if:NT \l__wheelchart_contour_bool + { + \fp_compare:nNnTF { \l__wheelchart_total_angle_fp } = { 360 } + { + \draw [ / wheelchart / contour_style ] \g__wheelchart_inner_contour_tl cycle ; + \draw [ / wheelchart / contour_style ] \g__wheelchart_outer_contour_tl cycle ; + } + { + \draw [ / wheelchart / contour_style ] \g__wheelchart_inner_contour_tl \g__wheelchart_outer_contour_tl cycle ; + } + } + } + \__wheelchart_for_loop:n + { + \__wheelchart_def_macros:n + { data~pos , lines , lines~angle~pos , lines~angle~shift , lines~ext , lines~pos , lines~sep } + \fp_compare:nNnF { \l__wheelchart_lines_ext_fp } = { 0 } + { + \bool_if:NF \l__wheelchart_lines_ext_dir_bool + { + \__wheelchart_def_macros:n { lines~ext~dirsep } + \int_set:Nn \l__wheelchart_lines_ext_dir_int + { + \fp_eval:n + { + ( + \WCdataangle < 90 - \l__wheelchart_lines_ext_dirsep_fp + ? + 1 + : + ( + \WCdataangle <= 90 + \l__wheelchart_lines_ext_dirsep_fp + ? + \l__wheelchart_lines_ext_top_dir_int + : + ( + \WCdataangle < 270 - \l__wheelchart_lines_ext_dirsep_fp + ? + -1 + : + ( + \WCdataangle <= 270 + \l__wheelchart_lines_ext_dirsep_fp + ? + \l__wheelchart_lines_ext_bottom_dir_int + : + 1 + ) + ) + ) + ) + } + } + } + \__wheelchart_def_macros:n { lines~ext~fixed~left , lines~ext~fixed~right } + } + \fp_compare:nF { \l__wheelchart_lines_fp == 0 && \l__wheelchart_lines_ext_fp == 0 } + { + \draw [ / wheelchart / lines_style ] let \p { l__wheelchart_lines_1 } = + \__wheelchart_convex_comb_coord:nnnn + { \l__wheelchart_data_angle_pos_fp } + { \l__wheelchart_data_angle_shift_fp } + { \l__wheelchart_data_pos_fp } + { \l__wheelchart_lines_sep_fp + \l__wheelchart_lines_fp } + in + \__wheelchart_convex_comb_coord:nnnn + { \l__wheelchart_lines_angle_pos_fp } + { \l__wheelchart_lines_angle_shift_fp } + { \l__wheelchart_lines_pos_fp } + { \l__wheelchart_lines_sep_fp } + -- ( \p { l__wheelchart_lines_1 } ) + \fp_compare:nNnF { \l__wheelchart_lines_ext_fp } = { 0 } + { + \str_case:enF { \pgfkeysvalueof { / wheelchart / lines~ext~fixed } } + { + { true } + { + -- + ( + { + \fp_eval:n + { + \l__wheelchart_lines_ext_dir_int == 1 + ? + \l__wheelchart_lines_ext_fixed_right_fp + : + \l__wheelchart_lines_ext_fixed_left_fp + } + } + , + \y { l__wheelchart_lines_1 } + ) + } + { false } + { --++ ( { \fp_eval:n { \l__wheelchart_lines_ext_dir_int * \l__wheelchart_lines_ext_fp } } , 0 ) } + } + { + \pgfkeys + { + / errors / boolean~expected /. expanded = + { lines~ext~fixed } + { \pgfkeysvalueof { / wheelchart / lines~ext~fixed } } + } + } + coordinate + [ shift = { ( { \fp_eval:n { \l__wheelchart_lines_ext_dir_int * \l__wheelchart_data_sep_fp } } , 0 ) } ] + ( g__wheelchart_data_coordinate ) + } + ; + } + \__wheelchart_if_text:nn { data } + { + \fp_compare:nNnTF { \l__wheelchart_lines_ext_fp } = { 0 } + { + \__wheelchart_def_macros:n { anchor~xsep , anchor~ysep } + \pgfmathparse + { + ( \WCdataangle == 0 ? "west" \c_colon_str + ( \WCdataangle == 90 ? "south" \c_colon_str + ( \WCdataangle == 180 ? "east" \c_colon_str + ( \WCdataangle == 270 ? "north" \c_colon_str + ( \WCdataangle <= \fp_use:N \l__wheelchart_anchor_ysep_fp ? "west" \c_colon_str + ( \WCdataangle < 90 - \fp_use:N \l__wheelchart_anchor_xsep_fp ? "south~west" \c_colon_str + ( \WCdataangle <= 90 + \fp_use:N \l__wheelchart_anchor_xsep_fp ? "south" \c_colon_str + ( \WCdataangle < 180 - \fp_use:N \l__wheelchart_anchor_ysep_fp ? "south~east" \c_colon_str + ( \WCdataangle <= 180 + \fp_use:N \l__wheelchart_anchor_ysep_fp ? "east" \c_colon_str + ( \WCdataangle < 270 - \fp_use:N \l__wheelchart_anchor_xsep_fp ? "north~east" \c_colon_str + ( \WCdataangle <= 270 + \fp_use:N \l__wheelchart_anchor_xsep_fp ? "north" \c_colon_str + ( \WCdataangle < 360 - \fp_use:N \l__wheelchart_anchor_ysep_fp ? "north~west" \c_colon_str + "west" + )))))))))))) + } + \tl_set:Ne \l__wheelchart_data_anchor_tl { \pgfmathresult } + \coordinate + [ + at = + \__wheelchart_convex_comb_coord:nnnn + { \l__wheelchart_data_angle_pos_fp } + { \l__wheelchart_data_angle_shift_fp } + { \l__wheelchart_data_pos_fp } + { + \l__wheelchart_data_sep_fp + + ( + \l__wheelchart_lines_fp == 0 + ? + 0 + : + \l__wheelchart_lines_sep_fp + \l__wheelchart_lines_fp + ) + } + ] + ( g__wheelchart_data_coordinate ) ; + } + { + \pgfmathparse { \int_use:N \l__wheelchart_lines_ext_dir_int == 1 ? "right" \c_colon_str "left" } + \tl_set:Ne \l__wheelchart_data_anchor_tl + { \pgfkeysvalueof { / wheelchart / lines~ext~\pgfmathresult \c_space_tl anchor } } + } + \node [ anchor = \l__wheelchart_data_anchor_tl , align = left , / wheelchart / data_style ] + at ( g__wheelchart_data_coordinate ) + { \pgfkeysvalueof { / wheelchart / data } } ;%a separate \node and not at the end of the \draw with lines_style + %such that the key lines style is not passed to this \node + } + \__wheelchart_def_macros:n { arc~data~angle~pos , arc~data~dir }%these are needed for arc data and arc + \pgfinterruptpicture% + \fp_gset:Nn \g__wheelchart_half_ex_over_one_cm_fp { 0.5 ex / 1 cm }% + \endpgfinterruptpicture% + \fp_gset:Nn \g__wheelchart_arc_data_factor_fp { 0 } + \__wheelchart_if_text:nn { arc~data } + { + \__wheelchart_def_macros:n { arc~data~angle~shift , arc~data~pos , arc~data~sep } + \hbox_set:Nn \l__wheelchart_arc_data_box + { \pgfinterruptpicture { \pgfkeysvalueof { / wheelchart / arc~data } } \endpgfinterruptpicture } + \fp_gset:Nn \g__wheelchart_arc_data_slice_length_fp { 1 }%this is necessary if the value is 0 + \__wheelchart_convex_comb_coord_plot:nnnnnnn + { + overlay , + decorate , + decoration = + { + text~along~path , + text = { {} { \fp_gset:Nn \g__wheelchart_arc_data_slice_length_fp { \pgfdecoratedpathlength } } } , + raise = -0.5 ex , + text~align = \l__wheelchart_arc_data_align_tl , + / wheelchart / arc_data_style + } + }%get the length of the path + %note the option overlay such that this does not increase the bounding box + %note the {} at the start of text and the braces around \fp_gset:Nn ... such that the compilation does not stall + { 0 } + { 1 } + { \l__wheelchart_plot_variable_fp } + { 0 } + { \l__wheelchart_arc_data_pos_fp } + { \l__wheelchart_arc_data_sep_fp } + \__wheelchart_convex_comb_coord_plot:nnnnnnn + { + decorate , + decoration = + { + text~along~path , + text = + { + { { \fp_gset:Nn \g__wheelchart_arc_data_factor_fp { \the \pgfdecoratedcompleteddistance } } } + \pgfkeysvalueof { / wheelchart / arc~data } + { + { + \fp_gset:Nn \g__wheelchart_arc_data_factor_fp + { + ( \the \pgfdecoratedcompleteddistance - \g__wheelchart_arc_data_factor_fp ) + / \g__wheelchart_arc_data_slice_length_fp + } + } + } + } , + raise = -0.5 ex , + text~align = \l__wheelchart_arc_data_align_tl , + / wheelchart / arc_data_style + } + }%note the double braces around \fp_gset:Nn ... so that for example arc data=text {\qty{5}{\percent}} is allowed + %note that \def\mytext{}\path[decorate,decoration={text along path,text={\mytext}}] (0,0)--(1,1); + %gives the message Missing character: There is no ... in font nullfont!, then + %text={\pgfkeysvalueof { / wheelchart / arc~data }{}} can be used if the \fp_gset:Nn ... would not be present + { \fp_use:c { c__wheelchart_arc_data_start_factor_\l__wheelchart_arc_data_align_tl _fp } } + { \fp_use:c { c__wheelchart_arc_data_end_factor_\l__wheelchart_arc_data_align_tl _fp } } + { + \l__wheelchart_plot_variable_fp * \l__wheelchart_arc_data_dir_fp * 1.1 + * ( \dim_to_fp:n { \box_wd:N \l__wheelchart_arc_data_box } / \g__wheelchart_arc_data_slice_length_fp ) + + \l__wheelchart_arc_data_angle_pos_fp + } + { \l__wheelchart_arc_data_angle_shift_fp } + { \l__wheelchart_arc_data_pos_fp } + { \l__wheelchart_arc_data_sep_fp } + \fp_compare:nNnT { \g__wheelchart_arc_data_factor_fp } < { 0 } + { + \PackageWarning { wheelchart } + { + The~arc~data~in~slice~\WCcount \c_space_tl did~(possibly)~not~fit.~ + Increase~the~absolute~value~of~arc~data~dir. + }%refer to \WCcount and not to \pgfkeysvalueof { / wheelchart / arc~data } + %because the latter is not necessarily unique + } + } + \bool_if:NT \l__wheelchart_arc_bool + { + \__wheelchart_def_macros:n { arc~pos , arc~sep } + \str_case:enF { \pgfkeysvalueof { / wheelchart / arc~around~text } } + { + { true } + { + \__wheelchart_arc_around_text:nnn { first } { -1 } { 0 } + \__wheelchart_arc_around_text:nnn { second } { 1 } { 1 } + } + { false } + { + \__wheelchart_convex_comb_coord_plot:nnnnnnn + { draw , / wheelchart / arc_style } + { 0 } + { 1 } + { \l__wheelchart_plot_variable_fp } + { 0 } + { \l__wheelchart_arc_pos_fp } + { \l__wheelchart_arc_sep_fp } + } + } + { + \pgfkeys + { + / errors / boolean~expected /. expanded = + { arc~around~text } + { \pgfkeysvalueof { / wheelchart / arc~around~text } } + } + } + } + \__wheelchart_if_text:nn { inner~data } + { + \__wheelchart_def_macros:n { inner~data~angle~pos , inner~data~angle~shift , inner~data~pos , inner~data~sep } + \node [ align = left , / wheelchart / inner_data_style ] at + \__wheelchart_convex_comb_coord:nnnn + { \l__wheelchart_inner_data_angle_pos_fp } + { \l__wheelchart_inner_data_angle_shift_fp } + { \l__wheelchart_inner_data_pos_fp } + { \l__wheelchart_inner_data_sep_fp } + { \pgfkeysvalueof { / wheelchart / inner~data } } ; + } + \__wheelchart_if_text:nn { wheel~data } + { + \__wheelchart_def_macros:n { wheel~data~angle~pos , wheel~data~angle~shift , wheel~data~pos , wheel~data~sep } + \node [ align = left , / wheelchart / wheel_data_style ] at + \__wheelchart_convex_comb_coord:nnnn + { \l__wheelchart_wheel_data_angle_pos_fp } + { \l__wheelchart_wheel_data_angle_shift_fp } + { \l__wheelchart_wheel_data_pos_fp } + { \l__wheelchart_wheel_data_sep_fp } + { \pgfkeysvalueof { / wheelchart / wheel~data } } ; + } + \pgfkeysvalueof { / wheelchart / legend~entry } + } + \bool_if:NT \l__wheelchart_legend_row_bool + { \__wheelchart_def_WClegend: } + \__wheelchart_if_text:nn { middle } + { \node [ align = center , / wheelchart / middle_style ] at ( 0 , 0 ) { \pgfkeysvalueof { / wheelchart / middle } } ; } + \pgfkeysvalueof { / wheelchart / legend } + \end { scope } + \__wheelchart_caption_and_title:nnnnn + { caption~left } { north~west } { left } { \g__wheelchart_name_tl .south~west } { -1 } + \__wheelchart_caption_and_title:nnnnn + { caption } { north } { center } { \g__wheelchart_name_tl .south -| 0 , 0 } { -1 } + \__wheelchart_caption_and_title:nnnnn + { title~left } { south~west } { left } { \g__wheelchart_name_tl .north~west } { 1 } + \__wheelchart_caption_and_title:nnnnn + { title } { south } { center } { \g__wheelchart_name_tl .north -| 0 , 0 } { 1 } + \end { scope } + } + } + }
\ No newline at end of file |