Steven
Steven7 min. skaitymo

Dashboardo perprojektavimas aplink vieną banguotą grafiką

GeekBye v1.8.2 pavertė dashboardą iš įrašymo nuotolinio pulto į tik-skaitymui skirtą analitikos vaizdą — statistikos juostą ir 7 dienų banguotą grafiką. Abu firminiai elementai buvo antrieji juodraščiai, išleisti per dvidešimt minučių po pirmųjų, tą pačią popietę.

Inžinerija
Dizainas
Dashboard
GeekBye leidimai
Dashboardo perprojektavimas aplink vieną banguotą grafiką

Kai kurie leidimai prideda funkciją. GeekBye v1.8.2 daugiausia vieną pašalino — ir tas pašalinimas čia yra istorija. Per vieną popietę 2026 vasarį aštuoniolika commitų pavertė dashboardo pradinį puslapį iš įrašymo nuotolinio pulto į tik-skaitymui skirtą analitikos vaizdą: keturios statistikos ir vienas aktyvumo grafikas. Pakeliui jis išleido stulpelinę diagramą, gyvenusią dvidešimt dvi minutes, statistikos kortelių tinklelį, gyvenusį dvidešimt, ir ranka padarytą bangą SVG, kuri pakeitė abi. Visa ši paieška išsaugota commitų laiko žymose, o tai geriausia dizaino dokumentacijos rūšis, kokia tik būna.

Dashboardas nustojo būti nuotoliniu pultu

Prieš šį leidimą dashboardo pradinis puslapis buvo valdymo pultas. Jį atverdavo hero kortelė — didelis įrašymo valdiklis su LIVE ženkleliu, Pause/Resume/Stop mygtukais, gradientinėmis dėmėmis ir useSessionState hooku, sujungiančiu visa tai su rekorderiu. Dashboardas bandė būti dviem dalykais iškart: vieta, kurioje žiūri savo susitikimus, ir vieta, iš kurios valdai rekorderį. Du produktai, vienas ekranas, tyliai konkuruojantys.

v1.8.2 pasirinko vieną. Jis pašalino hero kortelę ir visą useSessionState apvyniojimą — įskaitant efektą, kuris automatiškai permesdavo tave į susitikimo detalių puslapį tą akimirką, kai sesija baigdavosi, o tai kaip tik toks „naudingo" šuolio tipas, kuris išmuša žmones darbo įkarštyje. Rekorderio paleidimas ir slėpimas persikėlė į paprastą navbaro jungiklį (perdarytas mygtukas, sulieknėjęs maždaug šimtu eilučių pakeliui iš sesijos kontrolerio į on/off perjungiklį), paremtas nauju IPC handleriu navbar:hide. Liko dashboardas, kuris daro vieną dalyką: rodo tau, ką įrašei. Tik skaitymui. Ramus.

Šiame perėjime slypi mažas, žmogiškas bug, vertas paminėti, nes tai toks dalykas, kurį redizainas tyliai įveda, o gera akis pagauna tą pačią valandą. Du nauji šoninės juostos mygtukai — Start ir Hide — išėjo su ta pačia bendrine tinklelio ikona, tad buvo vizualiai identiški. Po dvylikos minučių pataisa davė Start play ikoną, davė Hide perbrauktos akies ikoną ir nudažė Hide gintariškai, kad „padaryk, kad programa dingtų" skaitytųsi kaip tyčinis veiksmas, o ne neutralus „starto" dvynys. Ikonos yra tekstas. Du mygtukai, kurie atrodo vienodai, sako tą patį, o šie nereiškė to paties.

Stulpelinė diagrama, gyvenusi dvidešimt dvi minutes

Štai dalis, kurią dievinu, ir ji visiškai perskaitoma iš git logo. 16:29:34 nusileido pirmas redizaino juodraštis: 7 dienų aktyvumo grafikas, nubraižytas kaip stulpeliai — animuotos kolonos, minimalus aukštis, kad mažytės dienos liktų matomos, 2 pikselių blankus kelmelis nulinėms dienoms. Protinga. Įprasta. Toks grafikas, kurio griebiesi negalvodamas.

