Jak používat Google Charts v Reactu

Tento článek byl původně publikován na mém osobním blogu

Google Charts je bezplatná Javascriptová knihovna, která vám umožňuje vizualizovat data v mnoha typech tabulek a grafů. Je to velmi užitečné a snadno použitelné ve vašich projektech.

V tomto tutoriálu se podíváme, jak používat Google Charts v React vytvořením jednoduché aplikace React pomocí Create React App (CRA). Naučíme se, jak používat Google Charts s háčky nebo kontextem pro různé případy použití.

Kód tohoto výukového programu můžete zkontrolovat v tomto úložišti GitHub.

Vytvořit aplikaci React

Začneme vytvořením aplikace React. Spusťte následující příkaz:

npx create-react-app react-google-charts

Po dokončení příkazu vytvoříme web pro reakce pomocí CRA.

Nainstalujeme také response-bootstrap, abychom mohli používat některé užitečné komponenty Bootstrap:

npm install react-bootstrap@next [email protected]

Použití Google Charts with Hooks

První přístup, který zkontrolujeme, je použití Google Charts v React with Hooks. Kód pro tuto část výukového programu v úložišti GitHub je pod src/WithHooks .

Vytvoření háku

Vytvořte soubor src/useGoogleCharts.js s následujícím obsahem:

import { useEffect, useState } from "react";

function useGoogleCharts () {
  const [google, setGoogle] = useState(null);

    useEffect(() => {
        if (!google) {
            //TODO load google charts
        }
   }, [google]);

  return google;
}

export default useGoogleCharts;

Tím se vytvoří nový háček, který má stav google . Tento stav nám umožňuje zkontrolovat, zda je Google Charts načten nebo ne, a bude obsahovat načtené window.google objekt. Potom použijeme useEffect k načtení grafů, když nejsou načteny. Nakonec jen vrátíme google .

Abychom mohli načíst Google Charts, musíme načíst skript https://www.gstatic.com/charts/loader.js v <head> dokumentu a po jeho načtení načteme základní balíček grafů Google. Nakonec po načtení základního balíčku nastavíme google na window.google .

Přidejte následující kód do if stav:

const head = document.head;
let script = document.getElementById('googleChartsScript');
if (!script) {
    script = document.createElement('script');
    script.src = 'https://www.gstatic.com/charts/loader.js';
    script.id = 'googleChartsScript';
    script.onload = () => {
        if (window.google && window.google.charts) {
            window.google.charts.load('current', {'packages':['corechart']});

            window.google.charts.setOnLoadCallback(() => setGoogle(window.google))
        }
    };
    head.appendChild(script);
} else if (window.google && window.google.charts && window.google.visualization) {
    setGoogle(window.google);
}

Nejprve zkontrolujeme, zda je skript již načten, abychom se vyhnuli jeho opětovnému načítání.

Pokud skript není načten, vytváříme script a přidáváme posluchač události pro onload který načte balíčky kódů Google Charts.

Poté, když jsou balíčky načteny, můžeme nastavit google s setGoogle(window.google) .

V případě, že skript již byl načten, zkontrolujeme, zda window.google je nastaveno a poté nastavte google .

Nakonec se vrátíme v useEffect následující funkce:

return () => {
      let script = document.getElementById('googleChartsScript');
      if (script) {
        script.remove();
      }
    }

Toto odebere skript při odpojení.

Vytvoření komponenty grafu

Dále vytvoříme komponentu grafu, která vykreslí graf po načtení knihovny Google Chart.

Vytvořte komponentu src/PizzaChart.js s následujícím obsahem:

import { useEffect, useState } from "react";
import { Spinner } from "react-bootstrap";

function PizzaChart ({google}) {
  const [chart, setChart] = useState(null);

  useEffect(() => {
    if (google && !chart) {
        //TODO draw the chart
    }
  }, [loaded, chart]);

  return (
    <>
      {!google && <Spinner />}
      <div id="pizzaChart" className={!google ? 'd-none' : ''} />
    </>
  )
}

export default PizzaChart;

Tato komponenta obdrží google prop, což bude vrácená hodnota z useGoogleCharts . Má chart stavu, abyste zajistili, že graf bude vytvořen pouze jednou.

Uvnitř useEffect , zkontrolujeme, zda google není null a pokud chart je nulový. V tom případě nakreslíme graf.

