Łączenie React, D3 i ich ekosystemu
Opublikowany: 2022-03-10Od momentu powstania w 2011 roku, D3.js stał się de facto standardem do budowania złożonych wizualizacji danych w sieci. React również szybko dojrzewa jako biblioteka z wyboru do tworzenia interfejsów użytkownika opartych na komponentach.
Zarówno React, jak i D3 to dwa doskonałe narzędzia zaprojektowane z celami, które czasami kolidują. Obaj przejmują kontrolę nad elementami interfejsu użytkownika i robią to na różne sposoby. Jak możemy sprawić, by współpracowali ze sobą, jednocześnie optymalizując ich wyraźne zalety zgodnie z bieżącym projektem?
W tym poście zobaczymy, jak możemy podejść do budowania projektów React, które potrzebują potężnej dobroci wykresów D3. Odkryjemy różne techniki i jak wybrać najlepszą bibliotekę do Twoich potrzeb w Twojej głównej pracy i projektach pobocznych.
D3 i DOM
D3 w D3.js oznacza dokumenty oparte na danych. D3.js to niskopoziomowa biblioteka zawierająca elementy niezbędne do tworzenia interaktywnych wizualizacji. Wykorzystuje standardy internetowe, takie jak SVG, HTML, canvas i CSS, aby zbudować front-endowy zestaw narzędzi z rozległym interfejsem API i prawie nieograniczoną kontrolą nad wyglądem i zachowaniem wizualizacji. Zapewnia również kilka funkcji matematycznych, które pomagają użytkownikom obliczać złożone ścieżki SVG.
Jak to działa?
Krótko mówiąc, D3.js ładuje dane i dołącza je do DOM. Następnie wiąże te dane z elementami DOM i przekształca te elementy, w razie potrzeby przechodząc między stanami.
Selekcje D3.js są podobne do obiektów jQuery, ponieważ pomagają nam radzić sobie ze złożonością SVG. Sposób, w jaki to się robi, jest porównywalny do sposobu, w jaki jQuery radzi sobie z elementami HTML DOM. Obie biblioteki mają również podobne API oparte na łańcuchach i wykorzystują DOM do przechowywania danych.
Połączenia danych
Jak wyjaśniono w artykule Mike'a Bostocksa „Thinking with Joins”, złączenia danych to proces, w którym D3 łączy dane z elementami DOM za pomocą selekcji.
Złączenia danych pomagają nam dopasować dane, które dostarczamy, do już utworzonych elementów, dodawać brakujące elementy i usuwać elementy, które nie są już potrzebne. Wykorzystują selekcje D3.js, które w połączeniu z danymi dzielą wybrane elementy na trzy różne grupy: elementy, które należy utworzyć (grupa wejść), elementy wymagające aktualizacji (grupa aktualizacji) i elementy, które wymagają do usunięcia (grupa wyjściowa).

W praktyce obiekt JavaScript z dwiema tablicami reprezentuje łączenie danych. Operacje na grupach wejścia i wyjścia możemy wywołać poprzez wywołanie metod wejścia i wyjścia selekcji, podczas gdy możemy bezpośrednio operować na grupie aktualizacji w najnowszej wersji D3.js.
Jak opisuje Bostock, dzięki łączeniom danych „można wizualizować dane w czasie rzeczywistym, umożliwiać interaktywną eksplorację i płynnie przechodzić między zestawami danych”. W rzeczywistości są algorytmem porównania, podobnym do sposobu, w jaki React zarządza renderowaniem elementów podrzędnych, jak zobaczymy w kolejnych sekcjach.
Biblioteki D3
Społeczność D3 nie znalazła standardowego sposobu tworzenia komponentów z kodu D3, co jest częstą potrzebą, ponieważ D3.js jest wyjątkowo niskopoziomowy. Można powiedzieć, że istnieje prawie tyle samo wzorców enkapsulacji, co bibliotek opartych na D3, chociaż zamierzam je sklasyfikować — poprzez ich API — na cztery grupy: zorientowane obiektowo, deklaratywne, funkcjonalne i połączone (lub podobne do D3).
Zrobiłem kilka badań nad ekosystemem D3.js i wybrałem mały, wysokiej jakości podzbiór. Są to aktualne biblioteki z D3.js w wersji 4 i dobrym pokryciem testowym. Różnią się rodzajem API i szczegółowością ich abstrakcji.
Drukowalny
Plottable to popularna, zorientowana obiektowo biblioteka do tworzenia wykresów, charakteryzująca się niską szczegółowością; więc musimy ręcznie ustawić osie, skale i wykresy, aby komponować wykresy. Przykład możesz zobaczyć tutaj.