16:51:21 — dvidešimt dvi minutes vėliau — jis buvo pašalintas. Pakeičiantis commit sako tiksliai, ką jis padarė: „replace bar chart with smooth wave area chart for 7-day activity". O 16:52:21, minute vėliau, kitas commit nuėmė suapvalintą kortelę ir rėmelį aplink bangą — „for cleaner look".

Kodėl? Commitai sako tik, kas pasikeitė, tad kodėl yra interpretacija — bet duomenų forma daro tai akivaizdu. Tai įrankis, kuriame tipiškas naudotojas turi nulį, vieną ar du susitikimus bet kurią konkrečią dieną. Septyni stulpeliai, dauguma 2 pikselių aukščio, atrodo kaip beveik tuščia stovėjimo aikštelė. Tie patys septyni skaičiai, nubraižyti kaip ištisinis užpildytas plotas, atrodo kaip tendencija — švelni banga, kylanti ten, kur savaitė buvo įtempta. Nieko nesuklastota; y reikšmės identiškos. Redizainas tiesiog pasirinko kodavimą, leidžiantį retiems, sąžiningiems duomenims skaitytis kaip forma, o ne kaip nebuvimas.

Statistikos gavo tokį patį traktavimą tuo pačiu laikrodžiu. Pirmas juodraštis (16:29) sudėjo keturis skaičius į 2×4 kortelių tinklelį. 16:49 tinklelis susitraukė į vieną įterptinę statistikos juostą — viena rėmeliu apibrėžta eilutė su plaukelio storio skirtukais, mažesniu šriftu, vienu konteineriu vietoj keturių. Penkios dėžės ekrane (keturios kortelės plius grafiko kortelė) tapo dviem (juosta ir banga). Kitas PR pridėjo dar vieną sąžiningą prisilietimą: etiketė „Total Time" (Iš viso laiko) tapo „Time in Meetings" (Laikas susitikimuose), nes iš-viso-ko buvo teisingas klausimas, kurio niekas neturėtų būti priverstas užduoti.

Dvidešimt minučių, nuo pirmo juodraščio iki galutinio, viskas viename pull request. Jei tie būtų suspausti į vieną commitą „redesign dashboard", paieška būtų nematoma. Kadangi nebuvo, gali stebėti, kaip dizaineris realiu laiku suartėja prie sprendimo.

Banga, mechaniškai

Čia nėra jokios grafikų bibliotekos. Banga yra įterptinis SVG, sukurtas JSX, ir į ją verta pažvelgti, nes tai mažas, sąžiningas receptas, kurį gali pasivogti bet kokiam sparkline.

Glotninimas yra visas triukas. Kiekvienai gretimų taškų porai kelias naudoja kubinės Bezier kreivės segmentą, kurio du kontroliniai taškai sėdi horizontaliame viduryje tarp jų — cpx = (prev.x + curr.x) / 2 — o kontroliniai taškai laikomi kiekvieno galo paties aukštyje. Tai klasikinis plokščios liestinės glotninimas: kreivė sklandžiai pereina pro kiekvieną duomenų tašką niekada neperšaudama virš aukščiausios ar žemiau žemiausios reikšmės, ką padarytų naivus Catmull-Rom splainas. Grafikui apie susitikimų skaičių „niekada nebraižyk kuprelės, kuri reiškia neįvykusią reikšmę" yra ne gražmena; tai korektiškumas. Užpildytas plotas yra ta pati kreivė, uždaryta palei apačią ir nudažyta vertikaliu gradientu (žydra, blėstanti nuo 30% beveik iki nieko), o linija pati save nubraižo framer-motion pathLength animacija, iš kairės į dešinę.

Po SVG yra duomenų vamzdynas, ir jis yra tylusis herojus. Naujas getAggregateStats() metodas transkriptų repozitorijuje paleidžia tris paruoštas užklausas prieš vietinę SQLite transcript_sessions lentelę: visų laikų sumas (kiekis, sudėta trukmė, vidutinė trukmė), slenkantį septynių dienų skaičių ir krepšį dienai GROUP BY date(created_at). Tada — ir tai detalė, daranti grafiką atsparų — maža JavaScript kilpa pereina paskutines septynias kalendorines dienas ir užpildo atgal kiekvieną dieną, kurios užklausa negrąžino, įstumdama nulį. Todėl grafikas garantuotai turi lygiai septynis taškus, visada.