Nakonec pouze ukazujeme číselník google je null a vytváříme div prvek, do kterého graf přejde.

Zpět na podmínku if v useEffect , musíme přidat kód pro kreslení grafu. Přidáme kód z příkladu koláčového grafu Google Charts:

// Create the data table.
const data = new google.visualization.DataTable();
data.addColumn('string', 'Topping');
data.addColumn('number', 'Slices');
data.addRows([
    ['Mushrooms', 3],
    ['Onions', 1],
    ['Olives', 1],
    ['Zucchini', 1],
    ['Pepperoni', 2]
]);

// Set chart options
var options = {'title':'How Much Pizza I Ate Last Night',
               'width':400,
               'height':300};

// Instantiate and draw our chart, passing in some options.
const newChart = new google.visualization.PieChart(document.getElementById('pizzaChart'));
newChart.draw(data, options);

setChart(newChart);

Nejprve shromažďujeme data s možnostmi a poté používáme google.visualization nakreslit koláčový graf. Nakonec nastavíme chart stavu.

Uvnitř src/App.js , nahraďte obsah následujícím:

import { Container } from "react-bootstrap";
import PizzaChart from "./PizzaChart";
import useGoogleCharts from './useGoogleCharts';

function App() {
  const google = useGoogleCharts();

  return (
    <>
      <Container className="mt-3">
        <h1>With Hooks</h1>
        <PizzaChart google={google} />
      </Container>
    </>
  );
}

export default App;

Zkuste server spustit nyní, pokud neběží. Zobrazí se výsečový graf.

Více grafů

Zkusme přidat další graf. Vytvoříme novou komponentu grafu src/DinosaurChart s následujícím obsahem:

import { useEffect, useState } from "react";
import { Spinner } from "react-bootstrap";

function DinosaurChart ({google}) {
  const [chart, setChart] = useState(null);

  useEffect(() => {
    if (google && !chart) {
      const data = google.visualization.arrayToDataTable([
        ['Dinosaur', 'Length'],
        ['Acrocanthosaurus (top-spined lizard)', 12.2],
        ['Albertosaurus (Alberta lizard)', 9.1],
        ['Allosaurus (other lizard)', 12.2],
        ['Apatosaurus (deceptive lizard)', 22.9],
        ['Archaeopteryx (ancient wing)', 0.9],
        ['Argentinosaurus (Argentina lizard)', 36.6],
        ['Baryonyx (heavy claws)', 9.1],
        ['Brachiosaurus (arm lizard)', 30.5],
        ['Ceratosaurus (horned lizard)', 6.1],
        ['Coelophysis (hollow form)', 2.7],
        ['Compsognathus (elegant jaw)', 0.9],
        ['Deinonychus (terrible claw)', 2.7],
        ['Diplodocus (double beam)', 27.1],
        ['Dromicelomimus (emu mimic)', 3.4],
        ['Gallimimus (fowl mimic)', 5.5],
        ['Mamenchisaurus (Mamenchi lizard)', 21.0],
        ['Megalosaurus (big lizard)', 7.9],
        ['Microvenator (small hunter)', 1.2],
        ['Ornithomimus (bird mimic)', 4.6],
        ['Oviraptor (egg robber)', 1.5],
        ['Plateosaurus (flat lizard)', 7.9],
        ['Sauronithoides (narrow-clawed lizard)', 2.0],
        ['Seismosaurus (tremor lizard)', 45.7],
        ['Spinosaurus (spiny lizard)', 12.2],
        ['Supersaurus (super lizard)', 30.5],
        ['Tyrannosaurus (tyrant lizard)', 15.2],
        ['Ultrasaurus (ultra lizard)', 30.5],
        ['Velociraptor (swift robber)', 1.8]]);

      var options = {
        title: 'Lengths of dinosaurs, in meters',
        legend: { position: 'none' },
      };

      // Instantiate and draw our chart, passing in some options.
      const newChart = new google.visualization.Histogram(document.getElementById('dinosaurChart'));
      newChart.draw(data, options);

      setChart(newChart);
    }
  }, [google, chart]);

  return (
    <>
      {!google && <Spinner />}
      <div id="dinosaurChart" className={!google ? 'd-none' : ''} />
    </>
  )
}

export default DinosaurChart;

