dangerzone-stats/output/components/Chart.js
Alexis Métaireau 2fbafed46e
First commit
2024-11-11 00:06:35 +01:00

113 lines
No EOL
4.4 KiB
JavaScript

import { h } from 'https://esm.sh/preact';
function getPlatform(assetName) {
assetName = assetName.toLowerCase();
if (assetName.includes('msi')) return 'Windows';
if (assetName.includes('arm64.dmg')) return 'Mac Silicon';
if (assetName.includes('i686.dmg') || assetName.includes('.dmg')) return 'Mac Intel';
if (assetName.includes('container')) return 'Container';
return 'Other';
}
function getColorForPlatform(platform) {
switch (platform) {
case 'Windows': return '#00A4EF';
case 'Mac Intel': return '#A2AAAD';
case 'Mac Silicon': return '#C4C4C4';
case 'Container': return '#FFD700';
default: return '#FF69B4';
}
}
function formatDate(dateString) {
return new Date(dateString).toLocaleDateString(undefined, {
year: 'numeric',
month: 'short'
});
}
export function Chart({ stats }) {
console.log('Received stats:', stats);
if (!stats || !stats.releases || !Array.isArray(stats.releases)) {
return h('div', { class: 'charts' }, 'No data available');
}
const platforms = ['Windows', 'Mac Intel', 'Mac Silicon', 'Container', 'Other'];
const downloadsByRelease = stats.releases
.filter(release => release && release.name && release.published_at)
.map(release => {
console.log('Processing release:', release);
return {
name: (release.name || '').replace(/^Dangerzone /, ''),
date: release.published_at,
platforms: platforms.reduce((acc, platform) => {
acc[platform] = 0;
return acc;
}, {}),
total: 0,
assets: release.assets || []
};
})
.map(release => {
release.assets.forEach(asset => {
const platform = getPlatform(asset.name);
release.platforms[platform] += asset.download_count || 0;
});
release.total = Object.values(release.platforms).reduce((a, b) => a + b, 0);
return release;
})
.sort((a, b) => new Date(b.date) - new Date(a.date));
console.log('Processed releases:', downloadsByRelease);
if (downloadsByRelease.length === 0) {
return h('div', { class: 'charts' }, 'No release data available');
}
const maxDownloads = Math.max(...downloadsByRelease.map(r => r.total));
return h('div', { class: 'charts' }, [
h('div', { class: 'chart horizontal' }, [
h('div', { class: 'chart-legend' },
platforms.map(platform =>
h('div', { class: 'legend-item' }, [
h('span', {
class: 'legend-color',
style: `background-color: ${getColorForPlatform(platform)}`
}),
h('span', { class: 'legend-label' }, platform)
])
)
),
h('div', { class: 'chart-container horizontal' },
downloadsByRelease.map(release =>
h('div', { class: 'bar-group horizontal' }, [
h('div', { class: 'bar-label horizontal' }, [
h('span', { class: 'version-label' }, release.name),
h('span', { class: 'date-label' }, formatDate(release.date))
]),
h('div', { class: 'stacked-bars horizontal' },
platforms.map(platform => {
const width = (release.platforms[platform] / maxDownloads) * 400;
return h('div', {
class: 'bar stacked-bar horizontal',
style: `
width: ${width}px;
background-color: ${getColorForPlatform(platform)};
`,
title: `${platform}: ${release.platforms[platform].toLocaleString()} downloads`
});
})
),
h('div', { class: 'total-downloads' },
`${release.total.toLocaleString()} downloads`
)
])
)
)
])
]);
}