mirror of
https://github.com/zyqunix/tools.git
synced 2025-07-05 14:00:31 +02:00
add github stats
This commit is contained in:
parent
1e9cea0bdb
commit
62beee7ff8
5 changed files with 331 additions and 221 deletions
|
@ -733,3 +733,28 @@ br {
|
||||||
.twitter-contact > img {
|
.twitter-contact > img {
|
||||||
color: var(--white);
|
color: var(--white);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#github-full {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gitnamepfp {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#github-full a {
|
||||||
|
text-decoration: none;
|
||||||
|
font-weight: 400 !important;
|
||||||
|
color: var(--text) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
#github-full a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
color: var(--white) !important;
|
||||||
|
}
|
||||||
|
|
76
assets/js/github.js
Normal file
76
assets/js/github.js
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
export async function fetchGithubStats(user) {
|
||||||
|
const response = await fetch(`https://api.github.com/users/${user}`);
|
||||||
|
if (!response.ok) throw new Error(`Error fetching Github Info: ${response.statusText}`);
|
||||||
|
return await response.json();
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getTotalStars(username) {
|
||||||
|
let page = 1;
|
||||||
|
let totalStars = 0;
|
||||||
|
let hasMore = true;
|
||||||
|
|
||||||
|
while (hasMore) {
|
||||||
|
const response = await fetch(`https://api.github.com/users/${username}/repos?per_page=100&page=${page}`);
|
||||||
|
const repos = await response.json();
|
||||||
|
|
||||||
|
if (repos.length === 0) break;
|
||||||
|
totalStars += repos.reduce((sum, repo) => sum + repo.stargazers_count, 0);
|
||||||
|
hasMore = repos.length === 100;
|
||||||
|
page++;
|
||||||
|
}
|
||||||
|
return totalStars;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function writeGithubStats(targetId) {
|
||||||
|
const data = await fetchGithubStats("zyqunix");
|
||||||
|
const stars = await getTotalStars("zyqunix");
|
||||||
|
|
||||||
|
const target = document.querySelector(targetId);
|
||||||
|
target.innerHTML = "";
|
||||||
|
|
||||||
|
const mainEl = document.createElement("div");
|
||||||
|
mainEl.classList.add("gitnamepfp");
|
||||||
|
|
||||||
|
const pfp = document.createElement("img");
|
||||||
|
pfp.src = data.avatar_url;
|
||||||
|
pfp.style.borderRadius = "50%";
|
||||||
|
pfp.style.width = "96px";
|
||||||
|
|
||||||
|
const name = document.createElement("a");
|
||||||
|
name.innerText = data.login;
|
||||||
|
name.href = data.html_url;
|
||||||
|
name.target = "_blank";
|
||||||
|
name.style.fontSize = "20px";
|
||||||
|
name.classList.add("tooltip");
|
||||||
|
name.setAttribute("data-tooltip", data.bio);
|
||||||
|
|
||||||
|
const pubRepos = document.createElement("a");
|
||||||
|
pubRepos.innerText = `${data.public_repos} Public Repositories`;
|
||||||
|
pubRepos.href = `https://github.com/${data.login}?tab=repos`;
|
||||||
|
pubRepos.id = "pubrepos";
|
||||||
|
|
||||||
|
const followers = document.createElement("div");
|
||||||
|
followers.innerHTML = `<a href="https://github.com/${data.login}?tab=followers" target="_blank">${data.followers} Followers</a> & <a href="https://github.com/${data.login}?tab=following" target="_blank">Following ${data.following}`;
|
||||||
|
|
||||||
|
|
||||||
|
const hireable = document.createElement("div");
|
||||||
|
if (data.hireable === "null") {
|
||||||
|
hireable.innerText = "Not Hireable";
|
||||||
|
} else {
|
||||||
|
hireable.innerText = "Hire Me!";
|
||||||
|
}
|
||||||
|
|
||||||
|
const tStars = document.createElement("div");
|
||||||
|
tStars.innerText = `${stars} Total Stars`;
|
||||||
|
|
||||||
|
const registered = data.created_at;
|
||||||
|
document.getElementById("gh_since").innerText = `Registed on ${registered.slice(0, 10).replace(/-/g, "/")}`;
|
||||||
|
|
||||||
|
mainEl.appendChild(pfp);
|
||||||
|
mainEl.appendChild(name);
|
||||||
|
target.appendChild(mainEl);
|
||||||
|
target.appendChild(pubRepos);
|
||||||
|
target.appendChild(followers);
|
||||||
|
target.appendChild(hireable);
|
||||||
|
target.appendChild(tStars);
|
||||||
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
import * as wakatime from "./wakatime.js";
|
import * as wakatime from "./wakatime.js";
|
||||||
|
import * as github from "./github.js";
|
||||||
const timeElem = document.getElementById('time');
|
const timeElem = document.getElementById('time');
|
||||||
const timezone = 'Europe/Berlin';
|
const timezone = 'Europe/Berlin';
|
||||||
|
|
||||||
|
@ -241,6 +242,7 @@ function fetchWeather(location) {
|
||||||
}
|
}
|
||||||
|
|
||||||
wakatime.fetchWakatime("#wakapi");
|
wakatime.fetchWakatime("#wakapi");
|
||||||
|
github.writeGithubStats("#github-full");
|
||||||
|
|
||||||
const messages = [
|
const messages = [
|
||||||
"Coding",
|
"Coding",
|
||||||
|
|
|
@ -57,7 +57,7 @@ const projectColors = [
|
||||||
'#E2F0CB',
|
'#E2F0CB',
|
||||||
'#F5E6E8',
|
'#F5E6E8',
|
||||||
'#C9D6DF'
|
'#C9D6DF'
|
||||||
];
|
];
|
||||||
|
|
||||||
const categoryColors = {
|
const categoryColors = {
|
||||||
coding: '#A8DADC',
|
coding: '#A8DADC',
|
||||||
|
@ -66,274 +66,273 @@ const categoryColors = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export async function fetchWakaTimeStats(user, range) {
|
export async function fetchWakaTimeStats(user, range) {
|
||||||
const response = await fetch(`https://wakapi.atums.world/api/v1/users/${user}/stats/${range}`);
|
const response = await fetch(`https://wakapi.atums.world/api/v1/users/${user}/stats/${range}`);
|
||||||
if (!response.ok) throw new Error(`Error fetching WakaTime stats: ${response.statusText}`);
|
if (!response.ok) throw new Error(`Error fetching WakaTime stats: ${response.statusText}`);
|
||||||
return await response.json();
|
return await response.json();
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function prepareChartData() {
|
export async function prepareChartData() {
|
||||||
const languages = await fetchWakaTimeStats("zyqunix", "all_time");
|
const languages = await fetchWakaTimeStats("zyqunix", "all_time");
|
||||||
const sortedLanguages = [...languages.data.languages].sort((a, b) => b.percent - a.percent);
|
const sortedLanguages = [...languages.data.languages].sort((a, b) => b.percent - a.percent);
|
||||||
|
|
||||||
const totalSeconds = sortedLanguages.reduce((total, lang) => total + lang.total_seconds, 0);
|
const totalSeconds = sortedLanguages.reduce((total, lang) => total + lang.total_seconds, 0);
|
||||||
let totalTime = '';
|
let totalTime = '';
|
||||||
|
|
||||||
if (totalSeconds > 3600) {
|
if (totalSeconds > 3600) {
|
||||||
totalTime = `${Math.floor(totalSeconds / 3600)}h ${Math.floor((totalSeconds % 3600) / 60)}m`;
|
totalTime = `${Math.floor(totalSeconds / 3600)}h ${Math.floor((totalSeconds % 3600) / 60)}m`;
|
||||||
} else {
|
|
||||||
totalTime = `${Math.floor(totalSeconds / 60)}m`;
|
|
||||||
}
|
|
||||||
|
|
||||||
const limit = 10;
|
|
||||||
const topLanguages = sortedLanguages.slice(0, limit);
|
|
||||||
|
|
||||||
if (sortedLanguages.length > limit) {
|
|
||||||
const otherSeconds = sortedLanguages.slice(limit).reduce((total, lang) => total + lang.total_seconds, 0);
|
|
||||||
const otherPercent = sortedLanguages.slice(limit).reduce((total, lang) => total + lang.percent, 0);
|
|
||||||
|
|
||||||
let otherText = '';
|
|
||||||
if (otherSeconds > 3600) {
|
|
||||||
otherText = `${Math.floor(otherSeconds / 3600)}h ${Math.floor((otherSeconds % 3600) / 60)}m`;
|
|
||||||
} else {
|
} else {
|
||||||
otherText = `${Math.floor(otherSeconds / 60)}m`;
|
totalTime = `${Math.floor(totalSeconds / 60)}m`;
|
||||||
}
|
}
|
||||||
|
|
||||||
topLanguages.push({
|
const limit = 10;
|
||||||
name: 'Other',
|
const topLanguages = sortedLanguages.slice(0, limit);
|
||||||
total_seconds: otherSeconds,
|
|
||||||
percent: otherPercent,
|
|
||||||
text: otherText,
|
|
||||||
color: '#CCCCCC',
|
|
||||||
digital: '',
|
|
||||||
hours: Math.floor(otherSeconds / 3600),
|
|
||||||
minutes: Math.floor((otherSeconds % 3600) / 60),
|
|
||||||
seconds: otherSeconds % 60
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const segmentsWithColors = topLanguages.map(lang => ({
|
if (sortedLanguages.length > limit) {
|
||||||
...lang,
|
const otherSeconds = sortedLanguages.slice(limit).reduce((total, lang) => total + lang.total_seconds, 0);
|
||||||
color: lang.color || langColors[lang.name] || '#CCCCCC'
|
const otherPercent = sortedLanguages.slice(limit).reduce((total, lang) => total + lang.percent, 0);
|
||||||
}));
|
|
||||||
|
|
||||||
return {
|
let otherText = '';
|
||||||
segments: segmentsWithColors,
|
if (otherSeconds > 3600) {
|
||||||
totalTime
|
otherText = `${Math.floor(otherSeconds / 3600)}h ${Math.floor((otherSeconds % 3600) / 60)}m`;
|
||||||
};
|
} else {
|
||||||
|
otherText = `${Math.floor(otherSeconds / 60)}m`;
|
||||||
|
}
|
||||||
|
|
||||||
|
topLanguages.push({
|
||||||
|
name: 'Other',
|
||||||
|
total_seconds: otherSeconds,
|
||||||
|
percent: otherPercent,
|
||||||
|
text: otherText,
|
||||||
|
color: '#CCCCCC',
|
||||||
|
digital: '',
|
||||||
|
hours: Math.floor(otherSeconds / 3600),
|
||||||
|
minutes: Math.floor((otherSeconds % 3600) / 60),
|
||||||
|
seconds: otherSeconds % 60
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const segmentsWithColors = topLanguages.map(lang => ({
|
||||||
|
...lang,
|
||||||
|
color: lang.color || langColors[lang.name] || '#CCCCCC'
|
||||||
|
}));
|
||||||
|
|
||||||
|
return {
|
||||||
|
segments: segmentsWithColors,
|
||||||
|
totalTime
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchWakatime(targetId) {
|
export async function fetchWakatime(targetId) {
|
||||||
const data = await fetchWakaTimeStats("zyqunix", "all_time");
|
const data = await fetchWakaTimeStats("zyqunix", "all_time");
|
||||||
const target = document.querySelector(`${targetId}`);
|
const target = document.querySelector(`${targetId}`);
|
||||||
target.innerHTML = "";
|
target.innerHTML = "";
|
||||||
|
|
||||||
const langDetails = document.createElement("details");
|
const langDetails = document.createElement("details");
|
||||||
const langSummary = document.createElement("summary");
|
const langSummary = document.createElement("summary");
|
||||||
langSummary.innerText = "Languages";
|
langSummary.innerText = "Languages";
|
||||||
langSummary.classList.add("tooltip");
|
langSummary.classList.add("tooltip");
|
||||||
langSummary.setAttribute("data-tooltip", "Most Used Languages");
|
langSummary.setAttribute("data-tooltip", "Most Used Languages");
|
||||||
langDetails.appendChild(langSummary);
|
langDetails.appendChild(langSummary);
|
||||||
langDetails.style.marginTop = "15px";
|
langDetails.style.marginTop = "15px";
|
||||||
target.appendChild(langDetails);
|
target.appendChild(langDetails);
|
||||||
|
|
||||||
const topLangs = data.data.languages.slice(0, 10);
|
const topLangs = data.data.languages.slice(0, 10);
|
||||||
topLangs.forEach(lang => {
|
topLangs.forEach(lang => {
|
||||||
const el = document.createElement("div");
|
const el = document.createElement("div");
|
||||||
el.innerText = `${lang.name}: ${lang.text}`;
|
el.innerText = `${lang.name}: ${lang.text}`;
|
||||||
el.id = lang.name.toLowerCase();
|
el.id = lang.name.toLowerCase();
|
||||||
el.classList.add("proglang");
|
el.classList.add("proglang");
|
||||||
el.style.margin = "5px";
|
el.style.margin = "5px";
|
||||||
el.style.padding = "10px";
|
el.style.padding = "10px";
|
||||||
el.style.borderRadius = "5px";
|
el.style.borderRadius = "5px";
|
||||||
el.style.backgroundColor = langColors[lang.name];
|
el.style.backgroundColor = langColors[lang.name];
|
||||||
el.style.color = "var(--base)";
|
el.style.color = "var(--base)";
|
||||||
langDetails.appendChild(el);
|
langDetails.appendChild(el);
|
||||||
});
|
});
|
||||||
|
|
||||||
const edDetails = document.createElement("details");
|
const edDetails = document.createElement("details");
|
||||||
const edSummary = document.createElement("summary");
|
const edSummary = document.createElement("summary");
|
||||||
edSummary.innerText = "Editors";
|
edSummary.innerText = "Editors";
|
||||||
edSummary.classList.add("tooltip");
|
edSummary.classList.add("tooltip");
|
||||||
edSummary.setAttribute("data-tooltip", "Most Used Editors");
|
edSummary.setAttribute("data-tooltip", "Most Used Editors");
|
||||||
edDetails.appendChild(edSummary);
|
edDetails.appendChild(edSummary);
|
||||||
edDetails.style.marginTop = "15px";
|
edDetails.style.marginTop = "15px";
|
||||||
target.appendChild(edDetails);
|
target.appendChild(edDetails);
|
||||||
|
|
||||||
const topEditors = data.data.editors.slice(0, 5);
|
const topEditors = data.data.editors.slice(0, 5);
|
||||||
topEditors.forEach(editor => {
|
topEditors.forEach(editor => {
|
||||||
const el = document.createElement("div");
|
const el = document.createElement("div");
|
||||||
el.innerText = `In ${editor.name} for ${editor.text} (${editor.percent}%)`;
|
el.innerText = `In ${editor.name} for ${editor.text} (${editor.percent}%)`;
|
||||||
el.style.margin = "5px";
|
el.style.margin = "5px";
|
||||||
el.style.padding = "10px";
|
el.style.padding = "10px";
|
||||||
el.style.borderRadius = "5px";
|
el.style.borderRadius = "5px";
|
||||||
el.style.color = "var(--base)";
|
el.style.color = "var(--base)";
|
||||||
el.style.backgroundColor = editorColors[editor.name.toLowerCase().replace(/\s+/g, '').replace(/[^a-zA-Z]/g, '')];
|
el.style.backgroundColor = editorColors[editor.name.toLowerCase().replace(/\s+/g, '').replace(/[^a-zA-Z]/g, '')];
|
||||||
edDetails.appendChild(el);
|
edDetails.appendChild(el);
|
||||||
});
|
});
|
||||||
|
|
||||||
const prDetails = document.createElement("details");
|
const prDetails = document.createElement("details");
|
||||||
const prSummary = document.createElement("summary");
|
const prSummary = document.createElement("summary");
|
||||||
prSummary.innerText = "Projects";
|
prSummary.innerText = "Projects";
|
||||||
prSummary.classList.add("tooltip");
|
prSummary.classList.add("tooltip");
|
||||||
prSummary.setAttribute("data-tooltip", "Most Used Projects");
|
prSummary.setAttribute("data-tooltip", "Most Used Projects");
|
||||||
prDetails.appendChild(prSummary);
|
prDetails.appendChild(prSummary);
|
||||||
prDetails.style.marginTop = "15px";
|
prDetails.style.marginTop = "15px";
|
||||||
target.appendChild(prDetails);
|
target.appendChild(prDetails);
|
||||||
|
|
||||||
const topProjects = data.data.projects.slice(0, 10);
|
const topProjects = data.data.projects.slice(0, 10);
|
||||||
topProjects.forEach(project => {
|
topProjects.forEach(project => {
|
||||||
const el = document.createElement("div");
|
const el = document.createElement("div");
|
||||||
el.innerText = `Coded ${project.name} for ${project.text}`;
|
el.innerText = `Coded ${project.name} for ${project.text}`;
|
||||||
el.style.margin = "5px";
|
el.style.margin = "5px";
|
||||||
el.style.padding = "10px";
|
el.style.padding = "10px";
|
||||||
el.style.borderRadius = "5px";
|
el.style.borderRadius = "5px";
|
||||||
el.style.color = "var(--base)";
|
el.style.color = "var(--base)";
|
||||||
el.style.backgroundColor = projectColors[Math.floor(Math.random() * projectColors.length)];
|
el.style.backgroundColor = projectColors[Math.floor(Math.random() * projectColors.length)];
|
||||||
prDetails.appendChild(el);
|
prDetails.appendChild(el);
|
||||||
});
|
});
|
||||||
|
|
||||||
const osDetails = document.createElement("details");
|
const osDetails = document.createElement("details");
|
||||||
const osSummary = document.createElement("summary");
|
const osSummary = document.createElement("summary");
|
||||||
osSummary.innerText = "Operating Systems";
|
osSummary.innerText = "Operating Systems";
|
||||||
osSummary.classList.add("tooltip");
|
osSummary.classList.add("tooltip");
|
||||||
osSummary.setAttribute("data-tooltip", "Most Used Operating Systems");
|
osSummary.setAttribute("data-tooltip", "Most Used Operating Systems");
|
||||||
osDetails.appendChild(osSummary);
|
osDetails.appendChild(osSummary);
|
||||||
osDetails.style.marginTop = "15px";
|
osDetails.style.marginTop = "15px";
|
||||||
target.appendChild(osDetails);
|
target.appendChild(osDetails);
|
||||||
|
|
||||||
const topOS = data.data.operating_systems;
|
const topOS = data.data.operating_systems;
|
||||||
topOS.forEach(machine => {
|
topOS.forEach(machine => {
|
||||||
const el = document.createElement('div');
|
const el = document.createElement('div');
|
||||||
el.innerText = `Coded on ${machine.name} for ${machine.text}`;
|
el.innerText = `Coded on ${machine.name} for ${machine.text}`;
|
||||||
el.style.margin = "5px";
|
el.style.margin = "5px";
|
||||||
el.style.padding = "10px";
|
el.style.padding = "10px";
|
||||||
el.style.borderRadius = "5px";
|
el.style.borderRadius = "5px";
|
||||||
el.style.color = "var(--base)";
|
el.style.color = "var(--base)";
|
||||||
el.style.backgroundColor = osColors[machine.name.toLowerCase()];
|
el.style.backgroundColor = osColors[machine.name.toLowerCase()];
|
||||||
osDetails.appendChild(el);
|
osDetails.appendChild(el);
|
||||||
});
|
});
|
||||||
|
|
||||||
const caDetails = document.createElement("details");
|
const caDetails = document.createElement("details");
|
||||||
const caSummary = document.createElement("summary");
|
const caSummary = document.createElement("summary");
|
||||||
caSummary.innerText = "Categories";
|
caSummary.innerText = "Categories";
|
||||||
caSummary.classList.add("tooltip");
|
caSummary.classList.add("tooltip");
|
||||||
caSummary.setAttribute("data-tooltip", "Time Spent by Category");
|
caSummary.setAttribute("data-tooltip", "Time Spent by Category");
|
||||||
caDetails.appendChild(caSummary);
|
caDetails.appendChild(caSummary);
|
||||||
caDetails.style.marginTop = "15px";
|
caDetails.style.marginTop = "15px";
|
||||||
target.appendChild(caDetails);
|
target.appendChild(caDetails);
|
||||||
|
|
||||||
const categories = data.data.categories;
|
const categories = data.data.categories;
|
||||||
categories.forEach(category => {
|
categories.forEach(category => {
|
||||||
const el = document.createElement('div');
|
const el = document.createElement('div');
|
||||||
el.style.margin = "5px";
|
el.style.margin = "5px";
|
||||||
el.style.padding = "10px";
|
el.style.padding = "10px";
|
||||||
el.style.borderRadius = "5px";
|
el.style.borderRadius = "5px";
|
||||||
el.style.color = "var(--base)";
|
el.style.color = "var(--base)";
|
||||||
el.style.backgroundColor = categoryColors[category.name.toLowerCase()];
|
el.style.backgroundColor = categoryColors[category.name.toLowerCase()];
|
||||||
el.innerText = `Has done ${category.name} for ${category.text}`;
|
el.innerText = `Has done ${category.name} for ${category.text}`;
|
||||||
caDetails.appendChild(el);
|
caDetails.appendChild(el);
|
||||||
});
|
});
|
||||||
|
|
||||||
const miscDetails = document.createElement("details");
|
const miscDetails = document.createElement("details");
|
||||||
const miscSummary = document.createElement("summary");
|
const miscSummary = document.createElement("summary");
|
||||||
miscSummary.innerText = "Miscellaneous";
|
miscSummary.innerText = "Miscellaneous";
|
||||||
miscSummary.classList.add("tooltip");
|
miscSummary.classList.add("tooltip");
|
||||||
miscSummary.setAttribute("data-tooltip", "Miscellaneous Wakatime Info");
|
miscSummary.setAttribute("data-tooltip", "Miscellaneous Wakatime Info");
|
||||||
miscDetails.appendChild(miscSummary);
|
miscDetails.appendChild(miscSummary);
|
||||||
miscDetails.style.marginTop = "15px";
|
miscDetails.style.marginTop = "15px";
|
||||||
target.appendChild(miscDetails);
|
target.appendChild(miscDetails);
|
||||||
|
|
||||||
const el = document.createElement("div");
|
const el = document.createElement("div");
|
||||||
el.innerHTML = `
|
el.innerHTML = `
|
||||||
Total Coding Time: ${data.data.human_readable_total}
|
Total Coding Time: ${data.data.human_readable_total}
|
||||||
<br>
|
<br>
|
||||||
Daily Average: ${data.data.human_readable_daily_average}
|
Daily Average: ${data.data.human_readable_daily_average}
|
||||||
<br>
|
<br>
|
||||||
Days Since Register: ${data.data.days_including_holidays}
|
Days Since Register: ${data.data.days_including_holidays}
|
||||||
`;
|
`;
|
||||||
miscDetails.appendChild(el);
|
miscDetails.appendChild(el);
|
||||||
|
|
||||||
document.getElementById("stats_since").innerText = `Registered on ${data.data.start}`;
|
const registered = data.data.start;
|
||||||
|
document.getElementById("stats_since").innerText = `Registered on ${registered.slice(0, 10).replace(/-/g, "/")}`;
|
||||||
|
|
||||||
const chartDetails = document.createElement("details");
|
const chartDetails = document.createElement("details");
|
||||||
const chartSummary = document.createElement("summary");
|
const chartSummary = document.createElement("summary");
|
||||||
chartSummary.innerText = "Chart";
|
chartSummary.innerText = "Chart";
|
||||||
chartSummary.classList.add("tooltip");
|
chartSummary.classList.add("tooltip");
|
||||||
chartSummary.setAttribute("data-tooltip", "Miscellaneous Coding Info");
|
chartSummary.setAttribute("data-tooltip", "Miscellaneous Coding Info");
|
||||||
chartDetails.appendChild(chartSummary);
|
chartDetails.appendChild(chartSummary);
|
||||||
chartDetails.style.marginTop = "15px";
|
chartDetails.style.marginTop = "15px";
|
||||||
target.appendChild(chartDetails);
|
target.appendChild(chartDetails);
|
||||||
|
|
||||||
const chartData = await prepareChartData();
|
const chartData = await prepareChartData();
|
||||||
|
|
||||||
|
|
||||||
const svgNS = "http://www.w3.org/2000/svg";
|
|
||||||
const radius = 50;
|
|
||||||
const center = 60;
|
|
||||||
const strokeWidth = 20;
|
|
||||||
const circumference = 2 * Math.PI * radius;
|
|
||||||
|
|
||||||
const container = document.createElement("div");
|
const svgNS = "http://www.w3.org/2000/svg";
|
||||||
|
const radius = 50;
|
||||||
|
const center = 60;
|
||||||
|
const strokeWidth = 20;
|
||||||
|
const circumference = 2 * Math.PI * radius;
|
||||||
|
|
||||||
const legend = document.createElement("div");
|
const container = document.createElement("div");
|
||||||
legend.style.display = 'flex';
|
|
||||||
legend.style.flexDirection = 'column';
|
|
||||||
legend.style.gap = '8px';
|
|
||||||
legend.id = 'legend';
|
|
||||||
|
|
||||||
chartData.segments.forEach(segment => {
|
const legend = document.createElement("div");
|
||||||
const label = document.createElement('div');
|
legend.style.display = 'flex';
|
||||||
label.style.display = 'flex';
|
legend.style.flexDirection = 'column';
|
||||||
label.style.alignItems = 'center';
|
legend.style.gap = '8px';
|
||||||
label.style.gap = '8px';
|
legend.id = 'legend';
|
||||||
|
|
||||||
const colorBox = document.createElement('span');
|
|
||||||
colorBox.style.width = '10px';
|
|
||||||
colorBox.style.height = '10px';
|
|
||||||
colorBox.style.backgroundColor = segment.color;
|
|
||||||
colorBox.style.borderRadius = '3px';
|
|
||||||
|
|
||||||
const text = document.createElement('span');
|
|
||||||
text.innerText = `${segment.name} (${segment.text})`;
|
|
||||||
|
|
||||||
label.appendChild(colorBox);
|
|
||||||
label.appendChild(text);
|
|
||||||
legend.appendChild(label);
|
|
||||||
});
|
|
||||||
|
|
||||||
const chart = document.createElementNS(svgNS, "svg");
|
chartData.segments.forEach(segment => {
|
||||||
chart.setAttribute("viewBox", "0 0 120 120");
|
const label = document.createElement('div');
|
||||||
chart.style.width = "120px";
|
label.style.display = 'flex';
|
||||||
chart.style.height = "120px";
|
label.style.alignItems = 'center';
|
||||||
|
label.style.gap = '8px';
|
||||||
|
|
||||||
let cumulativePercent = 0;
|
const colorBox = document.createElement('span');
|
||||||
|
colorBox.style.width = '10px';
|
||||||
|
colorBox.style.height = '10px';
|
||||||
|
colorBox.style.backgroundColor = segment.color;
|
||||||
|
colorBox.style.borderRadius = '3px';
|
||||||
|
|
||||||
chartData.segments.forEach(segment => {
|
const text = document.createElement('span');
|
||||||
const circle = document.createElementNS(svgNS, "circle");
|
text.innerText = `${segment.name} (${segment.text})`;
|
||||||
circle.setAttribute("cx", center);
|
|
||||||
circle.setAttribute("cy", center);
|
|
||||||
circle.setAttribute("r", radius);
|
|
||||||
circle.setAttribute("fill", "none");
|
|
||||||
circle.setAttribute("stroke", segment.color);
|
|
||||||
circle.setAttribute("stroke-width", strokeWidth);
|
|
||||||
circle.setAttribute("transform", `rotate(-90 ${center} ${center})`);
|
|
||||||
|
|
||||||
const segmentLength = (segment.percent / 100) * circumference;
|
label.appendChild(colorBox);
|
||||||
const emptyLength = circumference - segmentLength;
|
label.appendChild(text);
|
||||||
|
legend.appendChild(label);
|
||||||
|
});
|
||||||
|
|
||||||
circle.setAttribute("stroke-dasharray", `${segmentLength} ${emptyLength}`);
|
const chart = document.createElementNS(svgNS, "svg");
|
||||||
circle.setAttribute("stroke-dashoffset", circumference * (1 - cumulativePercent / 100));
|
chart.setAttribute("viewBox", "0 0 120 120");
|
||||||
|
chart.style.width = "120px";
|
||||||
|
chart.style.height = "120px";
|
||||||
|
|
||||||
cumulativePercent += segment.percent;
|
let cumulativePercent = 0;
|
||||||
|
|
||||||
chart.appendChild(circle);
|
chartData.segments.forEach(segment => {
|
||||||
});
|
const circle = document.createElementNS(svgNS, "circle");
|
||||||
|
circle.setAttribute("cx", center);
|
||||||
|
circle.setAttribute("cy", center);
|
||||||
|
circle.setAttribute("r", radius);
|
||||||
|
circle.setAttribute("fill", "none");
|
||||||
|
circle.setAttribute("stroke", segment.color);
|
||||||
|
circle.setAttribute("stroke-width", strokeWidth);
|
||||||
|
circle.setAttribute("transform", `rotate(-90 ${center} ${center})`);
|
||||||
|
|
||||||
container.appendChild(legend);
|
const segmentLength = (segment.percent / 100) * circumference;
|
||||||
container.appendChild(chart);
|
const emptyLength = circumference - segmentLength;
|
||||||
|
|
||||||
chartDetails.appendChild(container);
|
circle.setAttribute("stroke-dasharray", `${segmentLength} ${emptyLength}`);
|
||||||
|
circle.setAttribute("stroke-dashoffset", circumference * (1 - cumulativePercent / 100));
|
||||||
|
|
||||||
|
cumulativePercent += segment.percent;
|
||||||
|
|
||||||
|
chart.appendChild(circle);
|
||||||
|
});
|
||||||
|
|
||||||
|
container.appendChild(legend);
|
||||||
|
container.appendChild(chart);
|
||||||
|
|
||||||
|
chartDetails.appendChild(container);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(await fetchWakaTimeStats("zyqunix", "all_time"));
|
|
||||||
|
|
|
@ -43,6 +43,14 @@
|
||||||
<div id="wakapi"></div>
|
<div id="wakapi"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="github cards" id="GitHub">
|
||||||
|
<h2>GitHub Stats</h2>
|
||||||
|
<p id="gh_since">Since 30 Oct 2022</p>
|
||||||
|
<div id="github-full">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="contact cards" id="Contact">
|
<div class="contact cards" id="Contact">
|
||||||
<h2 class="card-header" id="contact">Contact</h2>
|
<h2 class="card-header" id="contact">Contact</h2>
|
||||||
<a class="contact-item github-contact" href="https://github.com/zyqunix" target="_blank">
|
<a class="contact-item github-contact" href="https://github.com/zyqunix" target="_blank">
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue