Add finer ranking levels (#2762)

* Add finer ranking levels

* Update rank description
This commit is contained in:
François Rozet
2023-06-12 14:38:07 +02:00
committed by GitHub
parent 768721f325
commit 66e5492654
6 changed files with 69 additions and 60 deletions
+25 -29
View File
@@ -1,5 +1,10 @@
function expsf(x, lambda = 1) {
return 2 ** (-lambda * x);
function exponential_cdf(x) {
return 1 - 2 ** -x;
}
function log_normal_cdf(x) {
// approximation
return x / (1 + x);
}
/**
@@ -13,7 +18,7 @@ function expsf(x, lambda = 1) {
* @param {number} params.repos Total number of repos.
* @param {number} params.stars The number of stars.
* @param {number} params.followers The number of followers.
* @returns {{level: string, score: number}}} The users rank.
* @returns {{level: string, percentile: number}}} The users rank.
*/
function calculateRank({
all_commits,
@@ -24,15 +29,15 @@ function calculateRank({
stars,
followers,
}) {
const COMMITS_MEAN = all_commits ? 1000 : 250,
const COMMITS_MEDIAN = all_commits ? 1000 : 250,
COMMITS_WEIGHT = 2;
const PRS_MEAN = 50,
const PRS_MEDIAN = 50,
PRS_WEIGHT = 3;
const ISSUES_MEAN = 25,
const ISSUES_MEDIAN = 25,
ISSUES_WEIGHT = 1;
const STARS_MEAN = 250,
const STARS_MEDIAN = 50,
STARS_WEIGHT = 4;
const FOLLOWERS_MEAN = 25,
const FOLLOWERS_MEDIAN = 10,
FOLLOWERS_WEIGHT = 1;
const TOTAL_WEIGHT =
@@ -42,30 +47,21 @@ function calculateRank({
STARS_WEIGHT +
FOLLOWERS_WEIGHT;
const THRESHOLDS = [1, 12.5, 25, 37.5, 50, 62.5, 75, 87.5, 100];
const LEVELS = ["S", "A+", "A", "A-", "B+", "B", "B-", "C+", "C"];
const rank =
(COMMITS_WEIGHT * expsf(commits, 1 / COMMITS_MEAN) +
PRS_WEIGHT * expsf(prs, 1 / PRS_MEAN) +
ISSUES_WEIGHT * expsf(issues, 1 / ISSUES_MEAN) +
STARS_WEIGHT * expsf(stars, 1 / STARS_MEAN) +
FOLLOWERS_WEIGHT * expsf(followers, 1 / FOLLOWERS_MEAN)) /
TOTAL_WEIGHT;
1 -
(COMMITS_WEIGHT * exponential_cdf(commits / COMMITS_MEDIAN) +
PRS_WEIGHT * exponential_cdf(prs / PRS_MEDIAN) +
ISSUES_WEIGHT * exponential_cdf(issues / ISSUES_MEDIAN) +
STARS_WEIGHT * log_normal_cdf(stars / STARS_MEDIAN) +
FOLLOWERS_WEIGHT * log_normal_cdf(followers / FOLLOWERS_MEDIAN)) /
TOTAL_WEIGHT;
const RANK_S_PLUS = 0.025;
const RANK_S = 0.1;
const RANK_A_PLUS = 0.25;
const RANK_A = 0.5;
const RANK_B_PLUS = 0.75;
const level = LEVELS[THRESHOLDS.findIndex((t) => rank * 100 <= t)];
const level = (() => {
if (rank <= RANK_S_PLUS) return "S+";
if (rank <= RANK_S) return "S";
if (rank <= RANK_A_PLUS) return "A+";
if (rank <= RANK_A) return "A";
if (rank <= RANK_B_PLUS) return "B+";
return "B";
})();
return { level, score: rank * 100 };
return { level: level, percentile: rank * 100 };
}
export { calculateRank };
+2 -3
View File
@@ -209,9 +209,8 @@ const renderStatsCard = (stats = {}, options = { hide: [] }) => {
hide_rank ? 0 : 150,
);
// the better user's score the the rank will be closer to zero so
// subtracting 100 to get the progress in 100%
const progress = 100 - rank.score;
// the lower the user's percentile the better
const progress = 100 - rank.percentile;
const cssStyles = getStyles({
titleColor,
ringColor,
+1 -1
View File
@@ -189,7 +189,7 @@ const fetchStats = async (
totalIssues: 0,
totalStars: 0,
contributedTo: 0,
rank: { level: "B", score: 0 },
rank: { level: "C", percentile: 100 },
};
let res = await statsFetcher(username);
+1 -1
View File
@@ -22,7 +22,7 @@ export type StatsData = {
totalIssues: number;
totalStars: number;
contributedTo: number;
rank: { level: string; score: number };
rank: { level: string; percentile: number };
};
export type Lang = {