diff --git a/assets/js/index.js b/assets/js/index.js
index 2653d91..f039d7e 100644
--- a/assets/js/index.js
+++ b/assets/js/index.js
@@ -23,7 +23,6 @@ setInterval(() => {
const ageElem = document.getElementById('age');
let birthday = new Date('2008-12-13');
-let age = 0;
function updateAge(elem, fix, text) {
const now = new Date();
@@ -112,7 +111,7 @@ function lan() {
});
}
-window.onload = (event) => {
+window.onload = () => {
lan();
};
@@ -241,7 +240,7 @@ function fetchWeather(location) {
});
}
-wakatime.fetchWakatime("#wakapi", "zyqunix", "all_time");
+wakatime.fetchWakatime("#wakapi");
const messages = [
"Coding",
@@ -349,4 +348,4 @@ document.addEventListener("keydown", function (e) {
if (e.key === "Escape") closeOverlay("music-pop", "overlay");
});
-document.getElementById('refresh').addEventListener('click', fetchSong);
\ No newline at end of file
+document.getElementById('refresh').addEventListener('click', fetchSong);
diff --git a/assets/js/wakatime.js b/assets/js/wakatime.js
index c17a812..3a31e89 100644
--- a/assets/js/wakatime.js
+++ b/assets/js/wakatime.js
@@ -63,141 +63,277 @@ const categoryColors = {
coding: '#A8DADC',
building: '#F4A261',
debugging: '#E9C46A'
+};
+
+export async function fetchWakaTimeStats(user, 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}`);
+ return await response.json();
}
-export function fetchWakatime(targetId, user, range) {
+export async function prepareChartData() {
+ const languages = await fetchWakaTimeStats("zyqunix", "all_time");
+ const sortedLanguages = [...languages.data.languages].sort((a, b) => b.percent - a.percent);
+
+ const totalSeconds = sortedLanguages.reduce((total, lang) => total + lang.total_seconds, 0);
+ let totalTime = '';
+
+ if (totalSeconds > 3600) {
+ 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 {
+ 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) {
+ const data = await fetchWakaTimeStats("zyqunix", "all_time");
const target = document.querySelector(`${targetId}`);
target.innerHTML = "";
- fetch(`https://wakapi.atums.world/api/v1/users/${user}/stats/${range}`).then(response => response.json()).then(data => {
- const langDetails = document.createElement("details");
- const langSummary = document.createElement("summary");
- langSummary.innerText = "Languages";
- langSummary.classList.add("tooltip");
- langSummary.setAttribute("data-tooltip", "Most Used Languages");
- langDetails.appendChild(langSummary);
- langDetails.style.marginTop = "15px";
- target.appendChild(langDetails);
+ const langDetails = document.createElement("details");
+ const langSummary = document.createElement("summary");
+ langSummary.innerText = "Languages";
+ langSummary.classList.add("tooltip");
+ langSummary.setAttribute("data-tooltip", "Most Used Languages");
+ langDetails.appendChild(langSummary);
+ langDetails.style.marginTop = "15px";
+ target.appendChild(langDetails);
- const topLangs = data.data.languages.slice(0, 10);
- topLangs.forEach(lang => {
- const el = document.createElement("div");
- el.innerText = `${lang.name}: ${lang.text}`;
- el.id = lang.name.toLowerCase();
- el.classList.add("proglang");
- el.style.margin = "5px";
- el.style.padding = "10px";
- el.style.borderRadius = "5px";
- el.style.backgroundColor = langColors[lang.name];
- el.style.color = "var(--base)";
- langDetails.appendChild(el);
- });
+ const topLangs = data.data.languages.slice(0, 10);
+ topLangs.forEach(lang => {
+ const el = document.createElement("div");
+ el.innerText = `${lang.name}: ${lang.text}`;
+ el.id = lang.name.toLowerCase();
+ el.classList.add("proglang");
+ el.style.margin = "5px";
+ el.style.padding = "10px";
+ el.style.borderRadius = "5px";
+ el.style.backgroundColor = langColors[lang.name];
+ el.style.color = "var(--base)";
+ langDetails.appendChild(el);
+ });
- const edDetails = document.createElement("details");
- const edSummary = document.createElement("summary");
- edSummary.innerText = "Editors";
- edSummary.classList.add("tooltip");
- edSummary.setAttribute("data-tooltip", "Most Used Editors");
- edDetails.appendChild(edSummary);
- edDetails.style.marginTop = "15px";
- target.appendChild(edDetails);
+ const edDetails = document.createElement("details");
+ const edSummary = document.createElement("summary");
+ edSummary.innerText = "Editors";
+ edSummary.classList.add("tooltip");
+ edSummary.setAttribute("data-tooltip", "Most Used Editors");
+ edDetails.appendChild(edSummary);
+ edDetails.style.marginTop = "15px";
+ target.appendChild(edDetails);
- const topEditors = data.data.editors.slice(0, 5);
- topEditors.forEach(editor => {
- const el = document.createElement("div");
- el.innerText = `In ${editor.name} for ${editor.text} (${editor.percent}%)`;
- el.style.margin = "5px";
- el.style.padding = "10px";
- el.style.borderRadius = "5px";
- el.style.color = "var(--base)";
- el.style.backgroundColor = editorColors[editor.name.toLowerCase().replace(/\s+/g, '').replace(/[^a-zA-Z]/g, '')];
- edDetails.appendChild(el);
- });
+ const topEditors = data.data.editors.slice(0, 5);
+ topEditors.forEach(editor => {
+ const el = document.createElement("div");
+ el.innerText = `In ${editor.name} for ${editor.text} (${editor.percent}%)`;
+ el.style.margin = "5px";
+ el.style.padding = "10px";
+ el.style.borderRadius = "5px";
+ el.style.color = "var(--base)";
+ el.style.backgroundColor = editorColors[editor.name.toLowerCase().replace(/\s+/g, '').replace(/[^a-zA-Z]/g, '')];
+ edDetails.appendChild(el);
+ });
- const prDetails = document.createElement("details");
- const prSummary = document.createElement("summary");
- prSummary.innerText = "Projects";
- prSummary.classList.add("tooltip");
- prSummary.setAttribute("data-tooltip", "Most Used Projects");
- prDetails.appendChild(prSummary);
- prDetails.style.marginTop = "15px";
- target.appendChild(prDetails);
+ const prDetails = document.createElement("details");
+ const prSummary = document.createElement("summary");
+ prSummary.innerText = "Projects";
+ prSummary.classList.add("tooltip");
+ prSummary.setAttribute("data-tooltip", "Most Used Projects");
+ prDetails.appendChild(prSummary);
+ prDetails.style.marginTop = "15px";
+ target.appendChild(prDetails);
- const topProjects = data.data.projects.slice(0, 10);
- topProjects.forEach(project => {
- const el = document.createElement("div");
- el.innerText = `Coded ${project.name} for ${project.text}`;
- el.style.margin = "5px";
- el.style.padding = "10px";
- el.style.borderRadius = "5px";
- el.style.color = "var(--base)";
- el.style.backgroundColor = projectColors[Math.floor(Math.random() * projectColors.length)];
- prDetails.appendChild(el);
- });
+ const topProjects = data.data.projects.slice(0, 10);
+ topProjects.forEach(project => {
+ const el = document.createElement("div");
+ el.innerText = `Coded ${project.name} for ${project.text}`;
+ el.style.margin = "5px";
+ el.style.padding = "10px";
+ el.style.borderRadius = "5px";
+ el.style.color = "var(--base)";
+ el.style.backgroundColor = projectColors[Math.floor(Math.random() * projectColors.length)];
+ prDetails.appendChild(el);
+ });
- const osDetails = document.createElement("details");
- const osSummary = document.createElement("summary");
- osSummary.innerText = "Operating Systems";
- osSummary.classList.add("tooltip");
- osSummary.setAttribute("data-tooltip", "Most Used Operating Systems");
- osDetails.appendChild(osSummary);
- osDetails.style.marginTop = "15px";
- target.appendChild(osDetails);
+ const osDetails = document.createElement("details");
+ const osSummary = document.createElement("summary");
+ osSummary.innerText = "Operating Systems";
+ osSummary.classList.add("tooltip");
+ osSummary.setAttribute("data-tooltip", "Most Used Operating Systems");
+ osDetails.appendChild(osSummary);
+ osDetails.style.marginTop = "15px";
+ target.appendChild(osDetails);
- const topOS = data.data.operating_systems;
- topOS.forEach(machine => {
- const el = document.createElement('div');
- el.innerText = `Coded on ${machine.name} for ${machine.text}`;
- el.style.margin = "5px";
- el.style.padding = "10px";
- el.style.borderRadius = "5px";
- el.style.color = "var(--base)";
- el.style.backgroundColor = osColors[machine.name.toLowerCase()];
- osDetails.appendChild(el);
- });
+ const topOS = data.data.operating_systems;
+ topOS.forEach(machine => {
+ const el = document.createElement('div');
+ el.innerText = `Coded on ${machine.name} for ${machine.text}`;
+ el.style.margin = "5px";
+ el.style.padding = "10px";
+ el.style.borderRadius = "5px";
+ el.style.color = "var(--base)";
+ el.style.backgroundColor = osColors[machine.name.toLowerCase()];
+ osDetails.appendChild(el);
+ });
- const caDetails = document.createElement("details");
- const caSummary = document.createElement("summary");
- caSummary.innerText = "Categories";
- caSummary.classList.add("tooltip");
- caSummary.setAttribute("data-tooltip", "Time Spent by Category");
- caDetails.appendChild(caSummary);
- caDetails.style.marginTop = "15px";
- target.appendChild(caDetails);
+ const caDetails = document.createElement("details");
+ const caSummary = document.createElement("summary");
+ caSummary.innerText = "Categories";
+ caSummary.classList.add("tooltip");
+ caSummary.setAttribute("data-tooltip", "Time Spent by Category");
+ caDetails.appendChild(caSummary);
+ caDetails.style.marginTop = "15px";
+ target.appendChild(caDetails);
- const categories = data.data.categories;
- categories.forEach(category => {
- const el = document.createElement('div');
- el.style.margin = "5px";
- el.style.padding = "10px";
- el.style.borderRadius = "5px";
- el.style.color = "var(--base)";
- el.style.backgroundColor = categoryColors[category.name.toLowerCase()];
- el.innerText = `Has done ${category.name} for ${category.text}`;
- caDetails.appendChild(el);
- });
+ const categories = data.data.categories;
+ categories.forEach(category => {
+ const el = document.createElement('div');
+ el.style.margin = "5px";
+ el.style.padding = "10px";
+ el.style.borderRadius = "5px";
+ el.style.color = "var(--base)";
+ el.style.backgroundColor = categoryColors[category.name.toLowerCase()];
+ el.innerText = `Has done ${category.name} for ${category.text}`;
+ caDetails.appendChild(el);
+ });
- const miscDetails = document.createElement("details");
- const miscSummary = document.createElement("summary");
- miscSummary.innerText = "Miscellaneous";
- miscSummary.classList.add("tooltip");
- miscSummary.setAttribute("data-tooltip", "Miscellaneous Coding Info");
- miscDetails.appendChild(miscSummary);
- miscDetails.style.marginTop = "15px";
- target.appendChild(miscDetails);
+ const miscDetails = document.createElement("details");
+ const miscSummary = document.createElement("summary");
+ miscSummary.innerText = "Miscellaneous";
+ miscSummary.classList.add("tooltip");
+ miscSummary.setAttribute("data-tooltip", "Miscellaneous Wakatime Info");
+ miscDetails.appendChild(miscSummary);
+ miscDetails.style.marginTop = "15px";
+ target.appendChild(miscDetails);
- const el = document.createElement("div");
- el.innerHTML = `
- Total Coding Time: ${data.data.human_readable_total}
-
- Daily Average: ${data.data.human_readable_daily_average}
-
- Days Since Register: ${data.data.days_including_holidays}
- `;
- miscDetails.appendChild(el);
+ const el = document.createElement("div");
+ el.innerHTML = `
+ Total Coding Time: ${data.data.human_readable_total}
+
+ Daily Average: ${data.data.human_readable_daily_average}
+
+ Days Since Register: ${data.data.days_including_holidays}
+ `;
+ miscDetails.appendChild(el);
+
+ document.getElementById("stats_since").innerText = `Registered on ${data.data.start}`;
+
+ const chartDetails = document.createElement("details");
+ const chartSummary = document.createElement("summary");
+ chartSummary.innerText = "Chart";
+ chartSummary.classList.add("tooltip");
+ chartSummary.setAttribute("data-tooltip", "Miscellaneous Coding Info");
+ chartDetails.appendChild(chartSummary);
+ chartDetails.style.marginTop = "15px";
+ target.appendChild(chartDetails);
+
+ 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 legend = document.createElement("div");
+ legend.style.display = 'flex';
+ legend.style.flexDirection = 'column';
+ legend.style.gap = '8px';
+ legend.id = 'legend';
+
+ chartData.segments.forEach(segment => {
+ const label = document.createElement('div');
+ label.style.display = 'flex';
+ label.style.alignItems = 'center';
+ label.style.gap = '8px';
+
+ 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");
+ chart.setAttribute("viewBox", "0 0 120 120");
+ chart.style.width = "120px";
+ chart.style.height = "120px";
+
+ let cumulativePercent = 0;
+
+ 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})`);
+
+ const segmentLength = (segment.percent / 100) * circumference;
+ const emptyLength = circumference - segmentLength;
+
+ 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);
- document.getElementById("stats_since").innerText = `Registered on ${data.data.start}`;
- }).catch(() => {
- target.innerHTML = ``;
- });
}
+
+console.log(await fetchWakaTimeStats("zyqunix", "all_time"));
diff --git a/bio/index.html b/bio/index.html
index dddb7fd..2c90dcc 100644
--- a/bio/index.html
+++ b/bio/index.html
@@ -12,12 +12,12 @@
-
+