Steven
Steven9 min di lettura

Ridisegnare la dashboard attorno a un solo grafico a onda

GeekBye v1.8.2 ha trasformato la dashboard da telecomando di registrazione a una vista di analisi in sola lettura — una barra di statistiche e un grafico a onda su 7 giorni. Entrambi gli elementi distintivi erano secondi abbozzi, spediti entro venti minuti dai loro primi abbozzi, nello stesso pomeriggio.

Ingegneria
Design
Dashboard
Release di GeekBye
Ridisegnare la dashboard attorno a un solo grafico a onda

Alcune release aggiungono una feature. GeekBye v1.8.2 ne ha soprattutto rimossa una — ed è la rimozione la storia. In un solo pomeriggio di febbraio 2026, diciotto commit hanno trasformato la home della dashboard, da telecomando di registrazione a vista di analisi in sola lettura: quattro statistiche e un grafico di attività. Lungo la strada ha spedito un grafico a barre vissuto ventidue minuti, una griglia di card di statistiche vissuta venti e un'onda SVG fatta a mano che ha sostituito entrambi. Tutta la ricerca è conservata nei timestamp dei commit, che è il miglior tipo di documentazione di design che esista.

La dashboard ha smesso di essere un telecomando

Prima di questa release, la home della dashboard era un pannello di controllo. Apriva con una card hero — un grande widget di registrazione con un badge LIVE, pulsanti Pausa/Riprendi/Stop, macchie di gradiente e un hook useSessionState che cablava il tutto al registratore. La dashboard cercava di essere due cose insieme: il posto dove guardi le tue riunioni e il posto dove guidi il registratore. Due prodotti, uno schermo, in silenziosa competizione.

La v1.8.2 ne ha scelta una. Ha eliminato la card hero e il cablaggio di useSessionState — compreso un effetto che ti portava automaticamente alla pagina di dettaglio di una riunione nell'istante in cui una sessione finiva, esattamente quel tipo di salto «premuroso» che sorprende le persone nel mezzo del flusso. Avviare e nascondere il registratore sono passati a un semplice pulsante della navbar (un pulsante riadattato che ha perso un centinaio di righe passando da controller di sessione a interruttore acceso/spento), sostenuto da un nuovo handler IPC navbar:hide. Ciò che è rimasto era una dashboard che fa una cosa sola: mostrarti cosa hai registrato. Sola lettura. Calma.

C'è un piccolo bug, molto umano, in quella transizione che vale la pena segnalare, perché è il genere di cosa che un redesign introduce in sordina e che un buon occhio coglie nella stessa ora. I due nuovi pulsanti della barra laterale — Avvia e Nascondi — sono usciti con la stessa icona a griglia generica, quindi erano visivamente identici. Dodici minuti dopo, un follow-up ha dato ad Avvia un'icona di play, ha dato a Nascondi un'icona di occhio sbarrato e ha tinto Nascondi di ambra, così «far sparire l'app» si legge come un'azione deliberata anziché come il gemello neutro di «avvia». Le icone sono testo. Due pulsanti che sembrano uguali dicono la stessa cosa, e questi non significavano la stessa cosa.

Il grafico a barre vissuto ventidue minuti

Ecco la parte che adoro, ed è interamente leggibile dal git log. Alle 16:29:34 è atterrato il primo abbozzo del redesign: un grafico di attività su 7 giorni disegnato a barre — colonne animate, un'altezza minima perché i giorni minuscoli restassero visibili, un moncone smorzato di 2 pixel per i giorni a zero. Ragionevole. Convenzionale. Il tipo di grafico a cui ricorri senza pensarci.

Alle 16:51:21 — ventidue minuti dopo — è stato eliminato. Il commit di sostituzione dice esattamente cosa ha fatto: «replace bar chart with smooth wave area chart for 7-day activity» (sostituire il grafico a barre con un grafico ad area a onda morbida per l'attività su 7 giorni). E alle 16:52:21, un minuto dopo, un altro commit ha tolto la card arrotondata e il bordo attorno all'onda, «for cleaner look» (per un aspetto più pulito).

Perché? I commit dicono solo cosa è cambiato, quindi il perché è una lettura — ma la forma dei dati lo rende ovvio. Questo è uno strumento in cui un utente tipico ha zero, una o due riunioni in un dato giorno. Sette barre, la maggior parte alte 2 pixel, sembrano un parcheggio quasi vuoto. Gli stessi sette numeri disegnati come un'area piena continua sembrano una tendenza — un'onda dolce che sale dove la settimana è stata piena. Nulla è stato falsato; i valori in y sono identici. Il redesign ha semplicemente scelto la codifica che permette a dati sparsi e onesti di leggersi come una forma anziché come un'assenza.

Le statistiche hanno ricevuto lo stesso trattamento sullo stesso orologio. Il primo abbozzo (16:29) ha messo quattro numeri in una griglia 2×4 di card. Alle 16:49 la griglia è collassata in un'unica barra di statistiche in linea — una singola riga con bordo e divisori sottilissimi, tipografia più piccola, un contenitore invece di quattro. Cinque riquadri sullo schermo (quattro card più una card di grafico) sono diventati due (una barra e un'onda). La PR successiva ha aggiunto un altro tocco di onestà: l'etichetta «Total Time» è diventata «Time in Meetings» (Tempo in riunione), perché totale-di-cosa era una domanda legittima che nessuno dovrebbe dover fare.