Tato komponenta grafu je přesně podobná PizzaChart , kromě toho, že kreslí spíše histogram než koláčový graf. Kód pro data je převzat z příkladu histogramu Google Charts.

Nyní přidejte novou komponentu za PizzaChart v src/App.js ve vráceném JSX:

<PizzaChart google={google} />
<DinosaurChart google={google} />

Pokud stránku otevřete nyní, uvidíte dva grafy.

Použití Google Charts s kontextem

Můžete také použít Google Charts s React Contexts. To vám umožní používat google objekt v jakékoli komponentě, aniž byste museli volat hák v jedné komponentě a předat google objekt jako podpěra ke komponentám grafu.

Kód pro tuto sekci se nachází v úložišti GitHub v adresáři src/WithContext .

Vytvořte kontext Google

Nejprve vytvořte src/GoogleContext.js s následujícím obsahem:

import React from "react";

export default React.createContext({
  google: null,
  setGoogle: () => {}
});

Tím se vytvoří kontext Google s google objekt, zpočátku null, a nastavovací funkce setGoogle .

Použít poskytovatele kontextu

Uvnitř src/App.js , změňte obsah na následující:

import { useEffect, useState } from "react";
import { Container } from "react-bootstrap";
import GoogleContext from "./GoogleContext";

function App() {
  const [google, setGoogle] = useState(null);

  useEffect(() => {
    if (!google) {
      const head = document.head;
      let script = document.getElementById('googleChartsScript');
      if (!script) {
        script = document.createElement('script');
        script.src = 'https://www.gstatic.com/charts/loader.js';
        script.id = 'googleChartsScript';
        script.onload = () => {
          if (window.google && window.google.charts) {
            window.google.charts.load('current', {'packages':['corechart']});

            window.google.charts.setOnLoadCallback(() => setGoogle(window.google))
          }
        };
        head.appendChild(script);
      } else if (window.google) {
        setGoogle(window.google);
      }
    }

    return () => {
      let script = document.getElementById('googleChartsScript');
      if (script) {
        script.remove();
      }
    }
  }, [google]);

  return (
    <GoogleContext.Provider value={{google, setGoogle}}>
      <Container className="mt-3">
        <h1>With Context</h1>
      </Container>
    </GoogleContext.Provider>
  );
}

export default App;

Zde vytváříme google Stát. Poté v useEffect spouštíme stejný kód, jaký jsme dělali dříve v useGoogleChart . Načítáme skript a poté nastavujeme google stav, kdy je načten.

Nakonec obklopíme vykreslené komponenty poskytovatelem kontextu a jako hodnotu mu předáme stav a jeho nastavovač.

Vytvořit komponentu grafu

Dále vytvoříme komponentu grafu src/PizzaChart.js s následujícím obsahem:

import { useContext, useEffect, useState } from "react";
import { Spinner } from "react-bootstrap";
import GoogleContext from "./GoogleContext";

function PizzaChart () {
  const [chart, setChart] = useState(null);
  const { google } = useContext(GoogleContext);

  useEffect(() => {
    if (google && !chart) {
      // Create the data table.
      var data = new window.google.visualization.DataTable();
      data.addColumn('string', 'Topping');
      data.addColumn('number', 'Slices');
      data.addRows([
        ['Mushrooms', 3],
        ['Onions', 1],
        ['Olives', 1],
        ['Zucchini', 1],
        ['Pepperoni', 2]
      ]);

      // Set chart options
      var options = {'title':'How Much Pizza I Ate Last Night',
                    'width':400,
                    'height':300};

      // Instantiate and draw our chart, passing in some options.
      const newChart = new window.google.visualization.PieChart(document.getElementById('pizzaChart'));
      newChart.draw(data, options);

      setChart(newChart);
    }
  }, [google, chart]);

  return (
    <>
      {!google && <Spinner />}
      <div id="pizzaChart" className={!google ? 'd-none' : ''} />
    </>
  )
}

export default PizzaChart;

Tato komponenta grafu je podobná předchozí komponentě grafu, kterou jsme vytvořili v předchozí části.

Nejprve vytvoříme stav chart vykreslit graf pouze jednou. Potom načteme kontext pomocí useContext . Poté kreslíme graf uvnitř useEffect . Nakonec vykreslíme spinner, pokud není načten google, a div prvek, do kterého bude graf vykreslen.

Nyní přidejte komponentu do vráceného JSX v src/App.js :

