diff --git a/api/index.js b/api/index.js
index e6684f2..392b694 100644
--- a/api/index.js
+++ b/api/index.js
@@ -8,6 +8,7 @@ module.exports = async (req, res) => {
username,
hide,
hide_border,
+ hide_rank,
show_icons,
line_height,
title_color,
@@ -29,6 +30,7 @@ module.exports = async (req, res) => {
hide: JSON.parse(hide || "[]"),
show_icons,
hide_border,
+ hide_rank,
line_height,
title_color,
icon_color,
diff --git a/readme.md b/readme.md
index 0e02eaf..008ba77 100644
--- a/readme.md
+++ b/readme.md
@@ -40,6 +40,8 @@ change the `?username=` value to your GitHubs's username
[](https://github.com/anuraghazra/github-readme-stats)
```
+_Note: Ranks are calculated based on users stats, see [src/calculateRank.js](./src/calculateRank.js)_
+
### Hiding individual stats
To hide any specific stats, you can pass a query parameter `?hide=` with an array of items, you wanna hide.
@@ -62,6 +64,7 @@ Other options:
- `&hide_border=true` hide the border box if you don't like it :D.
- `&line_height=30` control the line-height between text.
+- `&hide_rank=true` hides the ranking
### Customization
diff --git a/src/calculateRank.js b/src/calculateRank.js
new file mode 100644
index 0000000..9aeeae2
--- /dev/null
+++ b/src/calculateRank.js
@@ -0,0 +1,52 @@
+function calculateRank({
+ totalRepos,
+ totalCommits,
+ contributions,
+ followers,
+ prs,
+ issues,
+ stargazers,
+}) {
+ const COMMITS_OFFSET = 1.65;
+ const CONTRIBS_OFFSET = 1.65;
+ const ISSUES_OFFSET = 1;
+ const STARS_OFFSET = 0.75;
+ const PRS_OFFSET = 0.5;
+ const FOLLOWERS_OFFSET = 0.45;
+
+ const FIRST_STEP = 0;
+ const SECOND_STEP = 5;
+ const THIRD_STEP = 20;
+ const FOURTH_STEP = 50;
+ const FIFTH_STEP = 130;
+
+ // prettier-ignore
+ const score = (
+ totalCommits * COMMITS_OFFSET +
+ contributions * CONTRIBS_OFFSET +
+ issues * ISSUES_OFFSET +
+ stargazers * STARS_OFFSET +
+ prs * PRS_OFFSET +
+ followers * FOLLOWERS_OFFSET
+ ) / totalRepos;
+
+ let level = "";
+
+ if (score == FIRST_STEP) {
+ level = "B";
+ } else if (score > FIRST_STEP && score <= SECOND_STEP) {
+ level = "B+";
+ } else if (score > SECOND_STEP && score <= THIRD_STEP) {
+ level = "A";
+ } else if (score > THIRD_STEP && score <= FOURTH_STEP) {
+ level = "A+";
+ } else if (score > FOURTH_STEP && score <= FIFTH_STEP) {
+ level = "A++";
+ } else if (score > FIFTH_STEP) {
+ level = "S+";
+ }
+
+ return { level, score };
+}
+
+module.exports = calculateRank;
diff --git a/src/fetchStats.js b/src/fetchStats.js
index 8d29170..dc28590 100644
--- a/src/fetchStats.js
+++ b/src/fetchStats.js
@@ -1,4 +1,5 @@
const { request } = require("./utils");
+const calculateRank = require("./calculateRank");
require("dotenv").config();
async function fetchStats(username) {
@@ -22,7 +23,11 @@ async function fetchStats(username) {
issues(first: 100) {
totalCount
}
+ followers {
+ totalCount
+ }
repositories(first: 100, orderBy: { direction: DESC, field: STARGAZERS }) {
+ totalCount
nodes {
stargazers {
totalCount
@@ -42,6 +47,7 @@ async function fetchStats(username) {
totalIssues: 0,
totalStars: 0,
contributedTo: 0,
+ rank: "C",
};
if (res.data.errors) {
@@ -61,6 +67,16 @@ async function fetchStats(username) {
return prev + curr.stargazers.totalCount;
}, 0);
+ stats.rank = calculateRank({
+ totalCommits: stats.totalCommits,
+ totalRepos: user.repositories.totalCount,
+ followers: user.followers.totalCount,
+ contributions: stats.contributedTo,
+ stargazers: stats.totalStars,
+ prs: stats.totalPRs,
+ issues: stats.totalIssues,
+ });
+
return stats;
}
diff --git a/src/renderStatsCard.js b/src/renderStatsCard.js
index 56a4c24..8be256b 100644
--- a/src/renderStatsCard.js
+++ b/src/renderStatsCard.js
@@ -18,11 +18,13 @@ const renderStatsCard = (stats = {}, options = { hide: [] }) => {
totalIssues,
totalPRs,
contributedTo,
+ rank,
} = stats;
const {
hide = [],
show_icons = false,
hide_border = false,
+ hide_rank = false,
line_height = 25,
title_color,
icon_color,
@@ -81,23 +83,74 @@ const renderStatsCard = (stats = {}, options = { hide: [] }) => {
.filter((key) => !hide.includes(key))
.map((key) => STAT_MAP[key]);
- const height = 45 + (statItems.length + 1) * lheight;
+ // Calculate the card height depending on how many items there are
+ // but if rank circle is visible clamp the minimum height to `150`
+ const height = Math.max(
+ 45 + (statItems.length + 1) * lheight,
+ hide_rank ? 0 : 150
+ );
+
+ const border = `
+
+ `;
+
+ const rankProgress = 180 + rank.score * 0.8;
+ const rankCircle = hide_rank
+ ? ""
+ : `
+
+
+ ${rank.level}
+
+ `;
- const border = ``;
return `