Utiliser des composants de visualisation pour créer une visualisation personnalisée

Ce tutoriel est destiné aux développeurs JavaScript expérimentés et suppose une certaine connaissance des techniques de programmation fonctionnelle.

Dans cet exemple, nous commençons avec une requête liée aux informations sur les ventes trimestrielles hypothétiques de certaines marques. Nous allons d'abord filtrer la requête par marques spécifiques, puis faire pivoter les résultats par trimestre de vente. Consultez le tableau suivant pour obtenir un exemple.

Résultats d'une requête pour le nombre de commandes par marque, avec un tableau croisé dynamique sur la dimension Trimestre des commandes créées.

Ensuite, nous utiliserons des composants de visualisation pour créer une visualisation personnalisée qui montre les tendances des produits de chaque marque au cours du dernier trimestre. Le résultat sera un nouveau type de visualisation composé d'une série de courbes sparkline imbriquées dans un tableau, qui ressemble à cet exemple:

Une visualisation personnalisée montrant un tableau avec une ligne pour chaque marque et une visualisation sparkline intégrée montrant les commandes par trimestre sur chaque ligne.

En plus de vous montrer comment créer une visualisation personnalisée, cet exemple présente quelques bonnes pratiques pour utiliser l'API Looker dans une application React.

Pour créer une visualisation personnalisée avec des composants Looker, assurez-vous que votre configuration respecte les exigences, puis procédez comme suit:

  1. Créer une requête dans une exploration et copier la valeur qid
  2. Transmettre les données à un composant de visualisation personnalisé
  3. Créer le composant CustomVis
  4. Transformer les données normalisées
  5. Insérer les données transformées dans CustomVis
  6. Générer la visualisation personnalisée

L'utilisation de composants de visualisation pour créer une visualisation personnalisée est appropriée lorsque celle-ci est destinée à une application ou une extension intégrée. Si vous souhaitez que la visualisation personnalisée soit accessible aux utilisateurs de Looker sur une instance Looker, suivez les instructions de la page de documentation de visualization. Si vous souhaitez développer une visualisation personnalisée et l'importer dans le Marketplace Looker, suivez les instructions de la page de documentation Développer une visualisation personnalisée pour la Marketplace Looker.

Conditions requises

Avant de commencer, quelques éléments sont nécessaires:

  • Vous devez avoir accès à une instance Looker.
  • Que vous conceviez dans le framework d'extension ou dans votre propre application React autonome, il est important de vous authentifier avec l'API de Looker et d'avoir accès à l'objet SDK Looker. Pour en savoir plus, consultez les articles sur l'authentification de l'API Looker ou sur notre framework d'extension.
  • Assurez-vous d'avoir installé le package NPM des composants de visualisation Looker et le package NPM @looker/components-data. Pour en savoir plus sur l'installation et l'utilisation du package de composants de visualisation, consultez le document README, disponible sur GitHub et NPM.

Étape 1: Créez une requête dans une exploration et copiez l'ID de la requête

Dans cet exemple, nous utilisons les informations de ventes trimestrielles hypothétiques des marques dont nous effectuons le suivi au fil du temps.

Nous allons pivoter ces données, car cette méthode est intégrée à Looker pour regrouper les résultats des requêtes. Dans une exploration, nous pouvons exécuter une requête et créer un graphique des données à l'aide de l'un des types de visualisation natifs de Looker. Le graphique fournit beaucoup d'informations, mais il est difficile d'analyser en un coup d'œil les tendances des produits de chaque marque:

Graphique résultant d'une requête pour le nombre de commandes par marque, avec un tableau croisé dynamique sur la dimension Trimestre des ordres créés.

Comme dans l'exemple du rendu d'une visualisation simple, l'étape suivante consiste à copier la valeur qid de la barre d'adresse de l'exploration. Pour les besoins de cet exemple, la valeur qid sera Uijcav7pCA4MZY2MompsPZ, mais cette valeur est spécifique à notre instance de test. Votre valeur sera différente.

Étape 2: Transmettre les données à un composant de visualisation personnalisé

Pour commencer, transmettez la valeur qid issue de l'URL de l'exploration au composant Query et l'objet SDK authentifié à DataProvider.

