Cómo usar componentes de visualización para crear una visualización personalizada

Este instructivo está dirigido a desarrolladores experimentados de JavaScript y supone cierta familiaridad con las técnicas de programación funcionales.

En este ejemplo, comenzamos con una consulta que se relaciona con información hipotética de ventas trimestrales de algunas marcas. Primero, filtraremos la búsqueda para marcas específicas y, luego, rotaremos los resultados por trimestre de ventas. Consulta la siguiente tabla para ver un ejemplo.

Resultados de una búsqueda de recuentos de pedidos por marca, con un giro en la dimensión Pedidos creados.

Luego, utilizaremos componentes de visualización para crear una visualización personalizada que muestre las tendencias de los productos de cada marca en el último trimestre. El resultado será un nuevo tipo de visualización compuesto por una serie de minigráficos anidados en una tabla, que se ve como en este ejemplo:

Una visualización personalizada que muestra una tabla con una fila para cada marca y una visualización de minigráfico incorporada que muestra los pedidos por trimestre en cada fila.

Además de mostrarte la forma de crear una visualización personalizada, en este ejemplo se muestran algunas prácticas recomendadas para trabajar con la API de Looker dentro de una aplicación de React.

Para crear una visualización personalizada con componentes de Looker, asegúrate de que la configuración cumpla con los requisitos y, luego, sigue estos pasos:

  1. Crea una consulta en Explorar y copia el valor qid
  2. Cómo pasar los datos a un componente de visualización personalizado
  3. Crea el componente CustomVis
  4. Transforme los datos normalizados
  5. Inserta los datos transformados en CustomVis
  6. Genere la visualización personalizada

El uso de componentes de visualización para compilar una visualización personalizada es apropiado cuando la visualización personalizada está destinada a una aplicación o extensión incorporada. Si deseas que la visualización personalizada esté disponible para los usuarios de Looker en una instancia de Looker, sigue las instrucciones de la página de documentación de visualization. Si quieres desarrollar una visualización personalizada y subirla a Looker Marketplace, sigue las instrucciones que se indican en la página de documentación Cómo desarrollar una visualización personalizada para Looker Marketplace.

Requisitos

Antes de comenzar, se necesitan algunos elementos:

  • Debes tener acceso a una instancia de Looker.
  • Ya sea que estés compilando en el framework de extensión o en tu propia aplicación de React independiente, es importante autenticarse con la API de Looker y tener acceso al objeto del SDK de Looker. Obtén más información sobre la autenticación de la API de Looker o sobre nuestro framework de extensión.
  • Asegúrate de haber instalado el paquete de NPM de los componentes de visualización de Looker y el paquete de NPM @looker/components-data. Puedes encontrar información sobre cómo instalar y usar el paquete de componentes de visualización en el documento README, disponible en GitHub y NPM.

Paso 1: Cree una consulta en Explorar y copie el ID de consulta

En este ejemplo, usamos información hipotética trimestral de ventas para las marcas de las que hacemos un seguimiento en el tiempo.

Pivotaremos estos datos, ya que este método es la forma integrada de Looker para agrupar los resultados de las consultas. En Explorar, podemos ejecutar una consulta y crear un gráfico de los datos mediante uno de los tipos de visualización nativa de Looker. El gráfico proporciona mucha información, pero es difícil analizar a simple vista las tendencias de los productos de cada marca:

Gráfico resultante de una consulta de recuentos de pedidos por marca, con un giro en la dimensión Pedidos creados.

Al igual que con el ejemplo de renderización de una visualización simple, el siguiente paso es copiar el valor qid de la barra de URL de Explorar. A los fines de este ejemplo, el valor de qid será Uijcav7pCA4MZY2MompsPZ, pero ese valor es específico de nuestra instancia de prueba. Tu valor diferirá.

Paso 2: Pasa los datos a un componente de visualización personalizado

Para comenzar, pasa el valor qid tomado de la URL de Explorar al componente Query y el objeto SDK autenticado a 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>
  )
}

A continuación, en lugar de renderizar una visualización nativa de Looker a través del componente Visualization, crearemos nuestro propio componente personalizado llamado CustomVis.

El componente Query puede aceptar cualquier elemento de React como elemento secundario y simplemente pasará los valores config, data, fields y totals como propiedades para renderizar tus propios componentes de visualización. Renderizaremos CustomVis como elemento secundario de Query, por lo que puede recibir todos los datos relevantes como propiedades.

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>
  )
}

Paso 3: Compila el componente CustomVis

A continuación, compilaremos el componente CustomVis. Las propiedades heredadas del componente Query son config, fields, data, pivots y totals:

  • config describe todas las formas en que se deben renderizar los datos en un gráfico, como el grosor de las líneas en un minigráfico o el tamaño y la forma de los puntos de un diagrama de dispersión.
  • fields almacena metadatos adicionales sobre los valores de medición y dimensión que muestra la consulta, como el modo en que se deben formatear los valores o el nombre de cada eje.
  • data es la respuesta de clave-valor que se mostró de la consulta.
  • pivots describe la dimensión según la cual se dinamiza la consulta.
  • totals hace referencia a los totales de las filas de Looker para usarse en las visualizaciones basadas en tablas.

Podemos pasar estas propiedades sin modificar a la visualización de una tabla si insertas un componente 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} />
}

Esto nos da una idea de los datos, ya que se muestran directamente desde el SDK. En la respuesta procesada, hay una fila para cada marca con resultados agrupados o reorientados, por trimestre.

Paso 4: Transforma los datos normalizados

A fin de convertir estos datos dinámicos para que se rendericen con minigráficos, aíslamos todos los valores de medición y los pasamos a los subgráficos. En el siguiente gráfico, se destacan los datos relevantes de una sola fila para ilustrar los datos que se contraerán y renderizarán con una visualización secundaria:

Gráfico de resultados de datos con los recuentos de pedidos de la segunda fila destacados.

Crearemos una transformación personalizada para esto. El siguiente es un ejemplo específico para esta situación; deberás analizar tus propios datos según corresponda.


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 above.
    // 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: [],
            }}
          />
        ),
      },
    ]
  }, [])
}

La función se crea con los siguientes pasos:

  1. Reduce el conjunto de datos para aislar el nombre de la marca de los datos trimestrales de pedidos de cada fila.
  2. Actualiza cada fila para incluir la dimensión y un componente de React renderizado que pueda representar los valores de cada fila en la tabla.

Paso 5: Inserta los datos transformados en CustomVis

Ahora, transforma los datos con nuestra nueva función y asigna el resultado a una nueva variable llamada 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}
    />
  )
}

Paso 6: Genere la visualización personalizada

Después de insertar los datos transformados y configurar el gráfico, la visualización se verá como este ejemplo de una tabla con gráficos de minigráficos individuales para cada fila:

Una visualización personalizada que muestra una tabla con una fila para cada marca y una visualización de minigráfico incorporada que muestra los pedidos por trimestre en cada fila.

La totalidad del código necesario para renderizar la visualización anterior es el siguiente:


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 above.
    // 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>
  )
}

Próximos pasos