Mit Visualisierungskomponenten eine benutzerdefinierte Visualisierung erstellen

Diese Anleitung richtet sich an erfahrene JavaScript-Entwickler und setzt Kenntnisse in bestimmten Programmiertechniken voraus.

In diesem Beispiel beginnen wir mit einem Balkendiagramm, einer nativen Visualisierung von Looker, die hypothetische wöchentliche Umsatzinformationen anzeigt:

Anschließend erstellen wir mithilfe von Visualisierungskomponenten eine benutzerdefinierte Visualisierung, die zeigt, wie die Trends der einzelnen Marken im letzten Quartal im Trend liegen. Das Ergebnis ist eine neue Art der Visualisierung, die aus einer Reihe von Sparklinen besteht, die in einer Tabelle verschachtelt sind. Beispiel:

In diesem Beispiel werden nicht nur das Erstellen einer benutzerdefinierten Visualisierung, sondern auch einige Best Practices für die Arbeit mit der Looker API in einer React-Anwendung veranschaulicht.

Wenn Sie eine benutzerdefinierte Visualisierung mit Looker-Komponenten erstellen möchten, stellen Sie sicher, dass Ihre Einrichtung die Anforderungen erfüllt, und führen Sie dann die folgenden Schritte aus:

  1. Abfrage in einem Explore erstellen und den Wert qid kopieren
  2. Daten an eine benutzerdefinierte Visualisierungskomponente übergeben
  3. Komponente CustomVis erstellen
  4. Normalisierte Daten transformieren
  5. Fügen Sie die transformierten Daten in CustomVis ein.
  6. Benutzerdefinierte Visualisierung generieren

Die Verwendung von Visualisierungskomponenten zum Erstellen einer benutzerdefinierten Visualisierung ist sinnvoll, wenn sie für eine eingebettete Anwendung oder Erweiterung vorgesehen ist. Wenn Sie die benutzerdefinierte Visualisierung für Looker-Nutzer auf einer Looker-Instanz verfügbar machen möchten, folgen Sie der Anleitung auf der Dokumentationsseite zu visualization. Wenn Sie eine benutzerdefinierte Visualisierung entwickeln und in den Looker Marketplace hochladen möchten, folgen Sie der Anleitung auf der Dokumentationsseite Benutzerdefinierte Visualisierung für den Looker Marketplace entwickeln.

Voraussetzungen

Zuerst sind einige Elemente erforderlich:

  • Sie benötigen Zugriff auf eine Looker-Instanz.
  • Unabhängig davon, ob Sie das Erweiterungs-Framework oder Ihre eigene React-Anwendung verwenden, ist es wichtig, dass Sie sich mit der Looker API authentifizieren und Zugriff auf das Looker SDK-Objekt haben. Weitere Informationen finden Sie unter Looker API-Authentifizierung oder Erweiterungs-Framework.
  • Prüfen Sie, ob Sie das NPM-Paket für Looker-Visualisierungskomponenten und das NPM-Paket von @looker/components-data installiert haben. Informationen zum Installieren und Verwenden des Pakets von Visualisierungskomponenten finden Sie im README-Dokument, das in GitHub und NPM verfügbar ist.

Schritt 1: Abfrage in „Erkunden“ erstellen und die Abfrage-ID kopieren

In diesem Beispiel verwenden wir hypothetische wöchentliche Verkaufsinformationen für Marken, die wir für ein ganzes Quartal erfassen.

In einem explorativen Analysetool können wir eine Abfrage ausführen und ein Diagramm der Daten mit einem der nativen Visualisierungstypen von Looker erstellen. Das Diagramm bietet jede Menge Informationen, aber es ist schwierig, auf einen Blick zu erkennen, wie die Trends bei den einzelnen Marken aussehen:

Wie beim Beispiel für das Rendern einer einfachen Visualisierung besteht der nächste Schritt darin, den Wert qid aus der URL-Leiste des Bereichs „Erkunden“ zu kopieren. Für dieses Beispiel lautet der qid 4tQKzCBOwBGNWTskQyEpG8.

Schritt 2: Daten an eine benutzerdefinierte Visualisierungskomponente übergeben

Übergeben Sie zuerst den Wert qid aus der URL „Erkunden“ an die Query-Komponente und das authentifizierte SDK-Objekt an 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='4tQKzCBOwBGNWTskQyEpG8'></Query>
    </DataProvider>
  )
}

Anstatt eine native Looker-Visualisierung über die Komponente Visualization zu rendern, erstellen wir unsere eigene benutzerdefinierte Komponente namens CustomVis.

