Como usar componentes para criar uma visualização personalizada

Este tutorial é destinado a desenvolvedores experientes de JavaScript e supõe alguma familiaridade com técnicas funcionais de programação.

Neste exemplo, começamos com uma consulta relacionada a informações hipotéticas de vendas trimestrais para algumas marcas. Primeiro, filtraremos a consulta por marcas específicas e, em seguida, dinamizar os resultados por trimestre de vendas. Consulte a tabela a seguir para ver um exemplo.

Resultados de uma consulta para contagens de pedido por marca, com um pivô na dimensão Pedidos criados no trimestre.

Em seguida, usaremos componentes de visualização para criar uma visualização personalizada que mostra a tendência dos produtos de cada marca no último trimestre. O resultado será um novo tipo de visualização, composto por uma série de sparklines aninhados em uma tabela, como neste exemplo:

Uma visualização personalizada que mostra uma tabela com uma linha para cada marca e um minigráfico incorporado que mostra os pedidos por trimestre em cada linha.

Além de mostrar como criar uma visualização personalizada, este exemplo demonstra algumas práticas recomendadas para trabalhar com a API Looker em um aplicativo React.

Para criar uma visualização personalizada com os componentes do Looker, verifique se sua configuração atende aos requisitos e siga estas etapas:

  1. Crie uma consulta em uma exploração e copie o valor qid
  2. Transmitir os dados para um componente de visualização personalizado
  3. Criar o componente CustomVis
  4. Transformar os dados normalizados
  5. Insira os dados transformados em CustomVis
  6. Gerar a visualização personalizada

O uso de componentes para criar uma visualização personalizada é adequado quando ela é destinada a uma extensão ou aplicativo incorporado. Se você quiser disponibilizar a visualização personalizada para usuários do Looker em uma instância do Looker, siga as instruções na página de documentação do visualization. Se você quiser desenvolver uma visualização personalizada e fazer upload dela no Looker Marketplace, siga as instruções na página de documentação Como desenvolver uma visualização personalizada para o Looker Marketplace.

Requisitos

Antes de começar, alguns elementos são necessários:

  • Você precisa ter acesso a uma instância do Looker.
  • Não importa se você está criando no framework da extensão ou no seu próprio aplicativo autônomo do React, é importante autenticar com a API Looker e ter acesso ao objeto do SDK do Looker. Leia sobre a autenticação da API Looker ou nosso framework de extensão para mais informações.
  • Verifique se você instalou o pacote NPM dos componentes de visualização do Looker e o pacote NPM @looker/components-data. Informações sobre a instalação e o uso do pacote de componentes de visualização podem ser encontradas no documento README, disponível no GitHub e no NPM.

Etapa 1: criar uma consulta em "Explorar" e copiar o ID da consulta

Neste exemplo, usamos informações hipotéticas de vendas trimestrais para as marcas que estamos rastreando ao longo do tempo.

Vamos dinamizar esses dados, já que eles são a maneira integrada de usar o Looker para agrupar os resultados da consulta. Em uma exploração, podemos executar uma consulta e criar um gráfico dos dados usando um dos tipos de visualização nativos do Looker. O gráfico fornece muitas informações, mas é difícil analisar rapidamente as tendências dos produtos de cada marca:

Gráfico resultante de uma consulta de contagens de pedidos por marca, com uma tabela dinâmica sobre a dimensão "Pedidos criados" do trimestre.

Assim como no exemplo de renderização de uma visualização simples, a próxima etapa é copiar o valor qid da barra de URL da guia "Explorar". Para os fins deste exemplo, o valor qid será Uijcav7pCA4MZY2MompsPZ, mas esse valor é específico para nossa instância de teste. Seu valor será diferente.

Etapa 2: transmitir os dados para um componente de visualização personalizado

Para começar, transmita o valor qid tirado do URL do Explorar para o componente Query e o objeto do SDK autenticado para 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>
  )
}

Em vez de renderizar uma visualização nativa do Looker usando o componente Visualization, vamos criar nosso próprio componente personalizado, chamado CustomVis.

O componente Query pode aceitar qualquer elemento do React como filho e transmitir os valores config, data, fields e totals como propriedades para renderizar os próprios componentes de visualização. Renderizaremos CustomVis como filho de Query para que ele possa receber todos os dados relevantes como propriedades.

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

Etapa 3: criar o componente CustomVis

Em seguida, vamos criar o componente CustomVis. As propriedades herdadas do componente Query são config, fields, data, pivots e totals:

  • config descreve todas as maneiras de renderizar os dados em um gráfico, como a espessura da linha em um gráfico sparkline ou o tamanho e o formato dos pontos de um gráfico de dispersão.
  • fields armazena metadados adicionais sobre os valores de medida e dimensão retornados da consulta, por exemplo, como os valores precisam ser formatados ou quais rótulos devem ser rotulados em cada eixo.
  • data é a resposta de chave/valor retornada da consulta.
  • pivots descreve a dimensão pela qual a consulta é dinamizada.
  • totals faz referência aos totais da linha do Looker para uso em visualizações baseadas em tabelas.

É possível transmitir essas propriedades não modificadas para uma visualização de tabela inserindo um 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} />
}

Isso nos dá uma noção dos dados à medida que eles são retornados diretamente do SDK. Na resposta renderizada, há uma linha para cada marca com resultados agrupados ou dinamizados, por trimestre.

Etapa 4: transformar os dados normalizados

Para converter esses dados dinâmicos a serem renderizados com gráficos sparkline aninhados, isolamos todos os valores das medidas e os passamos para os subgráficos. No gráfico a seguir, os dados relevantes de uma única linha estão destacados para ilustrar os dados que serão recolhidos e renderizados com uma visualização filha:

Gráfico de resultados de dados com as contagens de pedidos na segunda linha destacadas.

Criaremos uma transformação personalizada para isso. Veja a seguir um exemplo específico para esse cenário. Você precisará analisar seus próprios dados adequadamente.


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

A função é criada seguindo estas etapas:

  1. Reduza o conjunto de dados para isolar o nome da marca dos dados do pedido trimestral para cada linha.
  2. Atualize cada linha para incluir a dimensão e um componente React renderizado que possa representar os valores de cada linha na tabela.

Etapa 5: inserir os dados transformados em CustomVis

Agora, transforme os dados usando nossa nova função e atribua a saída a uma nova variável chamada 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}
    />
  )
}

Etapa 6: gerar a visualização personalizada

Depois de inserir os dados transformados e configurar o gráfico, a visualização será semelhante a este exemplo de uma tabela com minigráficos:

Uma visualização personalizada que mostra uma tabela com uma linha para cada marca e um minigráfico incorporado que mostra os pedidos por trimestre em cada linha.

O código completo necessário para renderizar a visualização acima é o seguinte:


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óximas etapas