可視化コンポーネントを使用してカスタム可視化を構築する

このチュートリアルは、経験豊富な JavaScript デベロッパーを対象としており、関数型プログラミングのテクニックをある程度理解していることを前提としています。

この例では、一部のブランドの仮想的な四半期ごとの売上情報に関連するクエリから始めます。まず、特定のブランドのクエリをフィルタして、その結果を四半期ごとの売上高でピボットします。次の表に例を示します。

Orders Created Quarter ディメンションでピボットされたブランド別の注文数のクエリの結果。

次に、可視化コンポーネントを使用して、各ブランドの商品が過去四半期にどのように推移したかを示すカスタム可視化を構築します。その結果、以下の例のように、テーブル内にネストされた一連のスパークラインで構成される新しい種類の可視化が作成されます。

各ブランドの行を持つテーブルを示すカスタムビルドの可視化と、各行に四半期ごとの注文を示す埋め込み型スパークラインの可視化。

この例では、カスタム可視化を作成する方法を紹介しながら、React アプリケーション内で Looker API と連携するためのいくつかのベスト プラクティスを示しています。

Looker コンポーネントを使用してカスタマイズされた可視化を作成するには、設定が要件を満たしていることを確認してから、次の手順を実行します。

  1. データ探索でクエリを作成し、qid の値をコピーする
  2. データをカスタム可視化コンポーネントに渡す
  3. CustomVis コンポーネントを作成する
  4. 正規化されたデータを変換する
  5. 変換したデータを CustomVis に挿入する
  6. カスタム可視化を生成する

カスタム可視化を構築するために可視化コンポーネントを使用することは、カスタム可視化が埋め込み型のアプリケーションまたは拡張機能を対象としている場合に適しています。Looker ユーザーが Looker インスタンス全体でカスタム可視化を利用できるようにする場合は、visualization のドキュメント ページの手順をご覧ください。カスタム可視化を開発して Looker Marketplace にアップロードする場合は、Looker Marketplace のカスタム可視化の実現のドキュメント ページの手順をご覧ください。

要件

始める前に、いくつかの要素が必要になります。

  • Looker インスタンスに対するアクセス権が必要です。
  • 拡張機能のフレームワークを構築する場合でも、独自のスタンドアロンの React アプリケーションを構築する場合でも、Looker の API で認証し、Looker SDK オブジェクトにアクセスできることが重要です。詳細については、Looker API 認証または拡張機能フレームワークをご覧ください。
  • Looker 可視化コンポーネントの NPM パッケージ@looker/components-data NPM パッケージがインストールされていることを確認してください。可視化コンポーネント パッケージのインストールと使用方法については、GitHubNPM にある README ドキュメントをご覧ください。

ステップ 1: データ探索でクエリを作成し、クエリ ID をコピーする

この例では、長期的にトラッキングしているブランドの仮想的な四半期ごとの売上情報を使用します。

ピボットが Looker に組み込まれていて、クエリ結果をグループ化するので、このデータをピボットします。Explore でクエリを実行して、Looker のネイティブ可視化タイプを使用してデータのグラフを作成できます。このグラフには多くの情報が含まれていますが、各ブランドの商品がどのように推移しているか一目で解析することは困難です。

Orders Created Quarter ディメンションでピボットされたブランド別の注文数のクエリから生成されたグラフ。

シンプルな可視化のレンダリングの例と同様に、次のステップでは、Explore の URL バーから qid の値をコピーします。この例では qid の値は Uijcav7pCA4MZY2MompsPZ ですが、この値はテスト インスタンスに固有のもので、実際の値は異なる場合があります。

ステップ 2: データをカスタム可視化コンポーネントに渡す

まず、Explore の URL から取得した qid 値を Query コンポーネントに渡し、認証された SDK オブジェクトを 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>
  )
}

次に、Visualization コンポーネントを介してネイティブの Looker 可視化をレンダリングするのではなく、CustomVis という独自のカスタム コンポーネントを構築します。

Query コンポーネントは、任意の React 要素を子として受け入れることが可能で、configdatafieldstotals の値をプロパティとして渡すだけで独自の可視化コンポーネントをレンダリングします。CustomVisQuery の子としてレンダリングされ、関連するすべてのデータをプロパティとして受け取ることができます。

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

ステップ 3: CustomVis コンポーネントを構築する

次に、CustomVis コンポーネントを構築しましょう。Query コンポーネントから継承されるプロパティは、configfieldsdatapivotstotals です。

  • config には、スパークラインの線の太さや散布図の点のサイズと形状など、グラフでデータをレンダリングする方法をすべて記述します。
  • fields には、クエリから返される measure 値とディメンション値に関する追加のメタデータ(値のフォーマット方法や各軸のラベル付け方法など)を格納します。
  • data は、クエリから返された Key-Value レスポンスです。
  • pivots は、クエリをピボットするディメンションを表します。
  • totals は、テーブルベースの可視化で使用するために、Looker の行の合計を参照します。

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

これにより、SDK から直接返されるデータの概要がわかります。レンダリングされたレスポンスには、各ブランドの行があり、結果は四半期ごとにグループ化またはピボット化されます。

ステップ 4: 正規化されたデータを変換する

このピボット化したデータをネストされたスパークラインでレンダリングされるように変換するには、すべての measure 値を分離してサブグラフに渡します。次のグラフでは、子の可視化で折りたたみとレンダリングを行うデータを示すため、単一行に関連するデータがハイライト表示されています。

2 行目の注文数がハイライト表示されているデータの結果のグラフ。

そのためにカスタム変換を作成します。以下は、このシナリオに固有の例です。独自のデータは、それに応じて解析する必要があります。


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

関数は次の手順で作成します。

  1. データセットを削減して、各行の四半期ごとの注文データからブランド名を分離します。
  2. 各行を更新して、ディメンションと、テーブルの各行の値を表すことができるレンダリングされた React コンポーネントを含めます。

ステップ 5: 変換したデータを CustomVis に挿入する

次に、新しい関数を使用してデータを変換し、出力を 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}
    />
  )
}

ステップ 6: カスタム可視化を生成する

変換されたデータを挿入してグラフを構成すると、可視化は、各行の個別のスパークライン グラフを含む次の例のテーブルのようになります。

各ブランドの行を持つテーブルを示すカスタムビルドの可視化と、各行に四半期ごとの注文を示す埋め込み型スパークラインの可視化。

この可視化をレンダリングするために必要なコード全体は次のとおりです。


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

次のステップ