Галоўная / Артыкулы

D3.js унутрь React: прыўязка дадзеных, SVG і правіла власнасці з useEffect

Дакле, што на самай працо ёсць D3, як функціонуе прыўязка дадзеных, як вносіць/ацыянуваць/выходзіць з прыўязкі, чаму SVG падходзіць для яго, і як раздзеліць кераванне DOM, каб D3 і React моглі саўместна працаваць у столбчастай дыяграме.

Выдавец: REACTAPP.TOP7 хв чытання1530 слоў

Крыніцы: Harnessing the Power of Data Visualization: Integrating D3.js with React

Тры наявыскі, якія трэба ведаць спачатку

  1. D3 — гэта інструментальны набор, а не бібліятэка для стварэння дыяграм. Людзі, якія спакульваюцца на ўсё, сэрцаваючыся чымось на кшталт Chart.js, сталкнуцца з труднасцямі. D3 — гэта нізкага рэвэля механізм для прыўязкі дадзеных да элементаў DOM, што адказвае як за яго моц, так і за большую складнасць у вучэнні.
  2. React і D3 конкуруюць за тыя ж элементы DOM. Рашэнне проста: React атрыбуець кантэйнер SVG, а D3 керуе всім, што ў ім ёсць, за дапамогою useEffect. Калі прыгнуць гэтая правіла, даведзецца гадзіны прасіцься з дзівнымі конфліктамі.
  3. Шаблон enter, update і exit спачатку здаецца дзівным. Пасля калькі справак ён стане зрозумелым, а іншыя падходы да графікі, стваранай на адной з дадзеных, падаюць пад вопыт.

Што на самай працэ D3

Эта назва парадоксальна, адзначаючы “Дакументы, керованыя дадзеннямі”. Важлівым словам ёсць “дакументы”: элементы DOM, выгляд якіх задаецца дадзеннямі. D3 прыяўляе масівы да элементаў і дазваляе вам задаць ўзгляд на аднойчыну з значэннямі ў тых масівах. Графік — толькі адна з можлівых рэзультатаў, а сама бібліятэка не мае уявлення пра тыпы графікаў.

Сяродзе тут і крыець сілы, і сложнасці. D3 не прымеўляе рашэнняў за вас. Кожная візуальная характэрыстыка, кожны пазначкі на вісі, кожны калер і кожная взаімадзея прымушаныя задавацца вам. Вы атрымліваеце абсалютную творчую свабоду, але і многа працы з пісанням коду.

Прыяўленне дадзенняў і DOM

Сяродзе тут большасць новачакоў здаецца, таму варта адносна пашагоўна разбіраць гэта пытанне.

У звычнай JavaScript вы створаеце элемент, заполняеце яго контэнтам і вставляеце ў сторанку. З D3 вы выбіраеце групу элементаў, укладаючы ў яе нават тыя, якія яшчэ не існуюць, прыяўляеце масів да гэтага выбору, а пасля отрымаеце тры групы:

  • элементы, якія вялікі час вучыцца і проста патрабуюць новых дадзеных (выбор для апдэйта),
  • точкі дадзеных, якія яшчэ не маюць элемента (выбор для дадзення новых элементаў),
  • элементы, дадзеныя якіх зніклі (выбор для выключэння элементаў).

Странна частка — гэта вызванне методаў на выбраным элементах, якія ўсё ў той жа час пустыя. Вы выбіраеце всі элементы rect унутроц SVG, які не мае такіх элементаў, вызываеце .data(myArray), потым .enter(), а пасля .append('rect'), і тады з’яўляюцца прамоугольнікі. Насправды .enter() стварае місцэвыя заменікі для кожнага дадзення, якому не хапае элемента, а .append() ператварае кожны такі заменік у рэальны вузол. Можна гэта спрыятаць як «для кожнай точкі дадзення, якой не хапае элемента, стварыць адны».

Да таго часу, калі код D3 працюе, ён выглядае як чары. А пасля — чытаецца цалкам прыродна.

Настаўленне візуальных атрыбутаў на адной з дадзеных

Калі дадзеныя ужо прыўязаны, наступны крок стае простым для разумення. Будзь-які атрыбут чы стыль можна вырахаваць на адной з дадзеных:

selection.attr('height', d => yScale(d.value))

