diff --git a/packages/components/src/components/FlatUiTable.tsx b/packages/components/src/components/FlatUiTable.tsx index bec51bbc..69899ae4 100644 --- a/packages/components/src/components/FlatUiTable.tsx +++ b/packages/components/src/components/FlatUiTable.tsx @@ -90,5 +90,5 @@ const TableInner: React.FC = ({ ); - return ; + return ; }; diff --git a/packages/components/src/components/LineChart.tsx b/packages/components/src/components/LineChart.tsx index 278a1e3b..275ed57f 100644 --- a/packages/components/src/components/LineChart.tsx +++ b/packages/components/src/components/LineChart.tsx @@ -1,10 +1,19 @@ +import { useEffect, useState } from 'react'; +import LoadingSpinner from './LoadingSpinner'; import { VegaLite } from './VegaLite'; +import loadData from '../lib/loadData'; + +type AxisType = 'quantitative' | 'temporal'; +type TimeUnit = 'year' | undefined; // or ... export type LineChartProps = { data: Array> | string | { x: string; y: number }[]; title?: string; xAxis?: string; + xAxisType?: AxisType; + xAxisTimeUnit: TimeUnit; yAxis?: string; + yAxisType?: AxisType; fullWidth?: boolean; }; @@ -13,15 +22,16 @@ export function LineChart({ fullWidth = false, title = '', xAxis = 'x', + xAxisType = 'temporal', + xAxisTimeUnit = 'year', // TODO: defaults to undefined would probably work better... keeping it as it's for compatibility purposes yAxis = 'y', + yAxisType = 'quantitative', }: LineChartProps) { - var tmp = data; - if (Array.isArray(data)) { - tmp = data.map((r) => { - return { x: r[0], y: r[1] }; - }); - } - const vegaData = { table: tmp }; + const [isLoading, setIsLoading] = useState(false); + + // By default, assumes data is an Array... + const [specData, setSpecData] = useState({ name: 'table' }); + const spec = { $schema: 'https://vega.github.io/schema/vega-lite/v5.json', title, @@ -33,9 +43,7 @@ export function LineChart({ strokeWidth: 1, tooltip: true, }, - data: { - name: 'table', - }, + data: specData, selection: { grid: { type: 'interval', @@ -45,19 +53,44 @@ export function LineChart({ encoding: { x: { field: xAxis, - timeUnit: 'year', - type: 'temporal', + timeUnit: xAxisTimeUnit, + type: xAxisType, }, y: { field: yAxis, - type: 'quantitative', + type: yAxisType, }, }, - }; - if (typeof data === 'string') { - spec.data = { url: data } as any; - return ; + } as any; + + useEffect(() => { + // If data is string, assume it's a URL + if (typeof data === 'string') { + setIsLoading(true); + + // Manualy loading the data allows us to do other kinds + // of stuff later e.g. load a file partially + loadData(data).then((res: any) => { + setSpecData({ values: res, format: { type: 'csv' } }); + setIsLoading(false); + }); + } + }, []); + + var vegaData = {}; + if (Array.isArray(data)) { + var dataObj; + dataObj = data.map((r) => { + return { x: r[0], y: r[1] }; + }); + vegaData = { table: dataObj }; } - return ; + return isLoading ? ( +
+ +
+ ) : ( + + ); } diff --git a/packages/components/stories/LineChart.stories.ts b/packages/components/stories/LineChart.stories.ts index 66ac6043..8428ee8d 100644 --- a/packages/components/stories/LineChart.stories.ts +++ b/packages/components/stories/LineChart.stories.ts @@ -19,10 +19,19 @@ const meta: Meta = { description: 'Name of the X axis on the data. Required when the "data" parameter is an URL.', }, + xAxisType: { + description: 'Type of the X axis', + }, + xAxisTimeUnit: { + description: 'Time unit of the X axis (optional)', + }, yAxis: { description: 'Name of the Y axis on the data. Required when the "data" parameter is an URL.', }, + yAxisType: { + description: 'Type of the Y axis', + }, fullWidth: { description: 'Whether the component should be rendered as full bleed or not',