このチュートリアルは、経験豊富な JavaScript デベロッパーを対象としており、関数型プログラミングのテクニックをある程度理解していることを前提としています。
この例では、一部のブランドの仮想的な四半期ごとの売上情報に関連するクエリから始めます。まず、特定のブランドのクエリをフィルタして、その結果を四半期ごとの売上高でピボットします。次の表に例を示します。
次に、可視化コンポーネントを使用して、各ブランドの商品が過去四半期にどのように推移したかを示すカスタム可視化を構築します。その結果、以下の例のように、テーブル内にネストされた一連のスパークラインで構成される新しい種類の可視化が作成されます。
この例では、カスタム可視化を作成する方法を紹介しながら、React アプリケーション内で Looker API と連携するためのいくつかのベスト プラクティスを示しています。
Looker コンポーネントを使用してカスタマイズされた可視化を作成するには、設定が要件を満たしていることを確認してから、次の手順を実行します。
- データ探索でクエリを作成し、
qid
の値をコピーする - データをカスタム可視化コンポーネントに渡す
CustomVis
コンポーネントを作成する- 正規化されたデータを変換する
- 変換したデータを
CustomVis
に挿入する - カスタム可視化を生成する
カスタム可視化を構築するために可視化コンポーネントを使用することは、カスタム可視化が埋め込み型のアプリケーションまたは拡張機能を対象としている場合に適しています。Looker ユーザーが Looker インスタンス全体でカスタム可視化を利用できるようにする場合は、
visualization
のドキュメント ページの手順をご覧ください。カスタム可視化を開発して Looker Marketplace にアップロードする場合は、Looker Marketplace のカスタム可視化の実現のドキュメント ページの手順をご覧ください。
要件
始める前に、いくつかの要素が必要になります。
- Looker インスタンスに対するアクセス権が必要です。
- 拡張機能のフレームワークを構築する場合でも、独自のスタンドアロンの React アプリケーションを構築する場合でも、Looker の API で認証し、Looker SDK オブジェクトにアクセスできることが重要です。詳細については、Looker API 認証または拡張機能フレームワークをご覧ください。
- Looker 可視化コンポーネントの NPM パッケージと
@looker/components-data
NPM パッケージがインストールされていることを確認してください。可視化コンポーネント パッケージのインストールと使用方法については、GitHub と NPM にある README ドキュメントをご覧ください。
ステップ 1: データ探索でクエリを作成し、クエリ ID をコピーする
この例では、長期的にトラッキングしているブランドの仮想的な四半期ごとの売上情報を使用します。
ピボットが Looker に組み込まれていて、クエリ結果をグループ化するので、このデータをピボットします。Explore でクエリを実行して、Looker のネイティブ可視化タイプを使用してデータのグラフを作成できます。このグラフには多くの情報が含まれていますが、各ブランドの商品がどのように推移しているか一目で解析することは困難です。
シンプルな可視化のレンダリングの例と同様に、次のステップでは、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 要素を子として受け入れることが可能で、config
、data
、fields
、totals
の値をプロパティとして渡すだけで独自の可視化コンポーネントをレンダリングします。CustomVis
は Query
の子としてレンダリングされ、関連するすべてのデータをプロパティとして受け取ることができます。
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
コンポーネントから継承されるプロパティは、config
、fields
、data
、pivots
、totals
です。
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 値を分離してサブグラフに渡します。次のグラフでは、子の可視化で折りたたみとレンダリングを行うデータを示すため、単一行に関連するデータがハイライト表示されています。
そのためにカスタム変換を作成します。以下は、このシナリオに固有の例です。独自のデータは、それに応じて解析する必要があります。
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: [],
}}
/>
),
},
]
}, [])
}
関数は次の手順で作成します。
- データセットを削減して、各行の四半期ごとの注文データからブランド名を分離します。
- 各行を更新して、ディメンションと、テーブルの各行の値を表すことができるレンダリングされた 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>
)
}
次のステップ
- 可視化コンポーネントと
dashboard
プロパティを使用して単純なビジュアリゼーションをレンダリングする - 可視化コンポーネントと
query
プロパティを使用して単純なビジュアリゼーションをレンダリングする - 可視化コンポーネントを使用してカスタムのビジュアリゼーションをレンダリングする
- ビジュアリゼーションとクエリのプロパティ テーブル