<GoogleContext.Provider value={{google, setGoogle}}>
      <Container className="mt-3">
        <h1>With Context</h1>
        <PizzaChart />
      </Container>
    </GoogleContext.Provider>

Pokud nyní otevřete webovou stránku, uvidíte stejnou tabulku pizzy, kterou jsme viděli při použití háčků.

Více grafů

Vytvoříme další komponentu grafu src/DinosaurChart.js s následujícím obsahem:

import { useContext, useEffect, useState } from "react";
import { Spinner } from "react-bootstrap";
import GoogleContext from "./GoogleContext";

function DinosaurChart () {
  const [chart, setChart] = useState(null);
  const { google } = useContext(GoogleContext);

  useEffect(() => {
    if (google && !chart) {
      const data = google.visualization.arrayToDataTable([
        ['Dinosaur', 'Length'],
        ['Acrocanthosaurus (top-spined lizard)', 12.2],
        ['Albertosaurus (Alberta lizard)', 9.1],
        ['Allosaurus (other lizard)', 12.2],
        ['Apatosaurus (deceptive lizard)', 22.9],
        ['Archaeopteryx (ancient wing)', 0.9],
        ['Argentinosaurus (Argentina lizard)', 36.6],
        ['Baryonyx (heavy claws)', 9.1],
        ['Brachiosaurus (arm lizard)', 30.5],
        ['Ceratosaurus (horned lizard)', 6.1],
        ['Coelophysis (hollow form)', 2.7],
        ['Compsognathus (elegant jaw)', 0.9],
        ['Deinonychus (terrible claw)', 2.7],
        ['Diplodocus (double beam)', 27.1],
        ['Dromicelomimus (emu mimic)', 3.4],
        ['Gallimimus (fowl mimic)', 5.5],
        ['Mamenchisaurus (Mamenchi lizard)', 21.0],
        ['Megalosaurus (big lizard)', 7.9],
        ['Microvenator (small hunter)', 1.2],
        ['Ornithomimus (bird mimic)', 4.6],
        ['Oviraptor (egg robber)', 1.5],
        ['Plateosaurus (flat lizard)', 7.9],
        ['Sauronithoides (narrow-clawed lizard)', 2.0],
        ['Seismosaurus (tremor lizard)', 45.7],
        ['Spinosaurus (spiny lizard)', 12.2],
        ['Supersaurus (super lizard)', 30.5],
        ['Tyrannosaurus (tyrant lizard)', 15.2],
        ['Ultrasaurus (ultra lizard)', 30.5],
        ['Velociraptor (swift robber)', 1.8]]);

      var options = {
        title: 'Lengths of dinosaurs, in meters',
        legend: { position: 'none' },
      };

      const newChart = new google.visualization.Histogram(document.getElementById('dinosaurChart'));
      newChart.draw(data, options);

      setChart(newChart);
    }
  }, [google, chart]);

  return (
    <>
      {!google && <Spinner />}
      <div id="dinosaurChart" className={!google ? 'd-none' : ''} />
    </>
  )
}

export default DinosaurChart;

Kód je velmi podobný PizzaChart ale vykreslovaná data jsou odlišná a místo PieChartu se vykresluje histogram.

Nakonec musíme přidat DinosaurChart komponentu ve vráceném JSX v src/App.js :

return (
    <GoogleContext.Provider value={{google, setGoogle}}>
      <Container className="mt-3">
        <h1>With Context</h1>
        <PizzaChart />
        <DinosaurChart />
      </Container>
    </GoogleContext.Provider>
  );

Pokud nyní otevřete webovou stránku, uvidíte 2 grafy.

Měli byste použít kontext nebo háčky?

Přístup, který použijete, závisí na vašem případu použití. Pokud používáte jeden nebo více grafů uvnitř stejné komponenty, i když jako podřízené komponenty, může hákový přístup fungovat dobře.

Pokud však používáte více grafů rozložených v různých komponentách, nejlepším přístupem by bylo použít kontext.

Závěr

V tomto tutoriálu jsme se naučili používat Google Charts s Reactem. Implementaci lze v případě potřeby rozšířit na základě vašeho případu použití, protože Google Charts má mnoho případů použití a balíčků jiných než základní balíčky.

Nezapomeňte se také podívat do dokumentace Google Chart, kde najdete další informace.