Skip to content

Commit d31803b

Browse files
authored
Merge pull request #22 from yoshi389111/add_animate_pie_chart
feat: animate pie chart
2 parents b2cde28 + 1fbb24b commit d31803b

File tree

3 files changed

+77
-13
lines changed

3 files changed

+77
-13
lines changed

dist/index.js

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,7 @@ const OTHER_NAME = 'other';
336336
const OTHER_COLOR = '#444444';
337337
const bgcolor = '#ffffff';
338338
const fgcolor = '#00000f';
339-
const createPieLanguage = (svg, userInfo, x, y, width, height) => {
339+
const createPieLanguage = (svg, userInfo, x, y, width, height, isAnimate) => {
340340
if (userInfo.totalContributions === 0) {
341341
return;
342342
}
@@ -352,6 +352,11 @@ const createPieLanguage = (svg, userInfo, x, y, width, height) => {
352352
contributions: otherContributions,
353353
});
354354
}
355+
const animeSteps = 5;
356+
const animateOpacity = (num) => Array(languages.length + animeSteps)
357+
.fill('')
358+
.map((d, i) => (i < num ? 0 : Math.min((i - num) / animeSteps, 1)))
359+
.join(';');
355360
const radius = height / 2;
356361
const margin = radius / 10;
357362
const row = 8;
@@ -367,7 +372,7 @@ const createPieLanguage = (svg, userInfo, x, y, width, height) => {
367372
.append('g')
368373
.attr('transform', `translate(${radius * 2.1}, ${0})`);
369374
// markers for label
370-
groupLabel
375+
const markers = groupLabel
371376
.selectAll(null)
372377
.data(pieData)
373378
.enter()
@@ -379,8 +384,16 @@ const createPieLanguage = (svg, userInfo, x, y, width, height) => {
379384
.attr('fill', (d) => d.data.color)
380385
.attr('stroke', bgcolor)
381386
.attr('stroke-width', '1px');
387+
if (isAnimate) {
388+
markers
389+
.append('animate')
390+
.attr('attributeName', 'fill-opacity')
391+
.attr('values', (d, i) => animateOpacity(i))
392+
.attr('dur', '3s')
393+
.attr('repeatCount', '1');
394+
}
382395
// labels
383-
groupLabel
396+
const labels = groupLabel
384397
.selectAll(null)
385398
.data(pieData)
386399
.enter()
@@ -391,12 +404,20 @@ const createPieLanguage = (svg, userInfo, x, y, width, height) => {
391404
.attr('y', (d) => (d.index + offset) * (height / row))
392405
.attr('fill', fgcolor)
393406
.attr('font-size', `${fontSize}px`);
407+
if (isAnimate) {
408+
labels
409+
.append('animate')
410+
.attr('attributeName', 'fill-opacity')
411+
.attr('values', (d, i) => animateOpacity(i))
412+
.attr('dur', '3s')
413+
.attr('repeatCount', '1');
414+
}
394415
const arc = d3
395416
.arc()
396417
.outerRadius(radius - margin)
397418
.innerRadius(radius / 2);
398419
// pie chart
399-
group
420+
const paths = group
400421
.append('g')
401422
.attr('transform', `translate(${radius}, ${radius})`)
402423
.selectAll(null)
@@ -406,9 +427,18 @@ const createPieLanguage = (svg, userInfo, x, y, width, height) => {
406427
.attr('d', arc)
407428
.style('fill', (d) => d.data.color)
408429
.attr('stroke', bgcolor)
409-
.attr('stroke-width', '2px')
430+
.attr('stroke-width', '2px');
431+
paths
410432
.append('title')
411433
.text((d) => `${d.data.language} ${d.data.contributions}`);
434+
if (isAnimate) {
435+
paths
436+
.append('animate')
437+
.attr('attributeName', 'fill-opacity')
438+
.attr('values', (d, i) => animateOpacity(i))
439+
.attr('dur', '3s')
440+
.attr('repeatCount', '1');
441+
}
412442
};
413443
exports.createPieLanguage = createPieLanguage;
414444
//# sourceMappingURL=create-pie-language.js.map
@@ -605,7 +635,7 @@ const createSvg = (userInfo, seasonMode, isAnimate) => {
605635
// pie chart
606636
const pieHeight = 200 * 1.3;
607637
const pieWidth = pieHeight * 2;
608-
pie.createPieLanguage(svg, userInfo, 40, height - pieHeight - 70, pieWidth, pieHeight);
638+
pie.createPieLanguage(svg, userInfo, 40, height - pieHeight - 70, pieWidth, pieHeight, isAnimate);
609639
const group = svg.append('g');
610640
const positionXContrib = (width * 3) / 10;
611641
const positionYContrib = height - 20;

src/create-pie-language.ts

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ export const createPieLanguage = (
1212
x: number,
1313
y: number,
1414
width: number,
15-
height: number
15+
height: number,
16+
isAnimate: boolean
1617
): void => {
1718
if (userInfo.totalContributions === 0) {
1819
return;
@@ -31,6 +32,13 @@ export const createPieLanguage = (
3132
});
3233
}
3334

35+
const animeSteps = 5;
36+
const animateOpacity = (num: number) =>
37+
Array<string>(languages.length + animeSteps)
38+
.fill('')
39+
.map((d, i) => (i < num ? 0 : Math.min((i - num) / animeSteps, 1)))
40+
.join(';');
41+
3442
const radius = height / 2;
3543
const margin = radius / 10;
3644

@@ -51,7 +59,7 @@ export const createPieLanguage = (
5159
.attr('transform', `translate(${radius * 2.1}, ${0})`);
5260

5361
// markers for label
54-
groupLabel
62+
const markers = groupLabel
5563
.selectAll(null)
5664
.data(pieData)
5765
.enter()
@@ -63,9 +71,17 @@ export const createPieLanguage = (
6371
.attr('fill', (d) => d.data.color)
6472
.attr('stroke', bgcolor)
6573
.attr('stroke-width', '1px');
74+
if (isAnimate) {
75+
markers
76+
.append('animate')
77+
.attr('attributeName', 'fill-opacity')
78+
.attr('values', (d, i) => animateOpacity(i))
79+
.attr('dur', '3s')
80+
.attr('repeatCount', '1');
81+
}
6682

6783
// labels
68-
groupLabel
84+
const labels = groupLabel
6985
.selectAll(null)
7086
.data(pieData)
7187
.enter()
@@ -76,14 +92,22 @@ export const createPieLanguage = (
7692
.attr('y', (d) => (d.index + offset) * (height / row))
7793
.attr('fill', fgcolor)
7894
.attr('font-size', `${fontSize}px`);
79-
95+
if (isAnimate) {
96+
labels
97+
.append('animate')
98+
.attr('attributeName', 'fill-opacity')
99+
.attr('values', (d, i) => animateOpacity(i))
100+
.attr('dur', '3s')
101+
.attr('repeatCount', '1');
102+
}
103+
80104
const arc = d3
81105
.arc<d3.PieArcDatum<type.LangInfo>>()
82106
.outerRadius(radius - margin)
83107
.innerRadius(radius / 2);
84108

85109
// pie chart
86-
group
110+
const paths = group
87111
.append('g')
88112
.attr('transform', `translate(${radius}, ${radius})`)
89113
.selectAll(null)
@@ -93,7 +117,16 @@ export const createPieLanguage = (
93117
.attr('d', arc)
94118
.style('fill', (d) => d.data.color)
95119
.attr('stroke', bgcolor)
96-
.attr('stroke-width', '2px')
120+
.attr('stroke-width', '2px');
121+
paths
97122
.append('title')
98123
.text((d) => `${d.data.language} ${d.data.contributions}`);
124+
if (isAnimate) {
125+
paths
126+
.append('animate')
127+
.attr('attributeName', 'fill-opacity')
128+
.attr('values', (d, i) => animateOpacity(i))
129+
.attr('dur', '3s')
130+
.attr('repeatCount', '1');
131+
}
99132
};

src/create-svg.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,8 @@ export const createSvg = (
7575
40,
7676
height - pieHeight - 70,
7777
pieWidth,
78-
pieHeight
78+
pieHeight,
79+
isAnimate
7980
);
8081

8182
const group = svg.append('g');

0 commit comments

Comments
 (0)