forked from mirrored/github-readme-stats
Merge pull request #2527 from Zo-Bro-23/custom-cards
Transfer branch from my fork to main repo
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
import { renderStatsCard } from "../../src/cards/stats-card.js";
|
||||
import {
|
||||
clampValue,
|
||||
CONSTANTS,
|
||||
parseArray,
|
||||
parseBoolean,
|
||||
renderError,
|
||||
} from "../../src/common/utils.js";
|
||||
|
||||
export default async (req, res) => {
|
||||
const {
|
||||
hide,
|
||||
hide_title,
|
||||
hide_border,
|
||||
card_width,
|
||||
hide_rank,
|
||||
show_icons,
|
||||
line_height,
|
||||
title_color,
|
||||
ring_color,
|
||||
icon_color,
|
||||
text_color,
|
||||
text_bold,
|
||||
bg_color,
|
||||
theme,
|
||||
disable_animations,
|
||||
border_radius,
|
||||
border_color,
|
||||
} = req.query;
|
||||
res.setHeader("Content-Type", "image/svg+xml");
|
||||
|
||||
try {
|
||||
const stats = {
|
||||
totalStars: req.query.total_stars,
|
||||
totalCommits: req.query.total_commits,
|
||||
totalIssues: req.query.total_issues,
|
||||
totalPRs: req.query.total_prs,
|
||||
contributedTo: req.query.total_contribs,
|
||||
rank: {
|
||||
level: req.query.level || 'S',
|
||||
score: req.query.score || 10
|
||||
},
|
||||
starsTitle: req.query.stars_title,
|
||||
commitsTitle: req.query.commits_title,
|
||||
issuesTitle: req.query.issues_title,
|
||||
PRsTitle: req.query.prs_title,
|
||||
contribsTitle: req.query.contribs_title,
|
||||
title: req.query.title,
|
||||
};
|
||||
|
||||
return res.send(
|
||||
renderStatsCard(stats, {
|
||||
hide: parseArray(hide),
|
||||
show_icons: parseBoolean(show_icons),
|
||||
hide_title: parseBoolean(hide_title),
|
||||
hide_border: parseBoolean(hide_border),
|
||||
card_width: parseInt(card_width, 10),
|
||||
hide_rank: parseBoolean(hide_rank),
|
||||
line_height,
|
||||
title_color,
|
||||
ring_color,
|
||||
icon_color,
|
||||
text_color,
|
||||
text_bold: parseBoolean(text_bold),
|
||||
bg_color,
|
||||
theme,
|
||||
border_radius,
|
||||
border_color,
|
||||
disable_animations: parseBoolean(disable_animations),
|
||||
}),
|
||||
);
|
||||
} catch (err) {
|
||||
return res.send(renderError(err.message, err.secondaryMessage));
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,51 @@
|
||||
import { renderRepoCard } from "../../src/cards/repo-card.js";
|
||||
import {
|
||||
clampValue,
|
||||
CONSTANTS,
|
||||
parseBoolean,
|
||||
renderError,
|
||||
} from "../../src/common/utils.js";
|
||||
|
||||
export default async (req, res) => {
|
||||
const {
|
||||
hide_border,
|
||||
title_color,
|
||||
icon_color,
|
||||
text_color,
|
||||
bg_color,
|
||||
theme,
|
||||
border_radius,
|
||||
border_color,
|
||||
} = req.query;
|
||||
|
||||
res.setHeader("Content-Type", "image/svg+xml");
|
||||
|
||||
try {
|
||||
const repoData = {
|
||||
name: req.query.title || "awesome/repo",
|
||||
description: req.query.description || "What an awesome repo!",
|
||||
primaryLanguage: {
|
||||
name: req.query.footer || "Awesome",
|
||||
color: req.query.badge ? `#${req.query.badge}` : "#4287f5",
|
||||
},
|
||||
starCount: req.query.stars || 12838,
|
||||
forkCount: req.query.forks || 8929,
|
||||
highlight: req.query.highlight || "AWESOME",
|
||||
};
|
||||
|
||||
return res.send(
|
||||
renderRepoCard(repoData, {
|
||||
hide_border: parseBoolean(hide_border),
|
||||
title_color,
|
||||
icon_color,
|
||||
text_color,
|
||||
bg_color,
|
||||
theme,
|
||||
border_radius,
|
||||
border_color,
|
||||
}),
|
||||
);
|
||||
} catch (err) {
|
||||
return res.send(renderError(err.message, err.secondaryMessage));
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,84 @@
|
||||
import { renderTopLanguages } from "../../src/cards/top-languages-card.js";
|
||||
import {
|
||||
clampValue,
|
||||
CONSTANTS,
|
||||
parseArray,
|
||||
parseBoolean,
|
||||
renderError,
|
||||
} from "../../src/common/utils.js";
|
||||
|
||||
export default async (req, res) => {
|
||||
const {
|
||||
hide_title,
|
||||
hide_border,
|
||||
card_width,
|
||||
title_color,
|
||||
text_color,
|
||||
bg_color,
|
||||
theme,
|
||||
layout,
|
||||
border_radius,
|
||||
border_color,
|
||||
} = req.query;
|
||||
res.setHeader("Content-Type", "image/svg+xml");
|
||||
|
||||
try {
|
||||
let topLangs = []
|
||||
if (req.query.langs) {
|
||||
const split = req.query.langs.split(";");
|
||||
split.forEach(lang => {
|
||||
let {
|
||||
name = "No Name",
|
||||
size = "0",
|
||||
color,
|
||||
text,
|
||||
} = JSON.parse(lang)
|
||||
topLangs.push({
|
||||
name,
|
||||
size,
|
||||
color: color ? `#${color}` : undefined,
|
||||
text,
|
||||
});
|
||||
});
|
||||
} else {
|
||||
topLangs = [
|
||||
{
|
||||
name: "Javascript",
|
||||
size: 50,
|
||||
color: "#4287f5",
|
||||
},
|
||||
{
|
||||
name: "Python",
|
||||
size: 30,
|
||||
color: "#eb4034",
|
||||
},
|
||||
{
|
||||
name: "Ruby",
|
||||
size: 20,
|
||||
color: "#32a852",
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
const title = req.query.title || "Most Used Languages";
|
||||
|
||||
return res.send(
|
||||
renderTopLanguages(topLangs, {
|
||||
hide_title: parseBoolean(hide_title),
|
||||
hide_border: parseBoolean(hide_border),
|
||||
card_width: parseInt(card_width, 10),
|
||||
title_color,
|
||||
text_color,
|
||||
bg_color,
|
||||
theme,
|
||||
layout,
|
||||
langs_count: topLangs.length,
|
||||
border_radius,
|
||||
border_color,
|
||||
title,
|
||||
}),
|
||||
);
|
||||
} catch (err) {
|
||||
return res.send(renderError(err.message, err.secondaryMessage));
|
||||
}
|
||||
};
|
||||
@@ -92,6 +92,7 @@ Visit <https://indiafightscorona.giveindia.org> and make a small donation to hel
|
||||
- [Repo Card Exclusive Options](#repo-card-exclusive-options)
|
||||
- [Language Card Exclusive Options](#language-card-exclusive-options)
|
||||
- [Wakatime Card Exclusive Option](#wakatime-card-exclusive-options)
|
||||
- [Wild Cards](#wild-cards)
|
||||
- [Deploy Yourself](#deploy-on-your-own-vercel-instance)
|
||||
- [Keep your fork up to date](#keep-your-fork-up-to-date)
|
||||
|
||||
@@ -509,6 +510,64 @@ By default, GitHub does not lay out the cards side by side. To do that, you can
|
||||
</a>
|
||||
```
|
||||
|
||||
## Wild Cards
|
||||
You can also generate custom cards with custom text and custom values (these do not show any GitHub statistics - they're custom values that you provide):
|
||||
<p>
|
||||
<img src="https://github-readme-stats.zohan.tech/api/wild/top-langs?langs=%7B%22name%22%3A%22Pop%22%2C%22size%22%3A60%2C%22color%22%3A%2232a852%22%2C%22text%22%3A%2260%20Hours%22%7D%3B%7B%22name%22%3A%22Reggae%22%2C%22size%22%3A40%2C%22color%22%3A%22fcba03%22%2C%22text%22%3A%2240%20Hours%22%7D%3B%7B%22name%22%3A%22Electronic%22%2C%22size%22%3A25%2C%22color%22%3A%224287f5%22%2C%22text%22%3A%2225%20Hours%22%7D%3B%7B%22name%22%3A%22Rap%22%2C%22size%22%3A15%2C%22color%22%3A%22eb4034%22%2C%22text%22%3A%2215%20Hours%22%7D%3B%7B%22name%22%3A%22Rock%22%2C%22size%22%3A10%2C%22color%22%3A%2232a852%22%2C%22text%22%3A%2210%20Hours%22%7D%3B%7B%22name%22%3A%22Other%22%2C%22size%22%3A5%2C%22color%22%3A%22fcba03%22%2C%22text%22%3A%225%20Hours%22%7D&title=Top%20Songs%20%F0%9F%8E%B5&theme=onedark&hide_border=true">
|
||||
<img src="https://github-readme-stats.zohan.tech/api/wild?theme=onedark&level=CUST&score=50&title=Custom%20Cards%20%F0%9F%98%8E&show_icons=true&prs_title=Another%20Custom%20Title&total_stars=283%20Hours&stars_title=Non-numerical%20Value&commits_title=Recap&total_commits=%F0%9F%99%83&contribs_title=Big%20Number&total_contribs=12381&hide_border=true">
|
||||
<img src="https://github-readme-stats.zohan.tech/api/wild/top-langs?langs=%7B%22name%22%3A%22Pop%22%2C%22size%22%3A60%2C%22color%22%3A%2232a852%22%7D%3B%7B%22name%22%3A%22Reggae%22%2C%22size%22%3A40%2C%22color%22%3A%22fcba03%22%7D%3B%7B%22name%22%3A%22Electronic%22%2C%22size%22%3A25%2C%22color%22%3A%224287f5%22%7D%3B%7B%22name%22%3A%22Rap%22%2C%22size%22%3A15%2C%22color%22%3A%22eb4034%22%7D%3B%7B%22name%22%3A%22Rock%22%2C%22size%22%3A10%2C%22color%22%3A%2232a852%22%7D%3B%7B%22name%22%3A%22Other%22%2C%22size%22%3A5%2C%22color%22%3A%22fcba03%22%7D&title=Top%20Songs%20%F0%9F%8E%B5&theme=onedark&layout=compact&hide_border=true">
|
||||
<img src="https://github-readme-stats.zohan.tech/api/wild/pin?theme=onedark&title=Custom%20Repo%20%F0%9F%8E%86&description=Custom%20repo%20with%20a%20custom%20description!&highlight=CUSTOM&footer=Custom%20Language%20%F0%9F%93%9D&stars=The%20Best&hide_border=true">
|
||||
</p>
|
||||
|
||||
The wild/custom cards can be generated by using the `/api/wild/`, `/api/wild/top-langs/`, and `/api/wild/pin/` endpoints. The following parameters can be provided:
|
||||
|
||||
### `/api/wild/`
|
||||
|
||||
<img src="https://github-readme-stats.zohan.tech/api/wild/?theme=dracula&hide_border=true&title=title&stars_title=stars_title&commits_title=commits_title&prs_title=prs_title&issues_title=issues_title&contribs_title=contribs_title&total_stars=total_stars&total_commits=total_commits&total_prs=total_prs&total_issues=total_issues&total_contribs=total_contribs&level=level&score=90">
|
||||
|
||||
Additionally, the `score` parameter must be given a value from `0` to `100` where `100` doesn't fill the circle at all, and `0` fills the circle completely (the demo above has `score=90`).
|
||||
|
||||
### `/api/wild/top-langs/`
|
||||
|
||||
<img src="https://github-readme-stats.zohan.tech/api/wild/top-langs?theme=dracula&hide_border=true&title=title&langs={%22name%22:%22Category1%22,%22size%22:30,%22color%22:%224287f5%22,%22text%22:%223%20thousand%22};{%22name%22:%22Category2%22,%22size%22:20,%22color%22:%22fcba03%22,%22text%22:%222%20thousand%22}">
|
||||
|
||||
Here, the languages are defined using the `langs` parameter. It is of the following format (JSON with `;` separating the objects):
|
||||
```json
|
||||
{
|
||||
"name": "Category1",
|
||||
"size": 60,
|
||||
"color": "4287f5",
|
||||
"text": "3 thousand"
|
||||
};
|
||||
{
|
||||
"name": "Category2",
|
||||
"size": 40,
|
||||
"color": "fcba03",
|
||||
"text": "3 thousand"
|
||||
}
|
||||
```
|
||||
|
||||
`name` is the name of the category. `size` is an arbitary size used to calculate percentages. This can be hours, percent, or any other unit you wish to use. `color` is the color of the category. `text` is what text to display next to the categry. If left blank, a percentage will be calculated and displayed.
|
||||
|
||||
### `/api/wild/pin/`
|
||||
|
||||
<img src="https://github-readme-stats.zohan.tech/api/wild/pin?theme=dracula&hide_border=true&title=title&description=description&highlight=highlight&stars=stars&forks=forks&footer=footer&badge=4287f5">
|
||||
|
||||
Here, the `badge` parameter was used to set the color of the small round icon (`4287f5`) was passed.
|
||||
|
||||
Finally, here are some specifications that apply to all three endpoints.
|
||||
|
||||
### All Three
|
||||
Colors are passed as hex codes without the `#` character. For example, `ffffff`. This is the same as the main API.
|
||||
|
||||
Parameters like `total_stars` and `forks` can accept both numbers and text. If a number is given, it will automatically be formatted to use k-notation for thousands.
|
||||
|
||||
Parameters that apply only to the main API such as `username`, `repo`, `show_owner`, `locale`, etc won't work for this API. Other parameters like `layout` and `text_color` ***will*** work.
|
||||
|
||||
The new parameters that have been added are explained above (shown in the images). Parameters are lowercase snake-cased like for the main API.
|
||||
|
||||
Finally, no parameter is required, and parameters that aren't given will default to the most sensible option (original titles, ambigous descriptions, theme-based colors, and fake numbers).
|
||||
|
||||
## Deploy on your own Vercel instance
|
||||
|
||||
#### :film_projector: [Check Out Step By Step Video Tutorial By @codeSTACKr](https://youtu.be/n6d4KHSKqGk?t=107)
|
||||
|
||||
+51
-35
@@ -87,16 +87,6 @@ const iconWithLabel = (icon, label, testid) => {
|
||||
* @returns {string} Repository card SVG object.
|
||||
*/
|
||||
const renderRepoCard = (repo, options = {}) => {
|
||||
const {
|
||||
name,
|
||||
nameWithOwner,
|
||||
description,
|
||||
primaryLanguage,
|
||||
isArchived,
|
||||
isTemplate,
|
||||
starCount,
|
||||
forkCount,
|
||||
} = repo;
|
||||
const {
|
||||
hide_border = false,
|
||||
title_color,
|
||||
@@ -109,6 +99,42 @@ const renderRepoCard = (repo, options = {}) => {
|
||||
border_color,
|
||||
locale,
|
||||
} = options;
|
||||
|
||||
const i18n = new I18n({
|
||||
locale,
|
||||
translations: repoCardLocales,
|
||||
});
|
||||
|
||||
const colors = getCardColors({
|
||||
title_color,
|
||||
icon_color,
|
||||
text_color,
|
||||
bg_color,
|
||||
border_color,
|
||||
theme,
|
||||
});
|
||||
|
||||
const {
|
||||
name,
|
||||
nameWithOwner,
|
||||
description,
|
||||
primaryLanguage,
|
||||
isArchived,
|
||||
isTemplate,
|
||||
starCount,
|
||||
forkCount,
|
||||
} = repo;
|
||||
|
||||
const highlight = repo.highlight
|
||||
? // @ts-ignore
|
||||
getBadgeSVG(repo.highlight, colors.textColor)
|
||||
: isTemplate
|
||||
? // @ts-ignore
|
||||
getBadgeSVG(i18n.t("repocard.template"), colors.textColor)
|
||||
: isArchived
|
||||
? // @ts-ignore
|
||||
getBadgeSVG(i18n.t("repocard.archived"), colors.textColor)
|
||||
: ""
|
||||
|
||||
const lineHeight = 10;
|
||||
const header = show_owner ? nameWithOwner : name;
|
||||
@@ -125,27 +151,25 @@ const renderRepoCard = (repo, options = {}) => {
|
||||
const height =
|
||||
(descriptionLines > 1 ? 120 : 110) + descriptionLines * lineHeight;
|
||||
|
||||
const i18n = new I18n({
|
||||
locale,
|
||||
translations: repoCardLocales,
|
||||
});
|
||||
|
||||
// returns theme based colors with proper overrides and defaults
|
||||
const colors = getCardColors({
|
||||
title_color,
|
||||
icon_color,
|
||||
text_color,
|
||||
bg_color,
|
||||
border_color,
|
||||
theme,
|
||||
});
|
||||
|
||||
const svgLanguage = primaryLanguage
|
||||
? createLanguageNode(langName, langColor)
|
||||
: "";
|
||||
|
||||
const totalStars = kFormatter(starCount);
|
||||
const totalForks = kFormatter(forkCount);
|
||||
|
||||
let totalStars
|
||||
let totalForks
|
||||
if (isNaN(starCount)) {
|
||||
totalStars = starCount;
|
||||
} else {
|
||||
totalStars = kFormatter(starCount);
|
||||
}
|
||||
if (isNaN(forkCount)) {
|
||||
totalForks = forkCount;
|
||||
} else {
|
||||
totalForks = kFormatter(forkCount);
|
||||
}
|
||||
|
||||
const svgStars = iconWithLabel(icons.star, totalStars, "stargazers");
|
||||
const svgForks = iconWithLabel(icons.fork, totalForks, "forkcount");
|
||||
|
||||
@@ -180,15 +204,7 @@ const renderRepoCard = (repo, options = {}) => {
|
||||
`);
|
||||
|
||||
return card.render(`
|
||||
${
|
||||
isTemplate
|
||||
? // @ts-ignore
|
||||
getBadgeSVG(i18n.t("repocard.template"), colors.textColor)
|
||||
: isArchived
|
||||
? // @ts-ignore
|
||||
getBadgeSVG(i18n.t("repocard.archived"), colors.textColor)
|
||||
: ""
|
||||
}
|
||||
${highlight}
|
||||
|
||||
<text class="description" x="25" y="-5">
|
||||
${descriptionSvg}
|
||||
|
||||
+44
-32
@@ -40,7 +40,12 @@ const createTextNode = ({
|
||||
shiftValuePos,
|
||||
bold,
|
||||
}) => {
|
||||
const kValue = kFormatter(value);
|
||||
let kValue
|
||||
if (isNaN(value)) {
|
||||
kValue = value;
|
||||
} else {
|
||||
kValue = kFormatter(value);
|
||||
}
|
||||
const staggerDelay = (index + 3) * 150;
|
||||
|
||||
const labelOffset = showIcons ? `x="25"` : "";
|
||||
@@ -75,15 +80,6 @@ const createTextNode = ({
|
||||
* @returns {string} The stats card SVG object.
|
||||
*/
|
||||
const renderStatsCard = (stats = {}, options = { hide: [] }) => {
|
||||
const {
|
||||
name,
|
||||
totalStars,
|
||||
totalCommits,
|
||||
totalIssues,
|
||||
totalPRs,
|
||||
contributedTo,
|
||||
rank,
|
||||
} = stats;
|
||||
const {
|
||||
hide = [],
|
||||
show_icons = false,
|
||||
@@ -106,6 +102,37 @@ const renderStatsCard = (stats = {}, options = { hide: [] }) => {
|
||||
locale,
|
||||
disable_animations = false,
|
||||
} = options;
|
||||
|
||||
const name = stats.name || "GitHub User"
|
||||
|
||||
const apostrophe = ["x", "s"].includes(name.slice(-1).toLocaleLowerCase())
|
||||
? ""
|
||||
: "s";
|
||||
|
||||
const i18n = new I18n({
|
||||
locale,
|
||||
translations: statCardLocales({ name, apostrophe }),
|
||||
});
|
||||
|
||||
const {
|
||||
totalStars = "2018",
|
||||
totalCommits = "29019",
|
||||
totalIssues = "203",
|
||||
totalPRs = "127",
|
||||
contributedTo = "232",
|
||||
rank = {
|
||||
level: "S",
|
||||
score: 10
|
||||
},
|
||||
starsTitle = i18n.t("statcard.totalstars"),
|
||||
commitsTitle = `${i18n.t("statcard.commits")}${
|
||||
include_all_commits ? "" : ` (${new Date().getFullYear()})`
|
||||
}`,
|
||||
issuesTitle = i18n.t("statcard.issues"),
|
||||
PRsTitle = i18n.t("statcard.prs"),
|
||||
contribsTitle = i18n.t("statcard.contribs") + " (last year)",
|
||||
title = i18n.t("statcard.title"),
|
||||
} = stats;
|
||||
|
||||
const lheight = parseInt(String(line_height), 10);
|
||||
|
||||
@@ -121,45 +148,35 @@ const renderStatsCard = (stats = {}, options = { hide: [] }) => {
|
||||
theme,
|
||||
});
|
||||
|
||||
const apostrophe = ["x", "s"].includes(name.slice(-1).toLocaleLowerCase())
|
||||
? ""
|
||||
: "s";
|
||||
const i18n = new I18n({
|
||||
locale,
|
||||
translations: statCardLocales({ name, apostrophe }),
|
||||
});
|
||||
|
||||
// Meta data for creating text nodes with createTextNode function
|
||||
const STATS = {
|
||||
stars: {
|
||||
icon: icons.star,
|
||||
label: i18n.t("statcard.totalstars"),
|
||||
label: starsTitle,
|
||||
value: totalStars,
|
||||
id: "stars",
|
||||
},
|
||||
commits: {
|
||||
icon: icons.commits,
|
||||
label: `${i18n.t("statcard.commits")}${
|
||||
include_all_commits ? "" : ` (${new Date().getFullYear()})`
|
||||
}`,
|
||||
label: commitsTitle,
|
||||
value: totalCommits,
|
||||
id: "commits",
|
||||
},
|
||||
prs: {
|
||||
icon: icons.prs,
|
||||
label: i18n.t("statcard.prs"),
|
||||
label: PRsTitle,
|
||||
value: totalPRs,
|
||||
id: "prs",
|
||||
},
|
||||
issues: {
|
||||
icon: icons.issues,
|
||||
label: i18n.t("statcard.issues"),
|
||||
label: issuesTitle,
|
||||
value: totalIssues,
|
||||
id: "issues",
|
||||
},
|
||||
contribs: {
|
||||
icon: icons.contribs,
|
||||
label: i18n.t("statcard.contribs") + " (last year)",
|
||||
label: contribsTitle,
|
||||
value: contributedTo,
|
||||
id: "contribs",
|
||||
},
|
||||
@@ -215,7 +232,7 @@ const renderStatsCard = (stats = {}, options = { hide: [] }) => {
|
||||
});
|
||||
|
||||
const calculateTextWidth = () => {
|
||||
return measureText(custom_title ? custom_title : i18n.t("statcard.title"));
|
||||
return measureText(custom_title ? custom_title : title);
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -241,7 +258,7 @@ const renderStatsCard = (stats = {}, options = { hide: [] }) => {
|
||||
|
||||
const card = new Card({
|
||||
customTitle: custom_title,
|
||||
defaultTitle: i18n.t("statcard.title"),
|
||||
defaultTitle: title,
|
||||
width,
|
||||
height,
|
||||
border_radius,
|
||||
@@ -306,11 +323,6 @@ const renderStatsCard = (stats = {}, options = { hide: [] }) => {
|
||||
const labels = Object.keys(STATS)
|
||||
.filter((key) => !hide.includes(key))
|
||||
.map((key) => {
|
||||
if (key === "commits") {
|
||||
return `${i18n.t("statcard.commits")} ${
|
||||
include_all_commits ? "" : `in ${new Date().getFullYear()}`
|
||||
} : ${totalStars}`;
|
||||
}
|
||||
return `${STATS[key].label}: ${STATS[key].value}`;
|
||||
})
|
||||
.join(", ");
|
||||
|
||||
@@ -47,6 +47,7 @@ const getLongestLang = (arr) =>
|
||||
* @param {number} props.index Index of the programming language.
|
||||
* @returns {string} Programming language SVG node.
|
||||
*/
|
||||
|
||||
const createProgressTextNode = ({ width, color, name, progress, index }) => {
|
||||
const staggerDelay = (index + 3) * 150;
|
||||
const paddingRight = 95;
|
||||
@@ -56,7 +57,7 @@ const createProgressTextNode = ({ width, color, name, progress, index }) => {
|
||||
return `
|
||||
<g class="stagger" style="animation-delay: ${staggerDelay}ms">
|
||||
<text data-testid="lang-name" x="2" y="15" class="lang-name">${name}</text>
|
||||
<text x="${progressTextX}" y="34" class="lang-name">${progress}%</text>
|
||||
<text x="${progressTextX}" y="34" class="lang-name">${text || `${progress}%`}</text>
|
||||
${createProgressNode({
|
||||
x: 0,
|
||||
y: 25,
|
||||
@@ -89,7 +90,7 @@ const createCompactLangNode = ({ lang, totalSize, hideProgress, index }) => {
|
||||
<g class="stagger" style="animation-delay: ${staggerDelay}ms">
|
||||
<circle cx="5" cy="6" r="5" fill="${color}" />
|
||||
<text data-testid="lang-name" x="15" y="10" class='lang-name'>
|
||||
${lang.name} ${hideProgress ? "" : percentage + "%"}
|
||||
${lang.name} ${hideProgress ? "" : (lang.text || `${percentage}%`)}
|
||||
</text>
|
||||
</g>
|
||||
`;
|
||||
@@ -126,7 +127,7 @@ const createLanguageTextNode = ({ langs, totalSize, hideProgress }) => {
|
||||
|
||||
const percent = ((longestLang.size / totalSize) * 100).toFixed(2);
|
||||
const minGap = 150;
|
||||
const maxGap = 20 + measureText(`${longestLang.name} ${percent}%`, 11);
|
||||
const maxGap = 20 + measureText(`${longestLang.name} ${longestLang.text || `${percent}%`}`, 11);
|
||||
return flexLayout({
|
||||
items: layouts,
|
||||
gap: maxGap < minGap ? minGap : maxGap,
|
||||
@@ -149,6 +150,7 @@ const renderNormalLayout = (langs, width, totalLanguageSize) => {
|
||||
name: lang.name,
|
||||
color: lang.color || DEFAULT_LANG_COLOR,
|
||||
progress: ((lang.size / totalLanguageSize) * 100).toFixed(2),
|
||||
text: lang.text,
|
||||
index,
|
||||
});
|
||||
}),
|
||||
@@ -278,6 +280,12 @@ const useLanguages = (topLangs, hide, langs_count) => {
|
||||
* @returns {string} Language card SVG object.
|
||||
*/
|
||||
const renderTopLanguages = (topLangs, options = {}) => {
|
||||
const locale = options.locale
|
||||
const i18n = new I18n({
|
||||
locale,
|
||||
translations: langCardLocales,
|
||||
});
|
||||
|
||||
const {
|
||||
hide_title = false,
|
||||
hide_border,
|
||||
@@ -290,18 +298,13 @@ const renderTopLanguages = (topLangs, options = {}) => {
|
||||
theme,
|
||||
layout,
|
||||
custom_title,
|
||||
locale,
|
||||
langs_count = DEFAULT_LANGS_COUNT,
|
||||
border_radius,
|
||||
border_color,
|
||||
title = i18n.t("langcard.title"),
|
||||
disable_animations,
|
||||
} = options;
|
||||
|
||||
const i18n = new I18n({
|
||||
locale,
|
||||
translations: langCardLocales,
|
||||
});
|
||||
|
||||
const { langs, totalLanguageSize } = useLanguages(
|
||||
topLangs,
|
||||
hide,
|
||||
@@ -342,7 +345,7 @@ const renderTopLanguages = (topLangs, options = {}) => {
|
||||
|
||||
const card = new Card({
|
||||
customTitle: custom_title,
|
||||
defaultTitle: i18n.t("langcard.title"),
|
||||
defaultTitle: title,
|
||||
width,
|
||||
height,
|
||||
border_radius,
|
||||
|
||||
Reference in New Issue
Block a user