Būtent ši garantija priverčia kraštinius atvejus išnykti, užuot reikalavusi sargų, išbarstytų po visą vaizdą. Tuščia savaitė? Septyni nuliai, o Math.max(count, 1) vardiklyje laiko liniją plokščią apačioje, užuot dalijusi iš nulio. Vienas duomenų taškas, dėl kurio x ašies tarpo formulė i / (n − 1) pagamintų NaN? Negali nutikti — repozitorijus niekada neišspjauna mažiau nei septynių. Savaitės dienų etiketės netgi parsina kiekvieną krepšį ties T12:00:00, o ne ties pliku vidurnakčiu, kad YYYY-MM-DD eilutė nenuslystų į ankstesnę dieną neigiamo UTC laiko juostoje. Pataisyk duomenų formą prie šaltinio, ir atvaizdavimo kodas gali būti naivus tyčia.

Visa tai lieka mašinoje. Statistikos užklausa skaito vietinę duomenų bazę, grįžta per tipizuotą IPC kanalą transcript:get-stats ir montuojantis animuojasi į keturis į viršų skaičiuojančius skaičius. Niekas iš tavo susitikimų istorijos nepalieka nešiojamojo, kad nubraižytų šį grafiką — o tai įrankiui, kuris įrašo tavo pokalbius, vienintelis priimtinas būdas sukurti analitikos vaizdą.

Dar vienas bug, nes redizainai ištraukia juos į šviesą

Į tą patį leidimą buvo įpakuota pataisa, neturinti nieko bendra su dashboardu ir viską bendra su tokia skola, už kurios redizainas užklumpa. Programos tamsios slinkties juostos stilizavimas buvo nuslydęs į du konkuruojančius CSS apibrėžimus tos pačios klasės — senesnį violetinį ir naujesnį baltą-ant-tamsaus — ir tai, kuris laimėjo, priklausė nuo kaskados tvarkos. Blogiau, stilizuojami buvo tik elementai, kurie prisiminė pridėti klasę; visa kita grįždavo prie numatytosios šviesios slinkties juostos, o horizontalios slinkties juostos niekada nebuvo stilizuojamos, nes senos taisyklės nustatydavo tik plotį, niekada aukštį. Pataisa pašalino abu apibrėžimus, stilizavo slinkties juostą globaliai ant kiekvieno elemento ir pašalino dabar-mirusią klasę iš dešimties komponentų, kurie ją nešiojo. Tai dviejų eilučių diff, pakartotas dešimt kartų — neblizgus mokestis už tai, kad tas pats dalykas buvo stilizuotas dukart, o abi versijos paliktos gyventi.

Trys dalykai, kurių mus išmokė šis leidimas

  1. Atimk, kad susifokusuotum. Dashboardas pagerėjo darydamas mažiau — netekęs įrašymo valdiklių, kurių jam niekada nereikėjo, ir tapęs vienu aiškiu dalyku. Ekranas, kuris yra ir peržiūra, ir nuotolinis pultas, — tai du pusprodukčiai; pasirink vieną, o kitą perkelk ten, kur jo vieta.
  2. Pasirink kodavimą, kurio nusipelno tavo duomenys. Reti skaičiai skaitosi kaip nebuvimas stulpeliuose ir kaip tendencija area charte — iš identiškų skaičių. Tai ne manipuliacija; tai sąžiningos formos pasirinkimas, leidžiantis tikriems, liesiems duomenims ką nors pasakyti.
  3. Garantuok duomenų formą aukščiau sraute. Užpildymo-iki-septynių kilpa yra priežastis, kodėl grafiko kode nėra išbarstytų null patikrų: dalyba iš nulio, NaN vieno taško ir trūkstamos dienos visos išnyksta, nes užklausa žada lygiai septynis krepšius. Atsparus atvaizdavimas prasideda sluoksniu žemiau.

Ankstesniam v1 istorijos skyriui — keturi leidimai per dvidešimt šešias valandas (v1.7.6–v1.8.1); o visai istorijos linijai — programinės įrangos tobulybės pristatymo anatomija.

Susiję straipsniai