Die Komponente Query kann jedes React-Element als untergeordnetes Element annehmen und übergibt einfach die Werte config, data, fields und totals als Eigenschaften, um deine eigenen Visualisierungskomponenten zu rendern. Wir rendern CustomVis als untergeordnetes Element von Query, damit es alle relevanten Daten als Properties empfangen kann.

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='4tQKzCBOwBGNWTskQyEpG8'>
        <CustomVis />
      </Query>
    </DataProvider>
  )
}

Schritt 3: Komponente CustomVis erstellen

Als Nächstes erstellen wir die Komponente CustomVis. Die aus der Komponente Query übernommenen Attribute sind config, fields, data und totals:

  • Mit config werden alle Möglichkeiten zum Rendern der Daten in einem Diagramm beschrieben, z. B. die Linienstärke in einer Sparkline oder die Größe und Form der Punkte eines Streudiagramms.
  • In fields werden zusätzliche Metadaten zu den von der Abfrage zurückgegebenen Messwert- und Dimensionswerten gespeichert, z. B. zur Formatierung der Werte oder zur Beschriftung der einzelnen Achsen.
  • data ist die Schlüssel/Wert-Antwort, die von der Abfrage zurückgegeben wurde.
  • totals verweist auf die Zeilensummen von Looker zur Verwendung in tabellenbasierten Visualisierungen.

Wir können diese unveränderten Attribute an eine Tabellenvisualisierung übergeben, indem wir eine Table-Komponente einfügen.

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

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

So bekommen wir eine Vorstellung davon, welche Daten direkt vom SDK zurückgegeben werden. In der gerenderten Antwort gibt es für jede Marke eine Zeile, jede Woche:

Schritt 4: Normalisierte Daten transformieren

Um Zeitachsentrend-Informationen aus diesen Daten zu erhalten, müssen wir die Zeilen nach dem Markennamen gruppieren. Anstatt eine neue Zeile für jede Woche und jede Marke zu erstellen, möchten wir eine einzelne Zeile für jeden Markennamen – und darin verschachtelt – eine Liste mit Datumsangaben und Bestellzahlen.

Wir erstellen eine benutzerdefinierte Transformation, um die Werte so zu gruppieren. Unten sehen Sie ein Beispiel, das speziell für dieses Szenario gilt. Sie müssen Ihre eigenen Daten entsprechend parsen.

import React from 'react'
import { Table } from '@looker/visualizations'
import { filter, pick } from 'lodash'

const transformData = data => {
  const brandKey = 'products.brand_name'

  // create a unique set of brand names
  const uniqueBrands = new Set(data.map(d => d[brandKey]))

  // convert the Set back to an array and nest values below each brand name
  // sample output:
  // [{
  //     products.brand_name: "Looker",
  //     orders.count: { orders.created_week: '2019-09-30', orders.count: 17 }
  //  }, ...]
  return Array.from(uniqueBrands).map(brand => {
    const values = filter(data, { [brandKey]: brand }).map(d =>
      pick(d, ['orders.created_week', 'orders.count'])
    )

    return { [brandKey]: brand, 'orders.count': values }
  })
}

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

Mit den folgenden Schritten wird diese Funktion erstellt:

  1. Weisen Sie zuerst der Variable products.brand_name die Variable brandKey zu. So wird die Datenreihe in der Datenantwort gekennzeichnet und Sie können die Informationen gruppieren.
  2. Erstellen Sie als Nächstes eine eindeutige Liste mit Markennamen, indem Sie die Antwort zuordnen und nur die Werte zurückgeben, die products.brand_name zugewiesen sind. Diese werden dann an den Konstruktor Set übergeben. In JavaScript ist eine Set eine Liste, in der Werte nur einmal vorkommen können. Dadurch wird automatisch eine Liste eindeutiger Werte erstellt.
  3. Konvertieren Sie dann die Set einzelner Marken wieder in ein Array, um Tools zur Listentransformation zu verwenden, z. B. map.
  4. Filtern Sie für jede einzelne Marke die ursprüngliche Datenantwort so, dass sie nur die Zeitachsenzeilen enthält, die für diesen Markennamen relevant sind.
  5. Verschachteln Sie diese Werte schließlich für jeden Markennamen unter dem Objektschlüssel orders.count. Auch hier sehen Sie ein Beispiel dafür, wie hier dies zurückgegeben werden würde, wobei der Markenname auf den Stringwert und orders.count auf die Liste aller relevanten Werte für diese Marke festgelegt wäre.

