%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
% 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{\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, \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{\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{\text}{inside}}
  {
    \node at (#1) {\scalefont{#3}\shortstack{#6\\\beforenumber#3\afternumber}};
  }
  {
    \node at (#1) {\scalefont{#3}\beforenumber#3\afternumber};
  }
}

\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}

\newif\ifcloud
\pgfkeys{/cloud/.is if=cloud}

\newif\ifscalefont
\pgfkeys{/scale font/.is if=scalefont}
\let\scalefontorg\scalefont
\renewcommand{\scalefont}[1]
{
  \ifscalefont
  \pgfmathparse{#1 / \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{\sum}{100}}
  {
    \pgfkeys{after number=\%}
    \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}
      {\p}
      {\thecolor}
      {\t}
      %label
      \iflegend
      \else
      \ifthenelse{\equal{\text}{inside}}
      {}
      {
        \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}
      {\p}
      {\thecolor}
      {\t}
      %label
      \iflegend
      \else
      \ifthenelse{\equal{\text}{inside}}
      {}
      {
        \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
  \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 / \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{\text}{inside}}
    {}
    {
      \path (O) -- ++(\cloudExtendDir:\cloudR)
      node[inner sep=0, \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{\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
    \pgfpie@findExplode{\i}

    % find color
    \pgfpie@findColor{\i}

    \pgfpie@slice{\thepgfpie@angleBegin/\sum*360+\rotate}
    {\thepgfpie@angleEnd/\sum*360+\rotate}
    {\p}
    {\t}
    {\theexplode}
    {\thecolor}
    {\theradius}
    {\pos}
  }
  %%%%%%%%%% 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
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 