import React, { useContext } from 'react'
import { ExtensionContext } from '@looker/extension-sdk-react'
import { DataProvider } from '@looker/components-data'
import { Query } from '@looker/visualizations'

export const MyReactApp = () => {
  const { core40SDK } = useContext(ExtensionContext)

  return (
    <DataProvider sdk={core40SDK}>
      <Query query='Uijcav7pCA4MZY2MompsPZ'></Query>
    </DataProvider>
  )
}

Ensuite, plutôt que d'afficher une visualisation Looker native via le composant Visualization, nous allons créer notre propre composant personnalisé appelé CustomVis.

Le composant Query peut accepter n'importe quel élément React en tant qu'enfant et transmet simplement les valeurs config, data, fields et totals en tant que propriétés pour afficher vos propres composants de visualisation. CustomVis sera affiché en tant qu'enfant de Query afin qu'il puisse recevoir toutes les données pertinentes en tant que propriétés.

import React, { useContext } from 'react'
import { ExtensionContext } from '@looker/extension-sdk-react'
import { DataProvider } from '@looker/components-data'
import { Query } from '@looker/visualizations'
import { CustomVis } from '../path/to/MyCustomVis'

export const MyReactApp = () => {
  const { core40SDK } = useContext(ExtensionContext)

  return (
    <DataProvider sdk={core40SDK}>
      <Query query='Uijcav7pCA4MZY2MompsPZ'>
        <CustomVis />
      </Query>
    </DataProvider>
  )
}

Étape 3: Créez le composant CustomVis

Créons maintenant le composant CustomVis. Les propriétés héritées du composant Query sont config, fields, data, pivots et totals:

  • config décrit toutes les façons dont les données doivent être affichées dans un graphique, telles que l'épaisseur de la ligne dans un graphique sparkline ou la taille et la forme des points d'un nuage de points.
  • fields stocke des métadonnées supplémentaires sur les valeurs de mesure et de dimension renvoyées par la requête, telles que la mise en forme des valeurs ou le libellé à attribuer à chaque axe.
  • data est la réponse clé/valeur renvoyée par la requête.
  • pivots décrit la dimension par laquelle la requête est pivotée.
  • totals fait référence aux totaux des lignes de Looker à utiliser dans les visualisations basées sur des tables.

Nous pouvons transmettre ces propriétés non modifiées à une visualisation de table en insérant un composant Table.

import React from 'react'
import { Table } from '@looker/visualizations'

export const CustomVis = ({ config, fields, data, pivots }) => {
  return <Table config={config} data={data} fields={fields} pivots={pivots} />
}

Cela nous donne une idée des données, car elles sont renvoyées directement par le SDK. Dans la réponse affichée, il y a une ligne pour chaque marque. Les résultats sont regroupés ou croisés par trimestre.

Étape 4: Transformer les données normalisées

Pour convertir ces données croisées et les afficher avec des graphiques sparkline imbriqués, nous isolons toutes les valeurs de mesure et les transmettons aux sous-graphiques. Dans le graphique suivant, les données pertinentes pour une seule ligne sont mises en évidence pour illustrer les données que nous allons réduire et afficher avec une visualisation enfant:

Graphique des résultats de données avec le nombre de commandes mis en surbrillance dans la deuxième ligne.

Pour cela, nous allons créer une transformation personnalisée. L'exemple suivant est spécifique à ce scénario. Vous devrez analyser vos propres données en conséquence.


import React from 'react'
import { Table, Sparkline } from '@looker/visualizations'

// we assign this value to a constant to ensure that fields and data
// objects remain in sync.
const NESTED_DATA_KEY = 'orderCount'

const nestSparklines = (data) => {
  return data.reduce((acc, d) => {
    // the first entry is the dimension (brand name), and the rest of the rows are the
    // quarterly sales information we want to pass to the Sparkline.
    const [parentDimension, ...measurePairs] = Object.entries(d)

    // `nonPivotedData` represents a single data row.
    // e.g. [{entry: 1, orderCount: 10}, {entry: 2, orderCount: 15}, ...etc]
    const nonPivotedData: SDKRecord[] = measurePairs.map(([_, value], i) => {
      return { entry: i, [NESTED_DATA_KEY]: value }
    })

    // now for each row in the table we render a Sparkline using the `nonPivotedData`
    // that we built.
    // E.G. [{products.brand: 'adidas', orderCount: <Sparkline />}]
    return [
      ...acc,
      {
        [parentDimension[0]]: parentDimension[1],
        [NESTED_DATA_KEY]: () => (
          <Sparkline
            height={75}
            data={nonPivotedData}
            fields={{
              measures: [{ name: NESTED_DATA_KEY }],
              dimensions: [],
            }}
          />
        ),
      },
    ]
  }, [])
}