Billboard
Billboard to rozwidlenie słynnej biblioteki C3.js, zaktualizowanej o kompatybilność z D3.js w wersji 4 i mającej na celu zapewnienie ciągłości tej klasycznej biblioteki. Jest napisany przy użyciu ECMAScript 6 i nowych nowoczesnych narzędzi, takich jak Webpack. Jego API opiera się na obiektach konfiguracyjnych przekazywanych do wykresów, więc możemy powiedzieć, że jest to API deklaratywne.

Vega
Vega idzie nieco dalej deklaratywną ścieżką, ewoluując konfiguracje z obiektów JavaScript do czystych plików JSON. Ma na celu wdrożenie gramatyki wizualizacji inspirowanej The Grammar of Graphics , książką Lelanda Wilkinsona, która formalizuje elementy składowe wizualizacji danych i która była również inspiracją dla D3.js. Możesz bawić się jego edytorem, wybierając jeden z przykładów jako punkt wyjścia.

D3FC
D3FC korzysta z D3.js i niestandardowych bloków konstrukcyjnych, aby pomóc w tworzeniu potężnych interaktywnych wykresów zarówno w formacie SVG, jak i kanwie. Posiada funkcjonalny interfejs o niskiej szczegółowości i dużą ilość kodu D3.js, więc chociaż jest potężny, prawdopodobnie wymaga trochę nauki. Sprawdź jego przykłady.

Brytecharts
Britecharts — biblioteka stworzona przez firmę Eventbrite, której jestem głównym współtwórcą — wykorzystuje interfejs Reusable Chart API, wzorzec enkapsulacji spopularyzowany przez Mike'a Bostocka w jego poście „Towards Reusable Charts” i stosowany w innych bibliotekach, takich jak NVD3. Britecharts tworzy abstrakcję wysokiego poziomu, ułatwiając tworzenie wykresów, zachowując jednocześnie niską złożoność w środku, umożliwiając programistom D3 dostosowywanie Britecharts do ich użytku. Spędziliśmy dużo czasu na tworzeniu dopracowanego interfejsu użytkownika i wielu przystępnych dem.

Podsumowując biblioteki według ich API, moglibyśmy je przedstawić w ten sposób:

Reaguj i DOM
React to biblioteka JavaScript, która pomaga nam budować interfejsy użytkownika poprzez komponowanie komponentów . Te składniki śledzą swój stan i przekazują właściwości, aby skutecznie ponownie renderować się, optymalizując wydajność aplikacji.
Jak to działa?
Wirtualny DOM, który jest reprezentacją aktualnego stanu DOM, jest technologią, która umożliwia optymalizacje ponownego renderowania w React. Biblioteka używa złożonego algorytmu porównania, aby zrozumieć, które części aplikacji wymagają ponownego renderowania, gdy zmienią się warunki. Ten algorytm różnicowy nazywa się „algorytmem uzgadniania”.
Dynamiczne komponenty potomne
Podczas renderowania komponentów, które zawierają listę elementów, programiści muszą użyć unikalnej właściwości „klucza” dołączonej do komponentów podrzędnych. Ta wartość pomaga algorytmowi porównania określić, czy element musi być ponownie renderowany, gdy nowe dane — lub stan, jak to się nazywa w świecie React — są przekazywane do komponentu. Algorytm uzgadniania sprawdza wartości kluczy, aby zobaczyć, czy element wymaga dodania lub usunięcia. Czy to wydaje Ci się znajome po poznaniu złączeń danych D3.js?
Od wersji 0.14, React również przechowuje renderer w osobnym module. W ten sposób możemy wykorzystać te same komponenty do renderowania w różnych mediach, takich jak aplikacje natywne (React Native), rzeczywistość wirtualna (React VR) i DOM (react-dom). Ta elastyczność jest podobna do sposobu, w jaki kod D3.js może być renderowany w różnych kontekstach, takich jak SVG i kanwa.
Reaguj i D3.js
Zarówno React, jak i D3 mają wspólny cel, jakim jest pomoc w radzeniu sobie z DOM i jego złożonością w wysoce zoptymalizowany sposób. Dzielą one również preferencję dla czystych funkcji — kodu, który dla danego wejścia zawsze zwraca te same dane wyjściowe bez powodowania skutków ubocznych — oraz komponentów bezstanowych.
Jednak wspólna troska o DOM sprawia, że te dwie uparte biblioteki ścierają się podczas określania, która ma renderować i animować elementy interfejsu użytkownika. Zobaczymy różne sposoby rozwiązania tego sporu i że nie ma łatwej odpowiedzi. Moglibyśmy jednak ustalić twardą zasadę: nigdy nie powinni dzielić kontroli nad DOM . To byłby przepis na katastrofę.
Podejścia
Integrując React i D3.js, możemy to robić na różnych poziomach, opierając się bardziej na stronie D3.js lub React. Zobaczmy nasze cztery główne wybory.
D3.js w React
Pierwszym podejściem, jakie możemy zastosować, jest zapewnienie naszemu kodowi D3 jak największej kontroli DOM. Wykorzystuje komponent React do renderowania pustego elementu SVG, który działa jako główny element naszej wizualizacji danych. Następnie używa metody cyklu życia componentDidUpdate
, aby, używając tego elementu głównego, utworzyć wykres przy użyciu kodu D3.js, którego użylibyśmy w waniliowym scenariuszu JavaScript. Moglibyśmy również zablokować wszelkie dalsze aktualizacje składników, ustawiając metodę shouldComponentUpdate
, aby zawsze zwracała false
.
class Line extends React.Component { static propTypes = {...} componentDidMount() { // D3 Code to create the chart // using this._rootNode as container } shouldComponentUpdate() { // Prevents component re-rendering return false; } _setRef(componentNode) { this._rootNode = componentNode; } render() { <div className="line-container" ref={this._setRef.bind(this)} /> } }
Oceniając to podejście, zdajemy sobie sprawę, że ma ono pewne zalety i wady. Wśród korzyści jest to proste rozwiązanie, które działa dobrze przez większość czasu. Jest to również najbardziej naturalne rozwiązanie, gdy przenosisz istniejący kod do Reacta lub używasz wykresów D3.js, które już działały gdzie indziej.
Z drugiej strony mieszanie kodu React i kodu D3.js w komponencie React może być postrzegane jako nieco obrzydliwe, zawierające zbyt wiele zależności i czyniąc ten plik zbyt długim, aby można go było uznać za kod wysokiej jakości. Ponadto ta implementacja w ogóle nie wydaje się idiomatyczna. Wreszcie, ponieważ serwer renderujący React nie wywołuje metody componentDidUpdate
, nie możemy wysłać renderowanej wersji wykresu w początkowym kodzie HTML.
Reaguj Faux DOM
Zaimplementowany przez Olivera Caldwella React Faux DOM „jest sposobem na wykorzystanie istniejących narzędzi D3, ale renderowanie go za pomocą React w etosie React”. Wykorzystuje fałszywą implementację DOM, aby nakłonić D3.js do myślenia, że ma do czynienia z prawdziwym DOM. W ten sposób zachowujemy drzewo React DOM podczas używania D3.js w — prawie — całym jego potencjale.
import {withFauxDOM} from 'react-faux-dom' class Line extends React.Component { static propTypes = {...} componentDidMount() { const faux = this.props.connectFauxDOM('div', 'chart'); // D3 Code to create the chart // using faux as container d3.select(faux) .append('svg') {...} } render() { <div className="line-container"> {this.props.chart} </div> } } export default withFauxDOM(Line);
Zaletą tego podejścia jest możliwość korzystania z większości interfejsów API D3.js, co ułatwia integrację z już zbudowanym kodem D3.js. Pozwala również na renderowanie po stronie serwera. Wadą tej strategii jest to, że jest ona mniej wydajna, ponieważ umieszczamy kolejną fałszywą implementację DOM przed wirtualnym DOM Reacta, dwukrotnie wirtualizując DOM. Ten problem ogranicza jego zastosowanie do małych i średnich wizualizacji danych.
Owijanie metod cyklu życia
Podejście to, po raz pierwszy przedstawione przez Nicolasa Hery'ego, wykorzystuje metody cyklu życia obecne w komponentach React opartych na klasach. Elegancko obejmuje tworzenie, aktualizację i usuwanie wykresów D3.js, ustanawiając ostrą granicę między kodem React i D3.js.
import D3Line from './D3Line' class Line extends React.Component { static propTypes = {...} componentDidMount() { // D3 Code to create the chart this._chart = D3Line.create( this._rootNode, this.props.data, this.props.config ); } componentDidUpdate() { // D3 Code to update the chart D3Line.update( this._rootNode, this.props.data, this.props.config, this._chart ); } componentWillUnmount() { D3Line.destroy(this._rootNode); } _setRef(componentNode) { this._rootNode = componentNode; } render() { <div className="line-container" ref={this._setRef.bind(this)} /> } }
D3Line to mniej więcej tak:
const D3Line = {}; D3Line.create = (el, data, configuration) => { // D3 Code to create the chart }; D3Line.update = (el, data, configuration, chart) => { // D3 Code to update the chart }; D3Line.destroy = () => { // Cleaning code here }; export default D3Line;
Kodowanie w ten sposób tworzy lekki komponent React, który komunikuje się z instancją wykresu opartą na D3.js za pośrednictwem prostego API (tworzenie, aktualizowanie i usuwanie), przesuwając w dół wszystkie metody wywołań zwrotnych, które chcemy nasłuchiwać.

Ta strategia promuje wyraźne oddzielenie obaw, wykorzystując fasadę do ukrycia szczegółów implementacji wykresu. Może zawierać dowolny wykres, a wygenerowany interfejs jest prosty. Kolejną korzyścią jest łatwość integracji z dowolnym już napisanym kodem D3.js i pozwala nam korzystać z doskonałych przejść D3.js. Główną wadą tej metody jest to, że renderowanie po stronie serwera nie jest możliwe.
Reaguj na DOM, D3 na Math
W tej strategii ograniczamy użycie D3.js do minimum. Oznacza to wykonywanie obliczeń dla ścieżek SVG, skal, układów i wszelkich przekształceń, które pobierają dane użytkownika i przekształcają je w coś, co możemy narysować za pomocą Reacta.
Używanie D3.js tylko do matematyki jest możliwe dzięki dużej liczbie podmodułów D3.js, które nie są powiązane z DOM. Ta ścieżka jest najbardziej przyjazna dla React, dająca bibliotece Facebooka pełną władzę nad DOM, co robi bardzo dobrze.
Zobaczmy uproszczony przykład:
class Line extends React.Component { static propTypes = {...} drawLine() { let xScale = d3.scaleTime() .domain(d3.extent(this.props.data, ({date}) => date)); .rangeRound([0, this.props.width]); let yScale = d3.scaleLinear() .domain(d3.extent(this.props.data, ({value}) => value)) .rangeRound([this.props.height, 0]); let line = d3.line() .x((d) => xScale(d.date)) .y((d) => yScale(d.value)); return ( <path className="line" d={line(this.props.data)} /> ); } render() { <svg className="line-container" width={this.props.width} height={this.props.height} > {this.drawLine()} </svg> } }
Ta technika jest ulubiona przez doświadczonych programistów React, ponieważ jest spójna ze sposobem React. Ponadto, po jego wdrożeniu, budowanie wykresów z jego kodem jest świetne. Kolejną korzyścią byłoby renderowanie po stronie serwera i ewentualnie React Native lub React VR.
Paradoksalnie jest to podejście, które wymaga większej wiedzy na temat działania D3.js, ponieważ musimy zintegrować się z jego podmodułami na niskim poziomie. Musimy ponownie zaimplementować niektóre funkcje D3.js — osie i kształty są bardziej powszechne; pędzle, powiększanie i przeciąganie prawdopodobnie najtrudniejsze — a to oznacza znaczną ilość pracy z góry.
Musielibyśmy również zaimplementować wszystkie animacje. W ekosystemie React mamy świetne narzędzia, które pozwalają nam zarządzać animacjami — patrz reakcja-przejścia-grupa, reakcja-ruch i reakcja-ruch — chociaż żadne z nich nie umożliwia nam tworzenia złożonych interpolacji ścieżek SVG. Jedno z nierozstrzygniętych pytań dotyczyłoby tego, w jaki sposób można wykorzystać to podejście do renderowania wykresów przy użyciu elementu canvas HTML5.
Na poniższym diagramie możemy zobaczyć wszystkie opisane podejścia zgodnie z poziomem integracji zarówno z Reactem, jak i D3.js:

Biblioteki React-D3.js
Przeprowadziłem pewne badania nad bibliotekami D3.js-React, które, mam nadzieję, pomogą ci, gdy staniesz przed decyzją wyboru biblioteki do pracy, współtworzenia lub rozwidlenia. Zawiera pewne subiektywne metryki, więc proszę, traktuj go z przymrużeniem oka.
Badania te wykazały, że chociaż bibliotek jest wiele, niewiele z nich jest utrzymywanych. Jako opiekun sam rozumiem, jak trudno jest nadążyć za zmianami w jednej dużej bibliotece i jak dbanie o dwie byłoby zniechęcającym zadaniem.
Ponadto liczba bibliotek gotowych do produkcji (od wersji 1.0.0 wzwyż) jest nadal dość niska. Prawdopodobnie ma to związek z ilością pracy niezbędnej do wysłania biblioteki tego typu.
Zobaczmy niektóre z moich ulubionych.
Zwycięstwo
Victory, projekt firmy konsultingowej Formidable Labs, to niskopoziomowa biblioteka elementów wykresów. Dzięki tej niskopoziomowej charakterystyce, komponenty Victory mogą być łączone w różne konfiguracje w celu tworzenia złożonych wizualizacji danych. Pod maską ponownie implementuje funkcje D3.js, takie jak pędzel i zoom, chociaż używa interpolacji d3 do animacji.

Użycie go na wykresie liniowym wyglądałoby tak:
class LineChart extends React.Component { render() { return ( <VictoryChart height={400} width={400} containerComponent={<VictoryVoronoiContainer/>} > <VictoryGroup labels={(d) => `y: ${dy}`} labelComponent={ <VictoryTooltip style={{ fontSize: 10 }} /> } data={data} > <VictoryLine/> <VictoryScatter size={(d, a) => {return a ? 8 : 3;}} /> </VictoryGroup> </VictoryChart> ); } }
Daje to taki wykres liniowy:

Rozpoczęcie korzystania ze Zwycięstwa jest łatwe i ma kilka fajnych bonusów, takich jak powiększenie i kontener Voronoi z podpowiedziami. Jest to modna biblioteka, chociaż wciąż jest w stanie przedpremierowym i zawiera wiele oczekujących na zwłokę błędów. Victory to obecnie jedyna biblioteka, z której możesz korzystać z React Native.
Recharts
Estetycznie dopracowany, z przyjemnym doświadczeniem użytkownika, płynnymi animacjami i świetnie wyglądającą podpowiedź, Recharts jest jedną z moich ulubionych bibliotek React-D3.js. Recharts korzysta tylko ze skali d3, interpolacji d3 i kształtu d3. Oferuje wyższy poziom szczegółowości niż Victory, ograniczając ilość wizualizacji danych, które możemy skomponować.

Korzystanie z Recharts wygląda tak:
class LineChart extends React.Component { render () { return ( <LineChart width={600} height={300} data={data} margin={{top: 5, right: 30, left: 20, bottom: 5}} > <XAxis dataKey="name"/> <YAxis/> <CartesianGrid strokeDasharray="3 3"/> <Tooltip/> <Legend /> <Line type="monotone" dataKey="pv" stroke="#8884d8" activeDot={{r: 8}}/> <Line type="monotone" dataKey="uv" stroke="#82ca9d" /> </LineChart> ); } }

Ta biblioteka jest również bardzo dobrze przetestowana i chociaż wciąż jest w fazie beta, zawiera niektóre ze zwykłych wykresów, wykres radarowy, mapy drzew, a nawet pędzle. Możesz sprawdzić jego przykłady, aby zobaczyć więcej. Deweloperzy biorący udział w tym projekcie włożyli w to dużo pracy, osiągając płynne animacje dzięki swojemu projektowi animacji reaguje-smooth.
Nivo
Nivo to wysokopoziomowa biblioteka wykresów React-D3.js. Oferuje wiele opcji renderowania: SVG, płótno, a nawet opartą na API wersję HTML wykresów, która jest idealna do renderowania po stronie serwera. Wykorzystuje React Motion do animacji.

Jego API jest nieco inne, ponieważ ujawnia tylko jeden konfigurowalny komponent dla każdego wykresu. Zobaczmy przykład:
class LineChart extends React.Component { render () { return ( <ResponsiveLine data={data} margin={{ "top": 50, "right": 110, "bottom": 50, "left": 60 }} minY="auto" stacked={true} axisBottom={{ "orient": "bottom", "tickSize": 5, "tickPadding": 5, "tickRotation": 0, "legend": "country code", "legendOffset": 36, "legendPosition": "center" }} axisLeft={{ "orient": "left", "tickSize": 5, "tickPadding": 5, "tickRotation": 0, "legend": "count", "legendOffset": -40, "legendPosition": "center" }} dotSize={10} dotColor="inherit:darker(0.3)" dotBorderWidth={2} dotBorderColor="#ffffff" enableDotLabel={true} dotLabel="y" dotLabelYOffset={-12} animate={true} motionStiffness={90} motionDamping={15} legends={[ { "anchor": "bottom-right", "direction": "column", "translateX": 100, "itemWidth": 80, "itemHeight": 20, "symbolSize": 12, "symbolShape": "circle" } ]} /> ); } }

Raphael Benitte wykonał z Nivo niesamowitą robotę. Dokumentacja jest piękna, a jej dema można konfigurować. Ze względu na wyższy poziom abstrakcji tej biblioteki jest bardzo prosta w użyciu i można powiedzieć, że oferuje mniejsze możliwości tworzenia wizualizacji. Przyjemną funkcją Nivo jest możliwość używania wzorów i gradientów SVG do wypełniania wykresów.
VX
VX to zbiór niskopoziomowych komponentów wizualizacyjnych do tworzenia wizualizacji. Jest nieoceniony i ma być używany do tworzenia innych bibliotek wykresów lub taki, jaki jest.

Zobaczmy kod:
class VXLineChart extends React.Component { render () { let {width, height, margin} = this.props; // bounds const xMax = width - margin.left - margin.right; const yMax = height - margin.top - margin.bottom; // scales const xScale = scaleTime({ range: [0, xMax], domain: extent(data, x), }); const yScale = scaleLinear({ range: [yMax, 0], domain: [0, max(data, y)], nice: true, }); return ( <svg width={width} height={height} > <rect x={0} y={0} width={width} height={height} fill="white" rx={14} /> <Group top={margin.top}> <LinePath data={data} xScale={xScale} yScale={yScale} x={x} y={y} stroke='#32deaa' strokeWidth={2} /> </Group> </svg> ); } };

Biorąc pod uwagę ten niski poziom szczegółowości, myślę o VX jako o D3.js dla świata React. Jest niezależny od biblioteki animacji, z której użytkownik chce korzystać. Obecnie wciąż znajduje się we wczesnej fazie beta, chociaż jest używany w produkcji przez Airbnb. Jej deficyty w tej chwili to brak wsparcia dla interakcji, takich jak szczotkowanie i powiększanie.
Reaguj na Britechart
Britecharts React jest wciąż w fazie beta i jest jedyną z tych bibliotek, która korzysta z metody zawijania metod cyklu życia. Ma on na celu umożliwienie korzystania z wizualizacji Britecharts w React poprzez stworzenie łatwego w użyciu opakowania kodu.

Oto prosty kod dla wykresu liniowego:
class LineChart extends React.Component { render () { const margin = { top: 60, right: 30, bottom: 60, left: 70, }; return ( <TooltipComponent data={lineData.oneSet()} topicLabel="topics" title="Tooltip Title" render={(props) => ( <LineComponent margin={margin} lineCurve="basis" {...props} /> )} /> ); } }

Nie mogę być obiektywny w tej sprawie. Britecharts React może służyć jako szkielet do renderowania wykresów D3.js jako komponentów React. Nie obsługuje renderowania po stronie serwera, chociaż uwzględniliśmy stany ładowania, aby w jakiś sposób temu zaradzić.
Zapraszam do sprawdzenia wersji demonstracyjnych online i zabawy z kodem.
Wybór podejścia lub biblioteki
Rozważania dotyczące budowania aplikacji z wykresami pogrupowałem w cztery kategorie: jakość, czas, zakres i koszt. Jest ich za dużo, więc powinniśmy uprościć.
Powiedzmy, że naprawiamy jakość . Moglibyśmy dążyć do tego, aby baza kodu była dobrze przetestowana, zaktualizowana do D3.js w wersji 4 i z obszerną dokumentacją.
Jeśli myślimy o czasie , przydatnym pytaniem, które warto sobie zadać, jest: „Czy to inwestycja długoterminowa?” Jeśli odpowiedź brzmi „tak”, to radziłbym stworzyć bibliotekę opartą na D3.js i owinąć ją Reactem, stosując podejście metod cyklu życia. Takie podejście dzieli nasz kod według technologii i jest bardziej odporne na czas.
Jeśli wręcz przeciwnie, projekt ma napięte terminy i zespół nie musi go długo utrzymywać, radziłbym wziąć bibliotekę React-D3.js lub D3.js najbliższą specyfikacjom, rozwidlić ją i użyć , starając się wnieść swój wkład po drodze.
Kiedy mamy do czynienia z zakresem , powinniśmy zastanowić się, czy potrzebujemy niewielkiej liczby podstawowych wykresów, jednorazowej złożonej wizualizacji, czy kilku wysoce spersonalizowanych grafik. W pierwszym przypadku ponownie wybrałbym bibliotekę najbardziej zbliżoną do specyfikacji i rozwidliłbym ją. W przypadku szytych na miarę wizualizacji danych, które zawierają wiele animacji lub interakcji, najlepszym rozwiązaniem jest budowanie za pomocą zwykłego pliku D3.js. Wreszcie, jeśli planujesz używać różnych wykresów o określonych specyfikacjach — być może przy wsparciu UX'ów i projektantów — wtedy najlepiej będzie stworzyć swoją bibliotekę D3 od zera lub rozwidleć i dostosować istniejącą bibliotekę.
Wreszcie strona kosztowa decyzji związana jest z budżetem i szkoleniem zespołu. Jakie umiejętności posiada Twój zespół? Jeśli masz programistów D3.js, woleliby oni wyraźnie oddzielić D3.js od React, więc prawdopodobnie podejście wykorzystujące zawijanie metod cyklu życia będzie działać świetnie. Jeśli jednak Twój zespół składa się głównie z programistów Reacta, z przyjemnością poszerzy którąkolwiek z obecnych bibliotek React-D3.js. Również użycie metod cyklu życia wraz z przykładami D3.js może działać. To, co rzadko polecam, to rozwijanie własnej biblioteki React-D3.js. Ilość pracy niezbędnej na początku jest zniechęcająca, a tempo aktualizacji obu bibliotek sprawia, że koszty utrzymania nie są trywialne.
Streszczenie
React i D3.js to świetne narzędzia, które pomagają nam radzić sobie z DOM i związanymi z nim wyzwaniami. Z pewnością mogą ze sobą współpracować, a my możemy wybrać, gdzie postawić granicę między nimi. Istnieje zdrowy ekosystem bibliotek, który pomaga nam korzystać z D3.js. React-D3.js ma również wiele ekscytujących opcji, a obie biblioteki są w ciągłej ewolucji, więc projekty łączące obie będą miały trudności z nadążaniem za nimi.
Wybór będzie zależał od tak wielu zmiennych, których nie da się opisać w jednym artykule. Jednak omówiliśmy większość głównych kwestii, miejmy nadzieję, że umożliwimy Ci podjęcie świadomej decyzji.
Z tym podkładem zachęcam do ciekawości, sprawdzenia wspomnianych bibliotek i dodania wykresu dobroci do swoich projektów.
Czy korzystałeś z któregoś z tych projektów? Jeśli tak, jakie było Twoje doświadczenie? Podziel się z nami kilkoma słowami w komentarzach.