Compare commits

...

5 commits

Author SHA1 Message Date
zyqunix
0db21de34d
Update index.html
Some checks failed
Deploy static content to Pages / deploy (push) Failing after 15s
2025-06-22 20:28:07 +02:00
zyqunix
1d1e08eb63
Update index.html 2025-06-22 20:27:55 +02:00
zyqunix
46a4644a4d
Update index.html 2025-06-22 20:27:09 +02:00
zyqunix
1e9cea0bdb
remove constants.js 2025-06-22 18:18:45 +02:00
zyqunix
4336ce2972
chart 2025-06-22 18:18:17 +02:00
4 changed files with 262 additions and 127 deletions

View file

@ -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",

View file

@ -63,12 +63,69 @@ 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");
@ -181,7 +238,7 @@ export function fetchWakatime(targetId, user, range) {
const miscSummary = document.createElement("summary");
miscSummary.innerText = "Miscellaneous";
miscSummary.classList.add("tooltip");
miscSummary.setAttribute("data-tooltip", "Miscellaneous Coding Info");
miscSummary.setAttribute("data-tooltip", "Miscellaneous Wakatime Info");
miscDetails.appendChild(miscSummary);
miscDetails.style.marginTop = "15px";
target.appendChild(miscDetails);
@ -197,7 +254,86 @@ export function fetchWakatime(targetId, user, range) {
miscDetails.appendChild(el);
document.getElementById("stats_since").innerText = `Registered on ${data.data.start}`;
}).catch(() => {
target.innerHTML = `<img class="stat-img" src="https://github-readme-stats.vercel.app/api/wakatime?username=${user}&theme=transparent&hide_border=true&layout=compact">`;
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);
}
console.log(await fetchWakaTimeStats("zyqunix", "all_time"));

View file

@ -12,12 +12,12 @@
<meta property="og:image" content="https://rimgo.pussthecat.org/RFbdMMB.png">
<link rel="shortcut icon" href="https://easyfiles.cc/2024/4/e0482551-b6a6-4739-bf0a-758756e8c464/RFbdMMB.png" type="image/x-icon">
<script src="https://app.rybbit.io/api/script.js" data-site-id="1005" defer ></script>
</head>
<body>
<script src="https://cdn.jsdelivr.net/gh/0x5841524f4e/js-lanyard/lanyard.js"></script>
<script disable-devtool-auto="" src="htps://cdn.jsdelivr.net/npm/disable-devtool@latest"></script>
<script disable-devtool-auto="" src="https://cdn.jsdelivr.net/npm/disable-devtool@latest"></script>
<div class="video-container">
<video id="videoPlayer"></video>

View file

@ -8,7 +8,7 @@
<link href="assets/css/style.css" rel="stylesheet" />
<link rel="shortcut icon" href="https://rimgo.pussthecat.org/RFbdMMB.png" type="image/x-icon">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<script src="https://app.rybbit.io/api/script.js" data-site-id="1005" defer ></script>
</head>
<body>
<div class="info" id="Info">