123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440 |
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- % Start of pgf-pie.sty
- %
- % Some LaTeX macros for pie chart by using PGF/Tikz package.
- % Home page of project: http://pgf-pie.googlecode.com/
- % Author: Xu Yuan <xuyuan.cn@gmail.com>
- %
- \NeedsTeXFormat{LaTeX2e}[1999/12/01]
- \ProvidesPackage{pgf-pie}[2011/10/02 v0.2 Some LaTeX macros for pie
- chart by using PGF/Tikz package.]
- \RequirePackage{tikz}
- \RequirePackage{ifthen}
- \RequirePackage{scalefnt}
- % args:
- % #1: begin angle
- % #2: end angle
- % #3: number
- % #4: label
- % #5: explode
- % #6: fill color
- % #7: radius
- % #8: center
- \newcommand{\pgfpie@slice}[8]{
- \pgfmathparse{0.5*(#1)+0.5*(#2)}
- \let\midangle\pgfmathresult
- \path (#8) -- ++(\midangle:#5) coordinate(O);
- \pgfmathparse{#7+#5}
- \let\radius\pgfmathresult
-
- % slice
- \draw[line join=round, fill=#6, \style] (O) -- ++(#1:#7) arc (#1:#2:#7) -- cycle;
- \pgfmathparse{min(((#2)-(#1)-10)/110*(-0.3),0)}
- \let\temp\pgfmathresult
- \pgfmathparse{(max(\temp,-0.5) + 0.8)*#7}
- \let\innerpos\pgfmathresult
- \ifthenelse{\equal{\pgfpie@text}{inside}}
- {
- % label and number together
- \path (O) -- ++(\midangle:\innerpos) node
- {\scalefont{#3}\shortstack{#4\\\beforenumber#3\afternumber}};
- }
- {
- % label
- \iflegend
- \else
- \path (O) -- ++ (\midangle:\radius)
- node[inner sep=0, \pgfpie@text=\midangle:#4]{};
- \fi
- % number
- \path (O) -- ++(\midangle:\innerpos) node
- {\scalefont{#3}\beforenumber#3\afternumber};
- }
- }
- \newcommand{\pgfpie@findColor}[1]
- {
- \pgfmathparse{int(mod(#1,\value{pgfpie@colorLength}))}
- \let\ci\pgfmathresult
- \foreach \c [count=\j from 0] in \color {
- \ifnum \j=\ci
- \xdef\thecolor{\c}
- \thecolor
- \breakforeach
- \fi
- }
- }
- \newcommand{\pgfpie@findExplode}[1]
- {
- \pgfmathparse{int(mod(#1,\value{pgfpie@explodeLength}))}
- \let\ei\pgfmathresult
- \foreach \e [count=\j from 0] in \explode {
- \ifnum \j=\ei
- \xdef\theexplode{\e}
- \breakforeach
- \fi
- }
- }
- % #1: bottom left point
- % #2: size
- % #3: number
- % #4: color
- % #5: text
- \newcommand{\pgfpie@square}[5]
- {
- \ifthenelse{\equal{\pgfpie@text}{inside}}
- {
- \draw[fill=#4, \style] (#1) rectangle node
- {\scalefont{#3}\shortstack{#5\\\beforenumber#3\afternumber}} ++(#2);
- }
- {
- \draw[fill=#4, \style] (#1) rectangle node
- {\scalefont{#3}\beforenumber#3\afternumber} ++(#2);
- }
- }
- % #1: pos
- % #2: radius
- % #3: number
- % #4: color
- % $5: style
- % $6: label
- \newcommand{\pgfpie@cloud}[6]
- {
- \draw[fill=#4, #5] (#1) circle[radius=#2];
- \ifthenelse{\equal{\pgfpie@text}{inside}}
- {
- \node at (#1) {\scalefont{#3}\shortstack{#6\\\beforenumber#3\afternumber}};
- }
- {
- \node at (#1) {\scalefont{#3}\beforenumber#3\afternumber};
- }
- }
- \newlength{\pgfpie@angleEnd}
- \newcounter{pgfpie@explodeLength}
- \newcounter{pgfpie@colorLength}
- \newcounter{pgfpie@sliceLength}
- \def\setexplode#1\pgfeov{\def\explode{#1}}
- \pgfkeyslet{/explode/.@cmd}{\setexplode}
- \def\setcolor#1\pgfeov{\def\color{#1}}
- \pgfkeyslet{/color/.@cmd}{\setcolor}
- \def\setradius#1\pgfeov{\def\radius{#1}}
- \pgfkeyslet{/radius/.@cmd}{\setradius}
- \def\setpos#1\pgfeov{\def\pos{#1}}
- \pgfkeyslet{/pos/.@cmd}{\setpos}
- \def\setstyle#1\pgfeov{\def\style{#1}}
- \pgfkeyslet{/style/.@cmd}{\setstyle}
- \def\setbeforenumber#1\pgfeov{\def\beforenumber{#1}}
- \pgfkeyslet{/before number/.@cmd}{\setbeforenumber}
- \def\setafternumber#1\pgfeov{\def\afternumber{#1}}
- \pgfkeyslet{/after number/.@cmd}{\setafternumber}
- \def\settext#1\pgfeov{\xdef\pgfpie@text{#1}}
- \pgfkeyslet{/text/.@cmd}{\settext}
- \def\setsum#1\pgfeov{\xdef\pgfpie@sum{#1}}
- \pgfkeyslet{/sum/.@cmd}{\setsum}
- \def\setrotate#1\pgfeov{\xdef\rotate{#1}}
- \pgfkeyslet{/rotate/.@cmd}{\setrotate}
- \newif\ifpolar
- \pgfkeys{/polar/.is if=polar}
- \newif\iflegend
- \newif\ifsquare
- \pgfkeys{/square/.is if=square}
- \newif\ifcloud
- \pgfkeys{/cloud/.is if=cloud}
- \newif\ifscalefont
- \pgfkeys{/scale font/.is if=scalefont}
- \let\scalefontorg\scalefont
- \renewcommand{\scalefont}[1]
- {
- \ifscalefont
- \pgfmathparse{#1 / \pgfpie@sum * 3 + 0.9}
- \scalefontorg{\pgfmathresult}
- \fi
- }
- \newcommand{\pie}[2][]
- {
- % load default parameters
- \pgfkeys{
- explode=0,
- color={blue!60, cyan!60, yellow!60, orange!60, red!60,
- blue!60!cyan!60, cyan!60!yellow!60, red!60!cyan!60,
- red!60!blue!60, orange!60!cyan!60},
- radius=3,
- pos={0,0},
- style={thick},
- before number=,
- after number=,
- text=label,
- sum=100,
- rotate=0,
- polar=false,
- square=false,
- cloud=false,
- scale font=false,
- }
- % load user's parameters
- \pgfkeys{#1}
- % add percentage automatically
- \ifthenelse{\equal{\pgfpie@sum}{100}}
- {
- \pgfkeys{after number=\%}
- \pgfkeys{#1}
- }{}
- % legend or not
- \ifthenelse{\equal{\pgfpie@text}{legend}}
- {\legendtrue}
- {\legendfalse}
- % handle sum
- \ifthenelse{\equal{\pgfpie@sum}{auto}}
- {
- % sum all input
- \xdef\pgfpie@sum{0}
- \foreach \p/\t in {#2}
- {
- \pgfmathparse{\pgfpie@sum + \p}
- \xdef\pgfpie@sum{\pgfmathresult}
- }
- }
- {}
- % init counters
- \setcounter{pgfpie@explodeLength}{0}
- \foreach \e in \explode { \addtocounter{pgfpie@explodeLength}{1} }
- \setcounter{pgfpie@colorLength}{0}
- \foreach \c in \color { \addtocounter{pgfpie@colorLength}{1} }
-
- \pgfmathsetlength{\pgfpie@angleEnd}{0}
- \setcounter{pgfpie@sliceLength}{0}
- \foreach \p/\e in {#2} { \addtocounter{pgfpie@sliceLength}{1} }
- \ifsquare
- %%%%%%%%%% SQUARE PIE BEGIN %%%%%%%%%%%
- \pgfmathparse{\radius*2}
- \xdef\verticalLength{\pgfmathresult}
- \xdef\horizontalLength{\pgfmathresult}
- \path (\pos) -- ++(-\radius, -\radius) coordinate (start);
- \pgfmathparse{\verticalLength * \horizontalLength / \pgfpie@sum}
- \let\squareUnit\pgfmathresult
- % drawing loop
- \foreach \p/\t [count=\i from 0] in {#2}
- {
- \pgfpie@findColor{\i}
- \ifthenelse{\lengthtest{\verticalLength cm > \horizontalLength cm}}
- {
- \pgfmathparse{\p * \squareUnit / \horizontalLength}
- \let\height\pgfmathresult
-
- \pgfpie@square{start}{\horizontalLength,\height}
- {\p}
- {\thecolor}
- {\t}
- %label
- \iflegend
- \else
- \ifthenelse{\equal{\pgfpie@text}{inside}}
- {}
- {
- \path (start) -- ++(\horizontalLength,\height*0.5) node[inner
- sep=0, \pgfpie@text=0:\t]{};
- }
- \fi
- \pgfmathparse{\verticalLength - \height}
- \xdef\verticalLength{\pgfmathresult}
- \path (start) -- ++(0, \height) coordinate (start);
- }
- {
- \pgfmathparse{\p * \squareUnit / \verticalLength }
- \let\width\pgfmathresult
- \pgfpie@square{start}{\width,\verticalLength}
- {\p}
- {\thecolor}
- {\t}
- %label
- \iflegend
- \else
- \ifthenelse{\equal{\pgfpie@text}{inside}}
- {}
- {
- \path (start) -- ++(\width*0.5,\verticalLength) node[inner
- sep=0, \pgfpie@text=90:\t]{};
- }
- \fi
- \pgfmathparse{\horizontalLength - \width}
- \xdef\horizontalLength{\pgfmathresult}
- \path (start) -- ++(\width, 0) coordinate (start);
- }
- }
-
- %%%%%%%%%% SQUARE PIE END %%%%%%%%%%%
- \else
- \ifcloud
- %%%%%%%%%% CLOUD PIE BGEIN %%%%%%%%%%%
- % drawing loop
- \foreach \p/\t [count=\i from 0] in {#2}
- {
- % find explode
- \pgfpie@findExplode{\i}
- \def\cloudGap{\theexplode + 0.1}
- \pgfmathparse{sqrt(\p / \pgfpie@sum) * \radius}
- \let\cloudR\pgfmathresult
- \ifnum \i = 0
- % first cloud
- \coordinate (O) at (\pos);
- \xdef\cloudRone{\cloudR}
- \xdef\cloudExtendDir{180+\rotate}
- \else
- \ifnum \i = 1
- % second cloud
- \xdef\cloudRtwo{\cloudR}
- \xdef\cloudExtendDir{45+\rotate}
- \path (O) -- ++(\cloudExtendDir:\cloudRone+\cloudGap+\cloudRtwo) coordinate (O);
- \else
- % next cloud
- \pgfmathparse{\cloudRone+\cloudGap+\cloudRtwo}
- \let\la\pgfmathresult
- \pgfmathparse{\cloudRone+\cloudGap+\cloudR}
- \let\lb\pgfmathresult
- \pgfmathparse{\cloudRtwo+\cloudGap+\cloudR}
- \let\lc\pgfmathresult
- \pgfmathparse{\la^2+\lc^2-\lb^2}
- \let\tmp\pgfmathresult
- \pgfmathparse{180 - acos(\tmp / 2 / \la / \lc)}
- \let\cloudRot\pgfmathresult
- \ifodd \i
- \pgfmathparse{-\cloudRot}
- \let\cloudRot\pgfmathresult
- \fi
- \pgfmathparse{\cloudExtendDir - \cloudRot}
- \xdef\cloudExtendDir{\pgfmathresult}
- \path (O) -- ++(\cloudExtendDir:\lc) coordinate (O);
- \xdef\cloudRone{\cloudRtwo}
- \xdef\cloudRtwo{\cloudR}
- \fi
- \fi
- % find color
- \pgfpie@findColor{\i}
- \pgfpie@cloud{O}{\cloudR}{\p}
- {\thecolor}{\style}{\t}
- % label
- \iflegend
- \else
- \ifthenelse{\equal{\pgfpie@text}{inside}}
- {}
- {
- \path (O) -- ++(\cloudExtendDir:\cloudR)
- node[inner sep=0, \pgfpie@text=\cloudExtendDir:\t] {};
- }
- \fi
- }
- %%%%%%%%%% CLOUD PIE BGEIN %%%%%%%%%%%
- \else
- %%%%%%%%%% CIRCLE PIE BGEIN %%%%%%%%%%%
- \ifpolar
- \xdef\maxValue{0}
- \foreach \p/\e in {#2} {
- \ifnum \maxValue < \p
- \xdef\maxValue{\p}
- \fi
- }
- \pgfmathparse{\pgfpie@sum / \value{pgfpie@sliceLength}}
- \xdef\polarangle{\pgfmathresult}
- \pgfmathparse{\radius / sqrt(\maxValue)}
- \xdef\polarRadiusUnit{\pgfmathresult}
- \else
- \xdef\theradius{\radius}
- \fi
- \xdef\pgfpie@angleBegin{\the\pgfpie@angleEnd}
- % drawing loop
- \foreach \p/\t [count=\i from 0] in {#2}
- {
- \pgfmathsetlength{\pgfpie@angleEnd}{\pgfpie@angleBegin}
- \ifpolar
- % Polar area diagram
- \pgfmathaddtolength{\pgfpie@angleEnd}{\polarangle}
- \pgfmathparse{sqrt(\p) * \polarRadiusUnit}
- \xdef\theradius{\pgfmathresult}
- \else
- % normal pie
- \pgfmathaddtolength{\pgfpie@angleEnd}{\p}
- \fi
- % find explode
- \pgfpie@findExplode{\i}
- % find color
- \pgfpie@findColor{\i}
- \pgfpie@slice{\pgfpie@angleBegin/\pgfpie@sum*360+\rotate}
- {\the\pgfpie@angleEnd/\pgfpie@sum*360+\rotate}
- {\p}
- {\t}
- {\theexplode}
- {\thecolor}
- {\theradius}
- {\pos}
- \xdef\pgfpie@angleBegin{\the\pgfpie@angleEnd}
- }
- %%%%%%%%%% CIRCLE PIE END %%%%%%%%%%%
- \fi
- \fi
- % legend
- \iflegend
- \coordinate[xshift=0.8cm,
- yshift=(\value{pgfpie@sliceLength}*0.5+1)*0.5cm] (legendpos) at
- (current bounding box.east);
- \begin{scope}[node distance=0.5cm]
- \foreach \p/\t [count=\i from 0] in {#2}
- {
- \pgfpie@findColor{\i}
- \node[draw, fill=\thecolor, \style, below of=legendpos, label=0:\t] (legendpos) {};
- }
- \end{scope}
- \fi
- }
- %%% End of pgf-pie.sty
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|