[#912,@portaljs/components][m]: refactor LineChart and add more params

This commit is contained in:
João Demenech
2023-06-06 16:06:04 -03:00
parent 223a1bdd77
commit 5190f50948
3 changed files with 61 additions and 19 deletions

View File

@@ -90,5 +90,5 @@ const TableInner: React.FC<FlatUiTableProps> = ({
<Grid data={parsedData.data} /> <Grid data={parsedData.data} />
</div> </div>
); );
return <Spinning />; return <LoadingSpinner />;
}; };

View File

@@ -1,10 +1,19 @@
import { useEffect, useState } from 'react';
import LoadingSpinner from './LoadingSpinner';
import { VegaLite } from './VegaLite'; import { VegaLite } from './VegaLite';
import loadData from '../lib/loadData';
type AxisType = 'quantitative' | 'temporal';
type TimeUnit = 'year' | undefined; // or ...
export type LineChartProps = { export type LineChartProps = {
data: Array<Array<string | number>> | string | { x: string; y: number }[]; data: Array<Array<string | number>> | string | { x: string; y: number }[];
title?: string; title?: string;
xAxis?: string; xAxis?: string;
xAxisType?: AxisType;
xAxisTimeUnit: TimeUnit;
yAxis?: string; yAxis?: string;
yAxisType?: AxisType;
fullWidth?: boolean; fullWidth?: boolean;
}; };
@@ -13,15 +22,16 @@ export function LineChart({
fullWidth = false, fullWidth = false,
title = '', title = '',
xAxis = 'x', xAxis = 'x',
xAxisType = 'temporal',
xAxisTimeUnit = 'year', // TODO: defaults to undefined would probably work better... keeping it as it's for compatibility purposes
yAxis = 'y', yAxis = 'y',
yAxisType = 'quantitative',
}: LineChartProps) { }: LineChartProps) {
var tmp = data; const [isLoading, setIsLoading] = useState<boolean>(false);
if (Array.isArray(data)) {
tmp = data.map((r) => { // By default, assumes data is an Array...
return { x: r[0], y: r[1] }; const [specData, setSpecData] = useState<any>({ name: 'table' });
});
}
const vegaData = { table: tmp };
const spec = { const spec = {
$schema: 'https://vega.github.io/schema/vega-lite/v5.json', $schema: 'https://vega.github.io/schema/vega-lite/v5.json',
title, title,
@@ -33,9 +43,7 @@ export function LineChart({
strokeWidth: 1, strokeWidth: 1,
tooltip: true, tooltip: true,
}, },
data: { data: specData,
name: 'table',
},
selection: { selection: {
grid: { grid: {
type: 'interval', type: 'interval',
@@ -45,19 +53,44 @@ export function LineChart({
encoding: { encoding: {
x: { x: {
field: xAxis, field: xAxis,
timeUnit: 'year', timeUnit: xAxisTimeUnit,
type: 'temporal', type: xAxisType,
}, },
y: { y: {
field: yAxis, field: yAxis,
type: 'quantitative', type: yAxisType,
}, },
}, },
}; } as any;
if (typeof data === 'string') {
spec.data = { url: data } as any; useEffect(() => {
return <VegaLite fullWidth={fullWidth} spec={spec} />; // 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 <VegaLite fullWidth={fullWidth} data={vegaData} spec={spec} />; return isLoading ? (
<div className="w-full flex items-center justify-center w-[600px] h-[300px]">
<LoadingSpinner />
</div>
) : (
<VegaLite fullWidth={fullWidth} data={vegaData} spec={spec} />
);
} }

View File

@@ -19,10 +19,19 @@ const meta: Meta = {
description: description:
'Name of the X axis on the data. Required when the "data" parameter is an URL.', '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: { yAxis: {
description: description:
'Name of the Y axis on the data. Required when the "data" parameter is an URL.', 'Name of the Y axis on the data. Required when the "data" parameter is an URL.',
}, },
yAxisType: {
description: 'Type of the Y axis',
},
fullWidth: { fullWidth: {
description: description:
'Whether the component should be rendered as full bleed or not', 'Whether the component should be rendered as full bleed or not',