Хутчэй, d — гэта даны, прыязначаныя данаму элементу, а yScale — гэта функцыя, якая перакладвае дыяпазон значэнняў у пікселі. Высота ступеня ёсць прымытным наследкам яго дадзеных. Змяніце дадзеныя, запрацаваце код зноў, і высота будзе змяніцца. Практычна все ў візуалізацыях D3 вырашваецца за дапамою варыяцый гэтай ідэі: прыязначыце візуальную характэрыстыку як функцыю ад значэння, якое ёй задана.

Чаму SVG?

D3 адрасавае змест на SVG, і прычыны гэтага выходзяць за межы історыі.

SVG ўоснована на вектарах, таму фарматы візначаюцца матэматычна, а не як сіткі пікселів. Графік у віглядзе ступеня застаецца чыстым як на ноутбуку, так і на экране 4K без дадатковых зусіль, а экспортаваныя файлы не становяцца размытымі пры некальканадзесятых разрахунках.

Для інтэрактыўнасці важлівы тое, што фармы SVG ёсць звычныя элементы DOM і беруць удзел у сістэме запуску запісаў браузера так сама, як і кнопкі. Дзіянні на курсоры, клікі і дотыкі працуюць без додатковых перацэнак удару, таму што проста прыўязваюцца слухачы.

Затраты стаюць значнымі пры велікім колькасці элементаў. Тыясчы вузлаў SVG спамляюць працэс завантажэння стораніцы, таму стварэнне 50 000 окрэмых тачак як аддзінальных элементаў будзе негатыўна паўтарыцца. Рэндэрынг на canvas лепей падходзіць для такіх сітуацыяў. Для панелей керування, бізнес-графікаў і большасці аналітычных інструментаў SVG ўсё ж падходзіць, а інтэграцыя запісаў варта тых зусіль.

Інтэрактыўнасць і гнучкасць

Інтэрфейсы для аналізу дадзэнняў, дзе корыстувальнікі можаць фільтруваць, аналізаваць і дакладна розглядаць дадзеныя з разных кантактных точак, — гэта там, дзе D3 перавышае статычныя інструменты для стварэння графікаў. Вы контролюеце кожны запіс і пераход.

Большасць бібліятэкаў для стварэння дыяграм даўае вам варыянты дыяграм, якія можна настроіць: ступеневыя, лінейныя, кругавыя, з можлівасцю выбору кольцаў, пазначэнняў і легенд. D3 жа задае базовыя элементы: шкалы, вось, генераторы ліній і алгорытмы распакоўкі. Тып дыяграмы — гэта проста ўзаеднанне гэтых элементаў, таму не існуе спісу таго, што падтрымліваецца. Калі якой-небудзь візуалізацыі няма нідзе, яе можна стварыць, пры чым едынай меры ўскорання ёсць SVG і матэматыка.

Цэна — гэта дадатковая праця. Чы рэальна гэта, залежыць ад праекту. Для стандартных дыяграм для бізнесу падойду Recharts або Chart.js, і можна працаваць далей. Для індывідуальных, інтэрактыўных графіків, дзе важна точнае прадстаўленне, D3 ёсць лепшы выбар.

Функцыі, якія вы будзеце часта вжываць

