Work in progress atmosphere stats viewer
1

Configure Feed

Select the types of activity you want to include in your feed.

feat: add collapse non-bluesky toggle to pds distribution chart

+70 -28
+68 -7
src/routes/plc/PdsDistribution.svelte
··· 3 3 import { PieChart } from 'layerchart'; 4 4 5 5 const stats = getStats(); 6 + let collapse = $state(true); 7 + 8 + function format(raw: Record<string, number>, collapse: boolean) { 9 + const distribution = new Map<string, number>(); 10 + 11 + for (const [pds, count] of Object.entries(raw)) { 12 + const url = URL.parse(pds); 13 + const key = url?.hostname.endsWith('bsky.network') 14 + ? 'Bluesky PBC' 15 + : url && url.protocol === 'https:' && count > 300 && !collapse 16 + ? url.hostname 17 + : 'Other'; 18 + 19 + const total = distribution.getOrInsert(key, 0); 20 + distribution.set(key, total + count); 21 + } 22 + 23 + return distribution 24 + .entries() 25 + .map((d) => ({ key: d[0], value: d[1] })) 26 + .toArray() 27 + .sort((a, b) => { 28 + if (a.key === 'Bluesky PBC') return -1; 29 + if (b.key === 'Bluesky PBC') return 1; 30 + if (a.key === 'Other') return 1; 31 + if (b.key === 'Other') return -1; 32 + return b.value - a.value; 33 + }); 34 + } 6 35 </script> 7 36 8 37 <div class="chart"> 9 - <h4>PDS Distribution <small>(approx)</small></h4> 38 + <div class="title"> 39 + <h4>PDS Distribution <small>(approx)</small></h4> 40 + 41 + <label> 42 + Collapse non-Bluesky 43 + <input type="checkbox" role="switch" bind:checked={collapse} /> 44 + </label> 45 + </div> 10 46 11 47 {#if stats.loading} 12 48 <p>Loading...</p> 13 49 {:else if stats.current} 14 50 <PieChart 15 - data={stats.current.pdsDistribution} 51 + data={format(stats.current.pdsDistribution, collapse)} 52 + cRange={[ 53 + 'var(--primary)', 54 + '#ac21ed', 55 + 'var(--green)', 56 + 'var(--orange)', 57 + 'var(--secondary)', 58 + ]} 16 59 key="key" 17 60 value="value" 18 61 height={300} ··· 24 67 </div> 25 68 26 69 <style> 70 + .title { 71 + display: flex; 72 + justify-content: space-between; 73 + align-items: center; 74 + flex-wrap: wrap; 75 + gap: 8px; 76 + 77 + margin-top: 4px; 78 + margin-bottom: 16px; 79 + 80 + label { 81 + margin: 0px; 82 + display: flex; 83 + flex-direction: row-reverse; 84 + align-items: center; 85 + gap: 8px; 86 + 87 + input { 88 + margin: 0px; 89 + } 90 + } 91 + } 92 + 27 93 .chart { 28 94 background-color: var(--background-secondary); 29 95 border-radius: 12px; 30 96 padding: 8px 12px; 31 97 overflow: hidden; 32 - 33 - h4 { 34 - margin-top: 4px; 35 - margin-bottom: 16px; 36 - } 37 98 38 99 small { 39 100 font-size: 0.9rem;
+2 -21
src/routes/plc/plc.remote.ts
··· 39 39 } 40 40 41 41 interface Stats { 42 - pdsDistribution: { key: string; value: number }[]; 42 + pdsDistribution: Record<string, number>; 43 43 history: HistoryGraphPoint[]; 44 44 uses: PlcUses; 45 45 } 46 46 47 47 export const getStats = query<Stats>(async () => { 48 48 const raw = await fetchRawStats(); 49 - const distribution = new Map<string, number>(); 50 - 51 - for (const [pds, count] of Object.entries(raw.pdsDistribution)) { 52 - const url = URL.parse(pds); 53 - const key = url?.hostname.endsWith('bsky.network') 54 - ? 'Bluesky PBC' 55 - : url && url.protocol === 'https:' && count > 300 56 - ? url.hostname 57 - : 'Other'; 58 - 59 - const total = distribution.getOrInsert(key, 0); 60 - distribution.set(key, total + count); 61 - } 62 49 63 50 return { 64 51 uses: raw.uses, 65 - pdsDistribution: distribution 66 - .entries() 67 - .map((d) => ({ key: d[0], value: d[1] })) 68 - .toArray() 69 - .sort((a, b) => 70 - a.key === 'Other' || b.key === 'Other' ? -1 : b.value - a.value, 71 - ), 52 + pdsDistribution: raw.pdsDistribution, 72 53 history: Object.entries(raw.history) 73 54 .map(([date, d]) => ({ 74 55 date: new Date(date),