summaryrefslogtreecommitdiff
path: root/graphics/pgf/contrib/wheelchart/wheelchart.sty
diff options
context:
space:
mode:
Diffstat (limited to 'graphics/pgf/contrib/wheelchart/wheelchart.sty')
-rw-r--r--graphics/pgf/contrib/wheelchart/wheelchart.sty3177
1 files changed, 2753 insertions, 424 deletions
diff --git a/graphics/pgf/contrib/wheelchart/wheelchart.sty b/graphics/pgf/contrib/wheelchart/wheelchart.sty
index c7f9fbc8bb..af15d60654 100644
--- a/graphics/pgf/contrib/wheelchart/wheelchart.sty
+++ b/graphics/pgf/contrib/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