Venti minuti, dal primo abbozzo alla versione finale, tutto dentro una sola pull request. Se quelli fossero stati schiacciati in un unico commit «redesign dashboard», la ricerca sarebbe invisibile. Poiché non lo sono stati, puoi vedere un designer convergere in tempo reale.

L'onda, meccanicamente

Qui non c'è nessuna libreria di grafici. L'onda è un SVG inline costruito in JSX, e vale un'occhiata perché è una ricetta piccola e onesta che puoi rubare per qualsiasi sparkline.

Lo smoothing è il trucco. Per ogni coppia di punti adiacenti, il path usa un segmento cubic-bezier i cui due punti di controllo stanno al punto medio orizzontale tra loro — cpx = (prev.x + curr.x) / 2 — con i punti di controllo mantenuti all'altezza propria di ciascuna estremità. È il classico smoothing a tangente piatta: la curva scorre dolcemente attraverso ogni punto dati senza mai superare al di sopra del valore più alto né al di sotto del più basso, cosa che farebbe una spline Catmull-Rom ingenua. Per un grafico sul numero di riunioni, «non disegnare mai una gobba che implichi un valore che non è avvenuto» non è un vezzo; è correttezza. L'area piena è la stessa curva chiusa lungo il fondo e dipinta con un gradiente verticale (ciano, che sfuma dal 30% a quasi nulla), e la linea si disegna da sola con un'animazione pathLength di framer-motion, da sinistra a destra.

Sotto l'SVG c'è l'idraulica dei dati, ed è l'eroina silenziosa. Un nuovo metodo getAggregateStats() sul repository delle trascrizioni esegue tre prepared statement contro la tabella SQLite locale transcript_sessions: totali di sempre (conteggio, durata sommata, durata media), un conteggio mobile su sette giorni e un bucket per giorno con GROUP BY date(created_at). Poi — e questo è il dettaglio che rende il grafico robusto — un piccolo ciclo JavaScript percorre gli ultimi sette giorni di calendario e riempie ogni giorno che la query non ha restituito, spingendo uno zero. Il grafico ha perciò garantiti esattamente sette punti, sempre.

È questa garanzia a far svanire i casi limite invece di richiedere guardie sparpagliate nella view. Una settimana vuota? Sette zeri, e un Math.max(count, 1) al denominatore tiene la linea piatta in basso invece di dividere per zero. Un singolo punto dati che farebbe produrre NaN alla formula di spaziatura in x i / (n − 1)? Non può succedere — il repository non emette mai meno di sette. Le etichette dei giorni della settimana fanno persino il parsing di ogni bucket a T12:00:00 anziché alla mezzanotte nuda, così una stringa YYYY-MM-DD non scivola al giorno precedente in un fuso orario con UTC negativo. Correggi la forma dei dati alla sorgente e il codice di rendering può permettersi di essere ingenuo di proposito.

Tutto resta sulla macchina. La query di statistiche legge il database locale, torna attraverso un canale IPC tipizzato transcript:get-stats e si anima in quattro numeri che contano verso l'alto al montaggio. Nulla della tua cronologia di riunioni lascia il laptop per disegnare questo grafico — il che, per uno strumento che registra le tue conversazioni, è l'unico modo accettabile di costruire una vista di analisi.

Un altro bug, perché i redesign li trascinano alla luce

Impacchettata nella stessa release c'era una correzione che non aveva nulla a che fare con la dashboard e tutto a che fare con il tipo di debito su cui un redesign inciampa. Lo stile della scrollbar scura dell'app era derivato in due definizioni CSS concorrenti della stessa classe — una più vecchia, viola, e una più nuova, bianca su scuro — e quale vincesse dipendeva dall'ordine della cascata. Peggio, solo gli elementi che si ricordavano di aggiungere la classe venivano stilizzati; tutto il resto ricadeva sulla scrollbar chiara di default, e le scrollbar orizzontali non sono mai state stilizzate perché le vecchie regole impostavano solo una larghezza, mai un'altezza. La correzione ha eliminato entrambe le definizioni, ha stilizzato la scrollbar globalmente su ogni elemento e ha rimosso la classe ormai morta dai dieci componenti che se la portavano dietro. È un diff di due righe ripetuto dieci volte — la tassa poco glamour dell'aver stilizzato la stessa cosa due volte e lasciato sopravvivere entrambe.

Tre cose che questa release ci ha insegnato

  1. Sottrai per mettere a fuoco. La dashboard è migliorata facendo meno — perdendo i controlli di registrazione di cui non aveva mai avuto bisogno e diventando una cosa chiara. Uno schermo che è insieme un visualizzatore e un telecomando sono due mezzi-prodotti; scegline uno e sposta l'altro dove gli spetta.
  2. Scegli la codifica che i tuoi dati meritano. Conteggi sparsi si leggono come assenza a barre e come tendenza in un grafico ad area, a partire da numeri identici. Non è maquillage — è scegliere la forma onesta che lascia comunicare dati reali e radi.
  3. Garantisci la forma dei dati a monte. Il ciclo di riempimento-fino-a-sette è il motivo per cui il codice del grafico non ha controlli di null sparsi: divisione per zero, NaN a punto singolo e giorni mancanti spariscono tutti perché la query promette esattamente sette bucket. Il rendering robusto inizia uno strato più sotto.

Per il capitolo precedente della storia v1, quattro release in ventisei ore (v1.7.6–v1.8.1); e per tutto l'arco, l'anatomia del pubblicare software fino alla perfezione.