Гэта не повны справак, толькі тые функцыі, якія выкарыстоўваюцца ў павсякдзеннай працы:

  • d3.select() выбірае першы элемент, які падходзіць па селектар. У React d3.select(svgRef.current) — гэта стандартны спосаб з’явіцца да кантэйнера.
  • d3.selectAll() вяртае всі прыдатны элементы. Зазвычай тут і пачынаецца прыўязка дадзеных, таму што задэйствавана калькі элементаў.
  • selection.data() спаявае кожны элемент з пунктом масівы, так што d будзе доступны пад час пазнейшых вызоваў. Усе інша залежыць ад гэтага крока.
  • selection.enter() стварае тэмпарарыяны выбір для дадзеных, якія не маюць вузлаў, а .append() пасля гэтага стварае самі вузлы.
  • selection.attr() задае атрыбуты, напрыклад лінію высоты, якую трэба запісаць сотні разоў.
  • selection.style() выконвае тое жа для CSS, напрыклад, задае колер заполнення або ступень прозрачнасці, якая залежыць ад таго, чы рэчак актыўны.
  • selection.transition() стварае анімацыю змян. Яго трэба размясціць раней за .attr() або .style(), і тады значэнні плавна пераходзяць, ператвараючы рывок у анімацыю.
  • d3.scaleLinear() перакладае значэнні з аднаго чысловага дыяпазона ў іншы. Калі домэн — 0 да 100, а дыяпазон — 0 да 400, значэнне 50 падае на піксель 200. Масштабаванні вікорыстоўваюцца практычна ў кожной візуалізацыі.
  • d3.axisBottom() і d3.axisLeft() ствараюць восьры для показу значэнняў з масштабавання, з выметкамі і пазначэннямі, таму не трэба ручна малюваць ція знакі.
  • d3.max() вяртае самае большое значэнне, якое часта выкорыстоўваецца для задання домэнаў масштабавання, напрыклад, у d3.max(data, d => d.value).
  • d3.transition() скоордынавае анімацыі для кальколькіх выбраных элементаў адразу.
  • Іспытанне D3 унутрошчы React

    Проблема, пра якую ніхто не гаворыць, пакуль яе не зустрэнеш: React зберагае віртуальны DOM і застосоўвае сваія змяны да рэальнага, тады калі D3 правіць змяны безпасэродзе ў рэальным DOM. Калі обе бібліятэкі працуюць унутрошчы аднаго элемента, перыядынацыя React перазапіша работу D3, або D3 дадае вузлы, пра якія React не ведае, і наступная перыядынацыя стане плямавай.

    Эфектыўны падход — разпадзел адпаведнасцяў. React перыядынацуе кантэйнер SVG і не чыніць нічога ў яго ўнутры. D3 прабіраеся да гэтага контэйнера праз ref і выкананае ўсю сваю работу ў useEffect. Калі змянююцыся даны, апдэйт стану запускае гэты эфект, і D3 чыстае і перазрысоввае элементы. Ніякая з бібліятэкаў не пераскладвае работу іншай.

    1. Установіце пакеты

    Аддыруйце D3 разам з React і ReactDOM за дапамою вашага менеджэра пакетаў.

    npm install d3 react react-dom
    

    Пользоватары пражы рабяцуюць тое ж сама за дапамою свайго сабецькага каманды add.

    yarn add d3 react react-dom
    

    2. Запісаце компонент

    У частцы React ёсць адна задача: адразу выканаць элемент SVG і даць D3 кансэл да яго. Нічога іншага ў візуалізацыі не належыць до React.

    3. Адрысаванне ў useEffect

    У функцыі effect запісуйце код D3 так сама, як і паza React, выкарыстоўваючы кансэл, каб знайсці кантэйнер. Две шкалы выканаюць вырахунакі коордынатаў: адна перадае меткі катэгарыяў у горызонтальныя пазыцыі, а другая — значэнні дадзеных у вертыкальныя. Высота кожнай стрэлкі равная ніжняй межы графіка за вырахунакам шкалаванага значэння. Гэта частка часта стварае проблемы, таму што вісь y у SVG спрамована вярху, тэму вышэйшыя стрэлкі адпавядаюць меншым значэнням y.

    4. Выканаце компонент

    Размясціце компонент у сваёй аплікацыі і перадайце яму масэвую дадзеныя. Зменіце масэвую дадзеныя, і графік парадрукаваецца: React з’являецца пра змененыя проп, запускаецца эфект, а D3 чыстае і парадрукавае графік. Зв’язак между станам аплікацыі і візуалізацыяй ўтвараецца аўтаматычна.

    5. Запускайце аплікацыю

    Запускайце сервер разработкі за дапамою npm.

     npm start
    

    Або з Yarn.

     yarn start
    

    У прыгушчыку вы паблікуеце ступенчатую дыяграму. Адтуда ўсё будуе за аднаковым прыцэпам: падказкі пад курсарам, шкалы кольцаў, анімаваныя апдэты, зум і іншыя тыпы дыяграм. Усё гэта знаходзіцца ў гэтым эфекце і выкарыстоўвае вышэй пераказаныя функцыі.

    Падсумак

    D3 і React саўместна працуюць, калі структура правільная. React керуе кантэйнерам і жыццёвым цыклам компонента, а D3 — адрасаваннем унутры яго. Чыста пазначыце гэтыя межы, і кожная бібліятэка будзе выкананая для сваёй мэты.

    Прыдзеў — гэта можлівасць ствараць візуалізацыі, якіх няма ў жадных пакетах дыяграм, таму што вы працуеце з прымітывамі, а не з параметрамі налаштавання. Калі сам графік ёсць часткай цянінаў продукту, гэта мае значэнне. Калі панелі керування патрэбна толькі лінейная дыяграма, выкорыстайце Recharts і адмовіцеся ад додатковых налаштаванняў.