mirror of
https://github.com/skidoodle/ncore-stats.git
synced 2026-04-27 23:37:36 +02:00
real
This commit is contained in:
+9
-24
@@ -6,51 +6,35 @@ const config = {
|
||||
|
||||
let currentChart = null;
|
||||
|
||||
async function renderChart(owner) {
|
||||
async function renderChart(data) {
|
||||
const root = document.getElementById('modal-stats-root');
|
||||
if (!root) return;
|
||||
if (!root || !data) return;
|
||||
|
||||
try {
|
||||
const response = await fetch(`${config.api.history}${encodeURIComponent(owner)}`); if (!response.ok) throw new Error('Network error');
|
||||
const historyData = await response.json();
|
||||
|
||||
if (!historyData || historyData.length === 0) {
|
||||
if (!data.t || data.t.length === 0) {
|
||||
root.innerHTML = '<p class="stat-label" style="text-align: center; padding: 2rem; color: var(--muted);">No history available.</p>';
|
||||
return;
|
||||
}
|
||||
const parseUploadValue = (value) => {
|
||||
if (typeof value !== 'string') return 0;
|
||||
const num = parseFloat(value.replace(/,/g, '').replace(/TiB|GiB|MiB|KiB|B/i, '').trim());
|
||||
if (isNaN(num)) return 0;
|
||||
const lowerVal = value.toLowerCase();
|
||||
if (lowerVal.includes('tib')) return num;
|
||||
if (lowerVal.includes('gib')) return num / 1024;
|
||||
if (lowerVal.includes('mib')) return num / 1024 / 1024;
|
||||
if (lowerVal.includes('kib')) return num / 1024 / 1024 / 1024;
|
||||
return num / 1024 / 1024 / 1024 / 1024;
|
||||
};
|
||||
|
||||
const series = [
|
||||
{
|
||||
name: 'Upload',
|
||||
data: historyData.map(r => ({ x: new Date(r.timestamp).getTime(), y: parseUploadValue(r.upload) }))
|
||||
data: data.t.map((ts, i) => ({ x: ts, y: data.u[i] }))
|
||||
},
|
||||
{
|
||||
name: 'Rank',
|
||||
data: historyData.map(r => ({ x: new Date(r.timestamp).getTime(), y: r.rank }))
|
||||
data: data.t.map((ts, i) => ({ x: ts, y: data.r[i] }))
|
||||
},
|
||||
{
|
||||
name: 'Points',
|
||||
data: historyData.map(r => ({ x: new Date(r.timestamp).getTime(), y: r.points }))
|
||||
data: data.t.map((ts, i) => ({ x: ts, y: data.p[i] }))
|
||||
},
|
||||
{
|
||||
name: 'Seeding',
|
||||
data: historyData.map(r => ({ x: new Date(r.timestamp).getTime(), y: r.seeding_count }))
|
||||
data: data.t.map((ts, i) => ({ x: ts, y: data.s[i] }))
|
||||
}
|
||||
];
|
||||
|
||||
root.innerHTML = '<div id="chart-mount" style="height: 100%; width: 100%;"></div>';
|
||||
|
||||
const options = {
|
||||
series: series,
|
||||
chart: {
|
||||
@@ -61,7 +45,7 @@ async function renderChart(owner) {
|
||||
foreColor: '#71717a',
|
||||
fontFamily: 'Inter, system-ui, sans-serif',
|
||||
toolbar: { show: false },
|
||||
animations: { enabled: true, easing: 'easeinout', speed: 800 }
|
||||
animations: { enabled: false }
|
||||
},
|
||||
responsive: [
|
||||
{
|
||||
@@ -166,6 +150,7 @@ async function renderChart(owner) {
|
||||
currentChart.render();
|
||||
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
root.innerHTML = `<div class="spinner-container"><p class="stat-label" style="color: #ef4444;">Error: ${e.message}</p></div>`;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -179,6 +179,50 @@ main {
|
||||
border-color: var(--accent);
|
||||
}
|
||||
|
||||
.btn-range {
|
||||
background: var(--bg);
|
||||
border: 1px solid var(--border);
|
||||
color: var(--muted);
|
||||
padding: 0.4rem 0.8rem;
|
||||
font-size: 0.7rem;
|
||||
font-weight: 700;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.btn-range:hover {
|
||||
color: #fff;
|
||||
border-color: var(--muted);
|
||||
}
|
||||
|
||||
.spinner-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.spinner {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
border: 3px solid var(--border);
|
||||
border-top: 3px solid var(--accent);
|
||||
border-radius: 50%;
|
||||
animation: spin 1s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
.modal-overlay {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
|
||||
Reference in New Issue
Block a user