Mit Visualisierungskomponenten eine benutzerdefinierte Visualisierung erstellen

Dieses Tutorial richtet sich an erfahrene JavaScript-Entwickler und setzt eine gewisse Vertrautheit mit funktionalen Programmiertechniken voraus.

In diesem Beispiel beginnen wir mit einer Abfrage, die sich auf hypothetische Quartalsumsätze für einige Marken bezieht. Zuerst filtern wir die Abfrage nach bestimmten Marken und pivotieren dann die Ergebnisse nach Verkaufsquartal. Die folgende Tabelle zeigt ein Beispiel.

Ergebnisse aus einer Abfrage der Auftragszahlen nach Marke, mit einem Pivot für die Dimension „Erstellte Aufträge“.

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

Eine benutzerdefinierte Visualisierung mit einer Tabelle mit einer Zeile für jede Marke und einer eingebetteten Sparkline-Visualisierung, die die Bestellungen pro Quartal in jeder Zeile anzeigt.

Neben der Erstellung einer benutzerdefinierten Visualisierung zeigt dieses Beispiel einige Best Practices für die Arbeit mit der Looker-API in einer React-Anwendung.

Wenn Sie eine benutzerdefinierte Visualisierung mit Looker-Komponenten erstellen möchten, muss Ihre Einrichtung die Anforderungen erfüllen. 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. Transformierte Daten in CustomVis einfügen
  6. Benutzerdefinierte Visualisierung erstellen

Die Verwendung von Visualisierungskomponenten zum Erstellen einer benutzerdefinierten Visualisierung ist sinnvoll, wenn die benutzerdefinierte Visualisierung für eine eingebettete Anwendung oder Erweiterung vorgesehen ist. Wenn Sie die benutzerdefinierte Visualisierung für Looker-Nutzer in einer Looker-Instanz verfügbar machen möchten, folgen Sie der Anleitung auf der visualization-Dokumentationsseite. 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

Bevor Sie beginnen, sind einige Elemente erforderlich:

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

Schritt 1: Abfrage in einem Explore erstellen und die Abfrage-ID kopieren

In diesem Beispiel verwenden wir hypothetische vierteljährliche Umsatzdaten für Marken, die wir im Laufe der Zeit beobachten.

Wir pivotieren diese Daten, da Pivoting die integrierte Methode von Looker ist, die Abfrageergebnisse zu gruppieren. In einem Explore können Sie mit einem der nativen Visualisierungstypen von Looker eine Abfrage ausführen und ein Diagramm der Daten erstellen. Das Diagramm bietet viele Informationen, aber es ist schwer zu veranschaulichen, wie die Produkte der einzelnen Marken im Trend liegen:

Diagramm, das aus einer Abfrage der Auftragszahlen nach Marke resultiert, mit einer Pivot-Funktion für die Dimension „Bisherige Bestellungen“.

Wie im Beispiel für das Rendern einer einfachen Visualisierung muss im nächsten Schritt der Wert qid aus der URL-Leiste des Explores kopiert werden. In diesem Beispiel ist der Wert für qid Uijcav7pCA4MZY2MompsPZ, aber dieser Wert ist spezifisch für unsere Testinstanz. Ihr Wert wird anders aussehen.

Schritt 2: Daten an eine benutzerdefinierte Visualisierungskomponente übergeben

Übergeben Sie zuerst den Wert qid aus der URL des Explores an die Komponente Query 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='Uijcav7pCA4MZY2MompsPZ'></Query>
    </DataProvider>
  )
}

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

Die Query-Komponente kann jedes React-Element als untergeordnetes Element annehmen und gibt einfach die Werte config, data, fields und totals als Eigenschaften weiter, um Ihre eigenen Visualisierungskomponenten zu rendern. CustomVis wird als untergeordnetes Element von Query gerendert, damit alle relevanten Daten als Properties empfangen werden können.

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

Schritt 3: CustomVis-Komponente erstellen

Als Nächstes erstellen wir die Komponente CustomVis. Die von der Query-Komponente übernommenen Eigenschaften sind config, fields, data, pivots und totals:

  • In config wird beschrieben, wie die Daten in einem Diagramm gerendert werden sollten, z. B. die Stärke der Linie in einer Sparkline oder die Größe und Form der Punkte eines Streudiagramms.
  • fields speichert zusätzliche Metadaten zu den Messwert- und Dimensionswerten, die von der Abfrage zurückgegeben werden, z. B. wie die Werte formatiert werden sollen oder was die einzelnen Achsen mit Labels versehen sollen.
  • data ist die Schlüssel/Wert-Antwort, die von der Abfrage zurückgegeben wurde.
  • pivots beschreibt die Dimension, nach der die Abfrage pivotiert wird.
  • totals bezieht sich zur Verwendung in tabellenbasierten Visualisierungen auf die Zeilensummen von Looker.

Wir können diese unveränderten Eigenschaften 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, pivots }) => {
  return <Table config={config} data={data} fields={fields} pivots={pivots} />
}

So erhalten wir einen Eindruck von den Daten, da sie direkt vom SDK zurückgegeben werden. In der gerenderten Antwort gibt es eine Zeile für jede Marke, deren Ergebnisse nach Quartal gruppiert oder als Drehpunkt festgelegt sind.

Schritt 4: Normalisierte Daten transformieren

Damit diese als Drehpunkt festgelegten Daten mit verschachtelten Sparklines gerendert werden, isolieren wir alle Werte und übergeben sie an die Subdiagramme. Im folgenden Diagramm sind die relevanten Daten für eine einzelne Zeile hervorgehoben, um die Daten zu veranschaulichen, die in einer untergeordneten Visualisierung minimiert und gerendert werden:

Diagramm der Datenergebnisse, wobei die Anzahl der Bestellungen in der zweiten Zeile hervorgehoben ist.

Dazu erstellen wir eine benutzerdefinierte Transformation. Das folgende Beispiel bezieht sich auf dieses Szenario. Sie müssen Ihre eigenen Daten entsprechend parsen.


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

Die Funktion wird in den folgenden Schritten erstellt:

  1. Reduzieren Sie den Wert für den Datensatz, um den Markennamen von den vierteljährlichen Bestelldaten für jede Zeile zu isolieren.
  2. Aktualisieren Sie jede Zeile, um die Dimension und eine gerenderte React-Komponente hinzuzufügen, die die Werte für jede Zeile in der Tabelle darstellen kann.

Schritt 5: Transformierte Daten in CustomVis einfügen

Transformieren Sie nun die Daten mit unserer neuen Funktion und weisen Sie die Ausgabe einer neuen Variablen mit dem Namen nestedData zu:


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

Schritt 6: Benutzerdefinierte Visualisierung erstellen

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

Eine benutzerdefinierte Visualisierung mit einer Tabelle mit einer Zeile für jede Marke und einer eingebetteten Sparkline-Visualisierung, die die Bestellungen pro Quartal in jeder Zeile anzeigt.

Der gesamte Code, der zum Rendern der obigen Visualisierung erforderlich ist, lautet wie folgt:


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

Nächste Schritte