이 튜토리얼은 숙련된 JavaScript 개발자를 대상으로 하며 기능 프로그래밍 기법에 익숙하다고 가정합니다.
이 예시에서는 일부 브랜드의 분기별 가상 판매 정보와 관련된 쿼리로 시작합니다. 먼저 특정 브랜드에 대한 쿼리를 필터링한 후 판매 분기를 기준으로 결과를 피벗합니다. 예시는 다음 표를 참조하세요.
그런 다음 시각화 구성요소를 사용하여 지난 분기 동안 각 브랜드 제품의 추세를 보여주는 커스텀 시각화를 만들어 보겠습니다. 그 결과, 다음 예시와 같이 테이블 내에 중첩된 일련의 스파크라인으로 구성된 새로운 종류의 시각화가 생성됩니다.
이 예시는 커스텀 시각화를 만드는 방법을 보여주고 React 애플리케이션 내에서 Looker API를 사용하기 위한 몇 가지 권장사항을 보여줍니다.
Looker 구성요소를 사용하여 맞춤설정된 시각화를 빌드하려면 설정이 요구사항을 충족하는지 확인한 후 다음 단계를 수행합니다.
- Explore에서 쿼리를 빌드하고
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단계: Explore에서 쿼리 빌드 및 쿼리 ID 복사
이 예시에서는 시간 경과에 따라 추적하는 브랜드의 분기별 판매 정보를 가상으로 사용합니다.
피벗은 쿼리 결과를 그룹화하는 기본 제공되는 방법이므로 이 데이터를 피벗합니다. 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
는 쿼리에서 반환된 측정값 및 측정기준 값에 대한 추가 메타데이터(예: 값의 형식 지정 방법 또는 각 축의 라벨 지정)를 저장합니다.data
는 쿼리에서 반환된 키/값 응답입니다.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단계: 정규화된 데이터 변환
중첩된 스파크라인으로 렌더링되도록 피벗된 데이터를 변환하려면 모든 측정 값을 분리한 후 하위 차트에 전달합니다. 다음 차트에서는 단일 행의 관련 데이터가 강조표시되어 하위 시각화를 통해 축소 및 렌더링할 데이터를 보여줍니다.
이를 위한 커스텀 변환을 만들어 보겠습니다. 다음은 이 시나리오와 관련된 예시입니다. 자체 데이터는 파싱해야 합니다.
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
속성을 사용하여 간단한 시각화 렌더링 - 시각화 구성요소를 사용하여 커스텀 시각화 렌더링
- 시각화 및 쿼리 속성 표