forked from anuraghazra/github-readme-stats
-
Notifications
You must be signed in to change notification settings - Fork 0
/
renderTopLanguages.js
108 lines (93 loc) · 2.96 KB
/
renderTopLanguages.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
const { getCardColors, FlexLayout, clampValue } = require("../src/utils");
const createProgressNode = ({ width, color, name, progress }) => {
const paddingRight = 95;
const progressTextX = width - paddingRight + 10;
const progressWidth = width - paddingRight;
const progressPercentage = clampValue(progress, 2, 100);
return `
<text data-testid="lang-name" x="2" y="15" class="lang-name">${name}</text>
<text x="${progressTextX}" y="34" class="lang-name">${progress}%</text>
<svg width="${progressWidth}">
<rect rx="5" ry="5" x="0" y="25" width="${progressWidth}" height="8" fill="#ddd"></rect>
<rect
height="8"
fill="${color}"
rx="5" ry="5" x="0" y="25"
data-testid="lang-progress"
width="${progressPercentage}%"
>
</rect>
</svg>
`;
};
const lowercaseTrim = (name) => name.toLowerCase().trim();
const renderTopLanguages = (topLangs, options = {}) => {
const {
hide_title,
card_width,
title_color,
text_color,
bg_color,
hide,
theme,
} = options;
let langs = Object.values(topLangs);
let langsToHide = {};
// populate langsToHide map for quick lookup
// while filtering out
if (hide) {
hide.forEach((langName) => {
langsToHide[lowercaseTrim(langName)] = true;
});
}
// filter out langauges to be hidden
langs = langs
.sort((a, b) => b.size - a.size)
.filter((lang) => {
return !langsToHide[lowercaseTrim(lang.name)];
});
const totalSize = langs.reduce((acc, curr) => {
return acc + curr.size;
}, 0);
// returns theme based colors with proper overrides and defaults
const { titleColor, textColor, bgColor } = getCardColors({
title_color,
text_color,
bg_color,
theme,
});
const width = isNaN(card_width) ? 300 : card_width;
let height = 45 + (langs.length + 1) * 40;
if (hide_title) {
height -= 30;
}
return `
<svg width="${width}" height="${height}" viewBox="0 0 ${width} ${height}" fill="none" xmlns="http://www.w3.org/2000/svg">
<style>
.header { font: 600 18px 'Segoe UI', Ubuntu, Sans-Serif; fill: ${titleColor} }
.lang-name { font: 400 11px 'Segoe UI', Ubuntu, Sans-Serif; fill: ${textColor} }
</style>
<rect data-testid="card-bg" x="0.5" y="0.5" width="99.7%" height="99%" rx="4.5" fill="${bgColor}" stroke="#E4E2E2"/>
${
hide_title
? ""
: `<text data-testid="header" x="25" y="35" class="header">Top Languages</text>`
}
<svg data-testid="lang-items" x="25" y="${hide_title ? 25 : 55}">
${FlexLayout({
items: langs.map((lang) => {
return createProgressNode({
width: width,
name: lang.name,
color: lang.color || "#858585",
progress: ((lang.size / totalSize) * 100).toFixed(2),
});
}),
gap: 40,
direction: "column",
}).join("")}
</svg>
</svg>
`;
};
module.exports = renderTopLanguages;