Schritt 5: Die transformierten Daten in CustomVis einfügen

Transformieren Sie nun die Daten mit unserer neuen Funktion und weisen Sie die Ausgabe einer neuen Variablen namens nestedData zu.

import React from 'react'
import { Table } from '@looker/visualizations'
import { filter, pick } from 'lodash'

const transformData = data => {
  const brandKey = 'products.brand_name'

  // create a unique set of brand names
  const uniqueBrands = new Set(data.map(d => d[brandKey]))

  // convert the Set back to an array and nest values below each brand name
  // sample output:
  // [{
  //     products.brand_name: "Looker",
  //     orders.count: { orders.created_week: '2019-09-30', orders.count: 17 }
  //  }, ...]
  return Array.from(uniqueBrands).map(brand => {
    const values = filter(data, { [brandKey]: brand }).map(d =>
      pick(d, ['orders.created_week', 'orders.count'])
    )

    return { [brandKey]: brand, 'orders.count': values }
  })
}

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

  return <Table config={config} data={data} fields={fields} />
}

Als Nächstes führen Sie eine Schleife über das Array nestedData aus und übergeben die verschachtelten Werte in ein Standard-Sparkline-Diagramm, das von der Visualisierungskomponentenbibliothek von Looker zur Verfügung gestellt wird.

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

const transformData = data => {
  const brandKey = 'products.brand_name'

  // create a unique set of brand names
  const uniqueBrands = new Set(data.map(d => d[brandKey]))

  // convert the Set back to an array and nest values below each brand name
  // sample output:
  // [{
  //     products.brand_name: "Looker",
  //     orders.count: { orders.created_week: '2019-09-30', orders.count: 17 }
  //  }, ...]
  return Array.from(uniqueBrands).map(brand => {
    const values = filter(data, { [brandKey]: brand }).map(d =>
      pick(d, ['orders.created_week', 'orders.count'])
    )

    return { [brandKey]: brand, 'orders.count': values }
  })
}

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

  const nestedSparklines = nestedData.map(d => {
    return {
      ...d,
      'orders.count': () => (
        <Sparkline
          data={d['orders.count']}
          config={config}
          fields={fields}
          height={75}
        />
      ),
    }
  })

  return <Table config={config} data={nestedSparklines} fields={fields} />
}

Im Code oben geschieht Folgendes:

  • Die Daten werden mehr als einmal zugeordnet, um für jede Zeile eine neue Sparkline zu erstellen.
  • Die Werte, die unter dem Schlüssel orders.count verschachtelt sind (die Daten- und Anzahlfolge, die zu dieser Marke gehören), werden an die Property data von Sparkline übergeben.
  • Die config- und fields-Objekte, die für das Rendern aller Diagramme erforderlich sind, werden ebenfalls übergeben. Die Höhe ist ebenfalls auf 75 Pixel festgelegt, um ein angenehmes Layout für jede Zeile in der Tabelle zu ermöglichen.
  • Abschließend wird das verschachtelte Diagrammobjekt in das Diagramm Table übergeben.

Schritt 6: Benutzerdefinierte Visualisierung generieren

Nachdem Sie die transformierten Daten eingefügt und das Diagramm konfiguriert haben, sieht die Visualisierung wie in diesem Beispiel einer Tabelle mit einzelnen Sparkline-Diagrammen für jede Zeile aus:

Der gesamte Code, der zum Rendern der Visualisierung erforderlich ist, sieht so aus:

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

const transformData = data => {
  const brandKey = 'products.brand_name'

  // create a unique set of brand names
  const uniqueBrands = new Set(data.map(d => d[brandKey]))

  // convert the Set back to an array and nest values below each brand name
  // sample output:
  // [{
  //     products.brand_name: "Looker",
  //     orders.count: { orders.created_week: '2019-09-30', orders.count: 17 }
  //  }, ...]
  return Array.from(uniqueBrands).map(brand => {
    const values = filter(data, { [brandKey]: brand }).map(d =>
      pick(d, ['orders.created_week', 'orders.count'])
    )

    return { [brandKey]: brand, 'orders.count': values }
  })
}

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

  const nestedSparklines = nestedData.map(d => {
    return {
      ...d,
      'orders.count': () => (
        <Sparkline
          data={d['orders.count']}
          config={config}
          fields={fields}
          height={75}
        />
      ),
    }
  })

  return <Table config={config} data={nestedSparklines} fields={fields} />
}

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

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

Nächste Schritte