%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % 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 % \NeedsTeXFormat{LaTeX2e}[1999/12/01] \ProvidesPackage{pgf-pie}[2011/10/01 v0.1 Some LaTeX macros for pie chart by using PGF/Tikz package.] \RequirePackage{tikz} \RequirePackage{ifthen} % args: % #1: begin angle % #2: end angle % #3: number % #4: label % #5: explode % #6: fill color % #7: radius % #8: center % #9: style \newcommand{\pgfpie@slice}[9]{ \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, #9] (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{\text}{inside}} { % label and number together \path (O) -- ++(\midangle:\innerpos) node {\shortstack{#4 \\ #3}}; } { % label \iflegend \else \path (O) -- ++ (\midangle:\radius) node[inner sep=0, \text=\midangle:#4]{}; \fi % number \path (O) -- ++(\midangle:\innerpos) node {#3}; } } \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 } } % #1: bottom left point % #2: size % #3: number % #4: color \newcommand{\pgfpie@square}[4] { \draw[fill=#4] (#1) rectangle node {#3} ++(#2); } \newcounter{pgfpie@angleBegin} \newcounter{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\text{#1}} \pgfkeyslet{/text/.@cmd}{\settext} \def\setsum#1\pgfeov{\xdef\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} \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, } % load user's parameters \pgfkeys{#1} % legend or not \ifthenelse{\equal{\text}{legend}} {\legendtrue} {\legendfalse} % handle sum \ifthenelse{\equal{\sum}{auto}} { % sum all input \xdef\sum{0} \foreach \p/\t in {#2} { \pgfmathparse{\sum + \p} \xdef\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} } \setcounter{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 / \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} {\beforenumber \p \afternumber} {\thecolor} \iflegend \else %label \path (start) -- ++(\horizontalLength,\height*0.5) node[inner sep=0, \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} {\beforenumber \p \afternumber} {\thecolor} \iflegend \else %label \path (start) -- ++(\width*0.5,\verticalLength) node[inner sep=0, \text=90:\t]{}; \fi \pgfmathparse{\horizontalLength - \width} \xdef\horizontalLength{\pgfmathresult} \path (start) -- ++(\width, 0) coordinate (start); } } %%%%%%%%%% SQUARE PIE END %%%%%%%%%%% \else %%%%%%%%%% CIRCLE PIE BGEIN %%%%%%%%%%% \ifpolar \xdef\maxValue{0} \foreach \p/\e in {#2} { \ifnum \maxValue < \p \xdef\maxValue{\p} \fi } \pgfmathparse{\sum / \value{pgfpie@sliceLength}} \xdef\polarangle{\pgfmathresult} \pgfmathparse{\radius / sqrt(\maxValue)} \xdef\polarRadiusUnit{\pgfmathresult} \else \xdef\theradius{\radius} \fi % drawing loop \foreach \p/\t [count=\i from 0] in {#2} { \setcounter{pgfpie@angleBegin}{\value{pgfpie@angleEnd}} \ifpolar % Polar area diagram \addtocounter{pgfpie@angleEnd}{\polarangle} \pgfmathparse{sqrt(\p) * \polarRadiusUnit} \xdef\theradius{\pgfmathresult} \else % normal pie \addtocounter{pgfpie@angleEnd}{\p} \fi % find explode \pgfmathparse{int(mod(\i,\value{pgfpie@explodeLength}))} \let\ei\pgfmathresult \foreach \e [count=\j from 0] in \explode { \ifnum \j=\ei \xdef\theexplode{\e} \breakforeach \fi } % find color \pgfpie@findColor{\i} \pgfpie@slice{\thepgfpie@angleBegin/\sum*360+\rotate} {\thepgfpie@angleEnd/\sum*360+\rotate} {\beforenumber \p \afternumber} {\t} {\theexplode} {\thecolor} {\theradius} {\pos} {\style} } %%%%%%%%%% CIRCLE PIE END %%%%%%%%%%% \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 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%