Pour créer la fonction, procédez comme suit:

  1. Réduire l'ensemble de données pour isoler le nom de la marque des données de commande trimestrielles pour chaque ligne.
  2. Mettez à jour chaque ligne pour inclure la dimension et un composant React rendu, qui peut représenter les valeurs de chaque ligne du tableau.

Étape 5: Insérez les données transformées dans CustomVis

Maintenant, transformez les données à l'aide de notre nouvelle fonction et affectez la sortie à une nouvelle variable appelée nestedData:


export const CustomVis =({
  fields,
  data,
  config,
  pivots,
}) => {
  const nestedData = nestSparklines(data)

  return (
    <Table
      fields={{
        measures: [{ name: NESTED_DATA_KEY, label: 'Orders Count By Quarter' }],
        dimensions: fields.dimensions,
        pivots: [],
      }}
      config={config}
      data={nestedData}
      pivots={pivots}
    />
  )
}

Étape 6: Générer la visualisation personnalisée

Une fois que vous avez inséré les données transformées et configuré le graphique, la visualisation ressemblera à cet exemple de tableau avec des graphiques sparkline individuels pour chaque ligne:

Une visualisation personnalisée montrant un tableau avec une ligne pour chaque marque et une visualisation sparkline intégrée montrant les commandes par trimestre sur chaque ligne.

L'intégralité du code nécessaire pour afficher cette visualisation est la suivante:


import React, { useContext } from 'react'
import { ExtensionContext } from '@looker/extension-sdk-react'
import { DataProvider } from '@looker/components-data'
import { Query, Sparkline, Table } from '@looker/visualizations'

// we assign this value to a constant to ensure that fields and data
// objects remain in sync.
const NESTED_DATA_KEY = 'orderCount'
const ROW_HEIGHT = 75

const nestSparklines = data => {
  return data.reduce((acc, d) => {
    // the first entry is the dimension (brand name), and the rest of the rows are the
    // quarterly sales information we want to pass to the Sparkline.
    const [parentDimension, ...measurePairs] = Object.entries(d)

    // `nonPivotedData` represents a single data row.
    // e.g. [{entry: 1, orderCount: 10}, {entry: 2, orderCount: 15}, ...etc]
    const nonPivotedData = measurePairs.map(([_, value], i) => {
      return { entry: i, [NESTED_DATA_KEY]: value }
    })

    // now for each row in the table we render a Sparkline using the `nonPivotedData`
    // that we built.
    // E.G. [{products.brand: 'adidas', orderCount: <Sparkline />}]
    return [
      ...acc,
      {
        [parentDimension[0]]: parentDimension[1],
        [NESTED_DATA_KEY]: () => (
          <Sparkline
            height={ROW_HEIGHT}
            data={nonPivotedData}
            fields={{
              measures: [{ name: NESTED_DATA_KEY }],
              dimensions: [],
            }}
          />
        ),
      },
    ]
  }, [])
}

const CustomVis = ({ fields, data, pivots, config }) => {
  const nestedData = nestSparklines(data)

  return (
    <Table
      config={config}
      height={500}
      fields={{
        measures: [{ name: NESTED_DATA_KEY, label: 'Orders Count By Quarter' }],
        dimensions: fields.dimensions,
        pivots: [],
      }}
      data={nestedData}
      pivots={pivots}
      defaultRowHeight={ROW_HEIGHT}
    />
  )
}

export const MyReactApp = () => {
  const { core40SDK } = useContext(ExtensionContext)

  return (
    <DataProvider sdk={core40SDK}>
      <Query query='Uijcav7pCA4MZY2MompsPZ'>
        <CustomVis />
      </Query>
    </DataProvider>
  )
}

Étapes suivantes