Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download

📚 The CoCalc Library - books, templates and other resources

132941 views
License: OTHER
1
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2
% Start of pgf-pie.sty
3
%
4
% Some LaTeX macros for pie chart by using PGF/Tikz package.
5
% Home page of project: http://pgf-pie.googlecode.com/
6
% Author: Xu Yuan <[email protected]>
7
%
8
9
\NeedsTeXFormat{LaTeX2e}[1999/12/01]
10
\ProvidesPackage{pgf-pie}[2011/10/02 v0.2 Some LaTeX macros for pie
11
chart by using PGF/Tikz package.]
12
13
\RequirePackage{tikz}
14
\RequirePackage{ifthen}
15
\RequirePackage{scalefnt}
16
17
18
% args:
19
% #1: begin angle
20
% #2: end angle
21
% #3: number
22
% #4: label
23
% #5: explode
24
% #6: fill color
25
% #7: radius
26
% #8: center
27
\newcommand{\pgfpie@slice}[8]{
28
\pgfmathparse{0.5*(#1)+0.5*(#2)}
29
\let\midangle\pgfmathresult
30
31
\path (#8) -- ++(\midangle:#5) coordinate(O);
32
33
\pgfmathparse{#7+#5}
34
\let\radius\pgfmathresult
35
36
% slice
37
\draw[line join=round, fill=#6, \style] (O) -- ++(#1:#7) arc (#1:#2:#7) -- cycle;
38
39
\pgfmathparse{min(((#2)-(#1)-10)/110*(-0.3),0)}
40
\let\temp\pgfmathresult
41
\pgfmathparse{(max(\temp,-0.5) + 0.8)*#7}
42
\let\innerpos\pgfmathresult
43
44
\ifthenelse{\equal{\pgfpie@text}{inside}}
45
{
46
% label and number together
47
\path (O) -- ++(\midangle:\innerpos) node
48
{\scalefont{#3}\shortstack{#4\\\beforenumber#3\afternumber}};
49
}
50
{
51
% label
52
\iflegend
53
\else
54
\path (O) -- ++ (\midangle:\radius)
55
node[inner sep=0, \pgfpie@text=\midangle:#4]{};
56
\fi
57
58
% number
59
\path (O) -- ++(\midangle:\innerpos) node
60
{\scalefont{#3}\beforenumber#3\afternumber};
61
}
62
}
63
64
\newcommand{\pgfpie@findColor}[1]
65
{
66
\pgfmathparse{int(mod(#1,\value{pgfpie@colorLength}))}
67
\let\ci\pgfmathresult
68
\foreach \c [count=\j from 0] in \color {
69
\ifnum \j=\ci
70
\xdef\thecolor{\c}
71
\thecolor
72
\breakforeach
73
\fi
74
}
75
}
76
77
\newcommand{\pgfpie@findExplode}[1]
78
{
79
\pgfmathparse{int(mod(#1,\value{pgfpie@explodeLength}))}
80
\let\ei\pgfmathresult
81
\foreach \e [count=\j from 0] in \explode {
82
\ifnum \j=\ei
83
\xdef\theexplode{\e}
84
\breakforeach
85
\fi
86
}
87
}
88
89
% #1: bottom left point
90
% #2: size
91
% #3: number
92
% #4: color
93
% #5: text
94
\newcommand{\pgfpie@square}[5]
95
{
96
\ifthenelse{\equal{\pgfpie@text}{inside}}
97
{
98
\draw[fill=#4, \style] (#1) rectangle node
99
{\scalefont{#3}\shortstack{#5\\\beforenumber#3\afternumber}} ++(#2);
100
}
101
{
102
\draw[fill=#4, \style] (#1) rectangle node
103
{\scalefont{#3}\beforenumber#3\afternumber} ++(#2);
104
}
105
}
106
107
% #1: pos
108
% #2: radius
109
% #3: number
110
% #4: color
111
% $5: style
112
% $6: label
113
\newcommand{\pgfpie@cloud}[6]
114
{
115
\draw[fill=#4, #5] (#1) circle[radius=#2];
116
\ifthenelse{\equal{\pgfpie@text}{inside}}
117
{
118
\node at (#1) {\scalefont{#3}\shortstack{#6\\\beforenumber#3\afternumber}};
119
}
120
{
121
\node at (#1) {\scalefont{#3}\beforenumber#3\afternumber};
122
}
123
}
124
125
\newlength{\pgfpie@angleEnd}
126
\newcounter{pgfpie@explodeLength}
127
\newcounter{pgfpie@colorLength}
128
\newcounter{pgfpie@sliceLength}
129
130
\def\setexplode#1\pgfeov{\def\explode{#1}}
131
\pgfkeyslet{/explode/.@cmd}{\setexplode}
132
133
\def\setcolor#1\pgfeov{\def\color{#1}}
134
\pgfkeyslet{/color/.@cmd}{\setcolor}
135
136
\def\setradius#1\pgfeov{\def\radius{#1}}
137
\pgfkeyslet{/radius/.@cmd}{\setradius}
138
139
\def\setpos#1\pgfeov{\def\pos{#1}}
140
\pgfkeyslet{/pos/.@cmd}{\setpos}
141
142
\def\setstyle#1\pgfeov{\def\style{#1}}
143
\pgfkeyslet{/style/.@cmd}{\setstyle}
144
145
\def\setbeforenumber#1\pgfeov{\def\beforenumber{#1}}
146
\pgfkeyslet{/before number/.@cmd}{\setbeforenumber}
147
148
\def\setafternumber#1\pgfeov{\def\afternumber{#1}}
149
\pgfkeyslet{/after number/.@cmd}{\setafternumber}
150
151
\def\settext#1\pgfeov{\xdef\pgfpie@text{#1}}
152
\pgfkeyslet{/text/.@cmd}{\settext}
153
154
\def\setsum#1\pgfeov{\xdef\pgfpie@sum{#1}}
155
\pgfkeyslet{/sum/.@cmd}{\setsum}
156
157
\def\setrotate#1\pgfeov{\xdef\rotate{#1}}
158
\pgfkeyslet{/rotate/.@cmd}{\setrotate}
159
160
\newif\ifpolar
161
\pgfkeys{/polar/.is if=polar}
162
163
\newif\iflegend
164
165
\newif\ifsquare
166
\pgfkeys{/square/.is if=square}
167
168
\newif\ifcloud
169
\pgfkeys{/cloud/.is if=cloud}
170
171
\newif\ifscalefont
172
\pgfkeys{/scale font/.is if=scalefont}
173
\let\scalefontorg\scalefont
174
\renewcommand{\scalefont}[1]
175
{
176
\ifscalefont
177
\pgfmathparse{#1 / \pgfpie@sum * 3 + 0.9}
178
\scalefontorg{\pgfmathresult}
179
\fi
180
}
181
182
\newcommand{\pie}[2][]
183
{
184
% load default parameters
185
\pgfkeys{
186
explode=0,
187
color={blue!60, cyan!60, yellow!60, orange!60, red!60,
188
blue!60!cyan!60, cyan!60!yellow!60, red!60!cyan!60,
189
red!60!blue!60, orange!60!cyan!60},
190
radius=3,
191
pos={0,0},
192
style={thick},
193
before number=,
194
after number=,
195
text=label,
196
sum=100,
197
rotate=0,
198
polar=false,
199
square=false,
200
cloud=false,
201
scale font=false,
202
}
203
% load user's parameters
204
\pgfkeys{#1}
205
% add percentage automatically
206
\ifthenelse{\equal{\pgfpie@sum}{100}}
207
{
208
\pgfkeys{after number=\%}
209
\pgfkeys{#1}
210
}{}
211
212
% legend or not
213
\ifthenelse{\equal{\pgfpie@text}{legend}}
214
{\legendtrue}
215
{\legendfalse}
216
217
% handle sum
218
\ifthenelse{\equal{\pgfpie@sum}{auto}}
219
{
220
% sum all input
221
\xdef\pgfpie@sum{0}
222
\foreach \p/\t in {#2}
223
{
224
\pgfmathparse{\pgfpie@sum + \p}
225
\xdef\pgfpie@sum{\pgfmathresult}
226
}
227
}
228
{}
229
230
% init counters
231
\setcounter{pgfpie@explodeLength}{0}
232
\foreach \e in \explode { \addtocounter{pgfpie@explodeLength}{1} }
233
234
\setcounter{pgfpie@colorLength}{0}
235
\foreach \c in \color { \addtocounter{pgfpie@colorLength}{1} }
236
237
\pgfmathsetlength{\pgfpie@angleEnd}{0}
238
239
\setcounter{pgfpie@sliceLength}{0}
240
\foreach \p/\e in {#2} { \addtocounter{pgfpie@sliceLength}{1} }
241
242
\ifsquare
243
%%%%%%%%%% SQUARE PIE BEGIN %%%%%%%%%%%
244
\pgfmathparse{\radius*2}
245
\xdef\verticalLength{\pgfmathresult}
246
\xdef\horizontalLength{\pgfmathresult}
247
\path (\pos) -- ++(-\radius, -\radius) coordinate (start);
248
\pgfmathparse{\verticalLength * \horizontalLength / \pgfpie@sum}
249
\let\squareUnit\pgfmathresult
250
251
% drawing loop
252
\foreach \p/\t [count=\i from 0] in {#2}
253
{
254
\pgfpie@findColor{\i}
255
256
\ifthenelse{\lengthtest{\verticalLength cm > \horizontalLength cm}}
257
{
258
\pgfmathparse{\p * \squareUnit / \horizontalLength}
259
\let\height\pgfmathresult
260
261
\pgfpie@square{start}{\horizontalLength,\height}
262
{\p}
263
{\thecolor}
264
{\t}
265
%label
266
\iflegend
267
\else
268
\ifthenelse{\equal{\pgfpie@text}{inside}}
269
{}
270
{
271
\path (start) -- ++(\horizontalLength,\height*0.5) node[inner
272
sep=0, \pgfpie@text=0:\t]{};
273
}
274
\fi
275
276
\pgfmathparse{\verticalLength - \height}
277
\xdef\verticalLength{\pgfmathresult}
278
\path (start) -- ++(0, \height) coordinate (start);
279
}
280
{
281
\pgfmathparse{\p * \squareUnit / \verticalLength }
282
\let\width\pgfmathresult
283
284
\pgfpie@square{start}{\width,\verticalLength}
285
{\p}
286
{\thecolor}
287
{\t}
288
%label
289
\iflegend
290
\else
291
\ifthenelse{\equal{\pgfpie@text}{inside}}
292
{}
293
{
294
\path (start) -- ++(\width*0.5,\verticalLength) node[inner
295
sep=0, \pgfpie@text=90:\t]{};
296
}
297
\fi
298
299
\pgfmathparse{\horizontalLength - \width}
300
\xdef\horizontalLength{\pgfmathresult}
301
\path (start) -- ++(\width, 0) coordinate (start);
302
}
303
}
304
305
%%%%%%%%%% SQUARE PIE END %%%%%%%%%%%
306
\else
307
\ifcloud
308
%%%%%%%%%% CLOUD PIE BGEIN %%%%%%%%%%%
309
% drawing loop
310
\foreach \p/\t [count=\i from 0] in {#2}
311
{
312
% find explode
313
\pgfpie@findExplode{\i}
314
\def\cloudGap{\theexplode + 0.1}
315
\pgfmathparse{sqrt(\p / \pgfpie@sum) * \radius}
316
\let\cloudR\pgfmathresult
317
\ifnum \i = 0
318
% first cloud
319
\coordinate (O) at (\pos);
320
\xdef\cloudRone{\cloudR}
321
\xdef\cloudExtendDir{180+\rotate}
322
\else
323
\ifnum \i = 1
324
% second cloud
325
\xdef\cloudRtwo{\cloudR}
326
\xdef\cloudExtendDir{45+\rotate}
327
\path (O) -- ++(\cloudExtendDir:\cloudRone+\cloudGap+\cloudRtwo) coordinate (O);
328
\else
329
% next cloud
330
\pgfmathparse{\cloudRone+\cloudGap+\cloudRtwo}
331
\let\la\pgfmathresult
332
\pgfmathparse{\cloudRone+\cloudGap+\cloudR}
333
\let\lb\pgfmathresult
334
\pgfmathparse{\cloudRtwo+\cloudGap+\cloudR}
335
\let\lc\pgfmathresult
336
\pgfmathparse{\la^2+\lc^2-\lb^2}
337
\let\tmp\pgfmathresult
338
\pgfmathparse{180 - acos(\tmp / 2 / \la / \lc)}
339
\let\cloudRot\pgfmathresult
340
\ifodd \i
341
\pgfmathparse{-\cloudRot}
342
\let\cloudRot\pgfmathresult
343
\fi
344
\pgfmathparse{\cloudExtendDir - \cloudRot}
345
\xdef\cloudExtendDir{\pgfmathresult}
346
\path (O) -- ++(\cloudExtendDir:\lc) coordinate (O);
347
\xdef\cloudRone{\cloudRtwo}
348
\xdef\cloudRtwo{\cloudR}
349
\fi
350
\fi
351
352
% find color
353
\pgfpie@findColor{\i}
354
355
\pgfpie@cloud{O}{\cloudR}{\p}
356
{\thecolor}{\style}{\t}
357
358
% label
359
\iflegend
360
\else
361
\ifthenelse{\equal{\pgfpie@text}{inside}}
362
{}
363
{
364
\path (O) -- ++(\cloudExtendDir:\cloudR)
365
node[inner sep=0, \pgfpie@text=\cloudExtendDir:\t] {};
366
}
367
\fi
368
}
369
%%%%%%%%%% CLOUD PIE BGEIN %%%%%%%%%%%
370
\else
371
%%%%%%%%%% CIRCLE PIE BGEIN %%%%%%%%%%%
372
\ifpolar
373
\xdef\maxValue{0}
374
\foreach \p/\e in {#2} {
375
\ifnum \maxValue < \p
376
\xdef\maxValue{\p}
377
\fi
378
}
379
\pgfmathparse{\pgfpie@sum / \value{pgfpie@sliceLength}}
380
\xdef\polarangle{\pgfmathresult}
381
\pgfmathparse{\radius / sqrt(\maxValue)}
382
\xdef\polarRadiusUnit{\pgfmathresult}
383
\else
384
\xdef\theradius{\radius}
385
\fi
386
387
\xdef\pgfpie@angleBegin{\the\pgfpie@angleEnd}
388
% drawing loop
389
\foreach \p/\t [count=\i from 0] in {#2}
390
{
391
\pgfmathsetlength{\pgfpie@angleEnd}{\pgfpie@angleBegin}
392
\ifpolar
393
% Polar area diagram
394
\pgfmathaddtolength{\pgfpie@angleEnd}{\polarangle}
395
\pgfmathparse{sqrt(\p) * \polarRadiusUnit}
396
\xdef\theradius{\pgfmathresult}
397
\else
398
% normal pie
399
\pgfmathaddtolength{\pgfpie@angleEnd}{\p}
400
\fi
401
402
% find explode
403
\pgfpie@findExplode{\i}
404
405
% find color
406
\pgfpie@findColor{\i}
407
\pgfpie@slice{\pgfpie@angleBegin/\pgfpie@sum*360+\rotate}
408
{\the\pgfpie@angleEnd/\pgfpie@sum*360+\rotate}
409
{\p}
410
{\t}
411
{\theexplode}
412
{\thecolor}
413
{\theradius}
414
{\pos}
415
\xdef\pgfpie@angleBegin{\the\pgfpie@angleEnd}
416
}
417
%%%%%%%%%% CIRCLE PIE END %%%%%%%%%%%
418
\fi
419
\fi
420
421
% legend
422
\iflegend
423
\coordinate[xshift=0.8cm,
424
yshift=(\value{pgfpie@sliceLength}*0.5+1)*0.5cm] (legendpos) at
425
(current bounding box.east);
426
427
\begin{scope}[node distance=0.5cm]
428
\foreach \p/\t [count=\i from 0] in {#2}
429
{
430
\pgfpie@findColor{\i}
431
\node[draw, fill=\thecolor, \style, below of=legendpos, label=0:\t] (legendpos) {};
432
}
433
\end{scope}
434
\fi
435
}
436
437
%%% End of pgf-pie.sty
438
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
439
440
441