Skip to content

Commit

Permalink
Migrate Chart component to X charts library (#2500)
Browse files Browse the repository at this point in the history
Signed-off-by: Pedro Ferreira <[email protected]>
Co-authored-by: Olivier Tassinari <[email protected]>
  • Loading branch information
apedroferreira and oliviertassinari authored Nov 2, 2023
1 parent a9a27a6 commit dd8d147
Show file tree
Hide file tree
Showing 13 changed files with 355 additions and 200 deletions.
3 changes: 1 addition & 2 deletions examples/npm-stats/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
"start": "NODE_OPTIONS='--max-old-space-size=396' toolpad start"
},
"dependencies": {
"@mui/toolpad": "0.1.34",
"recharts": "2.9.1"
"@mui/toolpad": "0.1.34"
}
}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
"devDependencies": {
"@argos-ci/core": "1.0.0",
"@mui/monorepo": "https://github.com/mui/material-ui.git",
"@mui/x-charts": "6.0.0-alpha.17",
"@next/eslint-plugin-next": "14.0.0",
"@playwright/test": "1.39.0",
"@testing-library/react": "14.0.0",
Expand Down
1 change: 1 addition & 0 deletions packages/toolpad-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
"@mui/toolpad-utils": "0.1.34",
"@mui/types": "7.2.8",
"@mui/utils": "5.14.16",
"@mui/x-charts": "6.0.0-alpha.17",
"@mui/x-data-grid": "6.17.0",
"@mui/x-data-grid-pro": "6.17.0",
"@mui/x-date-pickers": "6.17.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ export default function NodeAttributeEditor<P extends object>({
propType={argType}
jsRuntime={jsBrowserRuntime}
renderControl={(params) => (
<Box sx={{ flex: 1 }}>
<Box sx={{ flex: 1, maxWidth: '100%' }}>
<Control nodeId={node.id} {...params} propType={argType} />
</Box>
)}
Expand Down
79 changes: 66 additions & 13 deletions packages/toolpad-app/src/toolpad/propertyControls/ChartData.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import BarChartIcon from '@mui/icons-material/BarChart';
import ShowChartIcon from '@mui/icons-material/ShowChart';
import LegendToggleIcon from '@mui/icons-material/LegendToggle';
import { evaluateBindable } from '@mui/toolpad-core/jsRuntime';
import { blueberryTwilightPalette } from '@mui/x-charts/colorPalettes';
import * as appDom from '../../appDom';
import type { EditorProps } from '../../types';
import PropertyControl from '../../components/PropertyControl';
Expand Down Expand Up @@ -58,6 +59,8 @@ function ChartDataPropEditor({

const appTheme = React.useMemo(() => createToolpadAppTheme(dom), [dom]);

const defaultPalette = blueberryTwilightPalette(appTheme.palette.mode);

const [dataSeriesEditIndex, setDataSeriesEditIndex] = React.useState<number | null>(null);
const [popoverAnchorElement, setPopoverAnchorElement] = React.useState<HTMLElement | null>(null);

Expand All @@ -72,13 +75,20 @@ function ChartDataPropEditor({
label: newDataSeriesLabel,
kind: 'line',
data: [],
color:
newDataSeriesCount % 2 === 0
? appTheme.palette.secondary.main
: appTheme.palette.primary.main,
color: defaultPalette[(newDataSeriesCount - 1) % defaultPalette.length],
},
]);
}, [appTheme, onChange, value]);
}, [defaultPalette, onChange, value]);

const previousDataSeriesCountRef = React.useRef(value.length);
React.useEffect(() => {
if (previousDataSeriesCountRef.current === 0 && value.length === 1) {
setDataSeriesEditIndex(0);
setPopoverAnchorElement(document.getElementById('data-series-button-1'));
}

previousDataSeriesCountRef.current = value.length;
}, [value.length]);

const handleDataSeriesClick = React.useCallback(
(index: number) => (event: React.MouseEvent<HTMLElement>) => {
Expand All @@ -90,9 +100,18 @@ function ChartDataPropEditor({

const handleDuplicateDataSeries = React.useCallback(
(index: number) => () => {
onChange([...value.slice(0, index + 1), value[index], ...value.slice(index + 1)]);
const newDataSeriesCount = value.length + 1;

onChange([
...value.slice(0, index + 1),
{
...value[index],
color: defaultPalette[(newDataSeriesCount - 1) % defaultPalette.length],
},
...value.slice(index + 1),
]);
},
[onChange, value],
[defaultPalette, onChange, value],
);

const handleRemoveDataSeries = React.useCallback(
Expand Down Expand Up @@ -213,9 +232,11 @@ function ChartDataPropEditor({
const dataResult = (evaluateBindable(jsBrowserRuntime, dataSeries.data, pageState).value ||
[]) as NonNullable<ChartDataSeries['data']>;

return dataResult
.flatMap((dataSeriesPoint) => Object.keys(dataSeriesPoint))
.filter((key, index, array) => array.indexOf(key) === index);
return Array.isArray(dataResult)
? dataResult
.flatMap((dataSeriesPoint) => Object.keys(dataSeriesPoint))
.filter((key, index, array) => array.indexOf(key) === index)
: [];
}),
[jsBrowserRuntime, pageState, value],
);
Expand All @@ -233,10 +254,16 @@ function ChartDataPropEditor({
return (
<ListItem key={index} disableGutters>
<ListItemButton
id={`data-series-button-${index + 1}`}
onClick={handleDataSeriesClick(index)}
aria-describedby={popoverId}
>
<ListItemText primary={label} />
<ListItemText
primary={label}
primaryTypographyProps={{
style: { overflow: 'hidden', textOverflow: 'ellipsis', maxWidth: 166 },
}}
/>
</ListItemButton>
<IconButton
aria-label="Duplicate data series"
Expand Down Expand Up @@ -315,14 +342,40 @@ function ChartDataPropEditor({
options={dataSeriesKeySuggestions[dataSeriesEditIndex]}
value={editDataSeries?.xKey || ''}
onInputChange={handleDataSeriesAutocompletePropChange(dataSeriesEditIndex, 'xKey')}
renderInput={(params) => <TextField {...params} label="xKey" />}
renderInput={(params) => {
const keyExists =
!editDataSeries?.xKey ||
dataSeriesKeySuggestions[dataSeriesEditIndex].includes(editDataSeries.xKey);

return (
<TextField
{...params}
label="xKey"
error={!keyExists}
helperText={keyExists ? '' : 'Property not present in data'}
/>
);
}}
/>
<Autocomplete
freeSolo
options={dataSeriesKeySuggestions[dataSeriesEditIndex]}
value={editDataSeries?.yKey || ''}
onInputChange={handleDataSeriesAutocompletePropChange(dataSeriesEditIndex, 'yKey')}
renderInput={(params) => <TextField {...params} label="yKey" />}
renderInput={(params) => {
const keyExists =
!editDataSeries?.yKey ||
dataSeriesKeySuggestions[dataSeriesEditIndex].includes(editDataSeries.yKey);

return (
<TextField
{...params}
label="yKey"
error={!keyExists}
helperText={keyExists ? '' : 'Property not present in data'}
/>
);
}}
/>
<ColorPicker
label="color"
Expand Down
4 changes: 2 additions & 2 deletions packages/toolpad-components/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
"@mui/material": "5.14.16",
"@mui/toolpad-core": "0.1.34",
"@mui/toolpad-utils": "0.1.34",
"@mui/x-charts": "6.0.0-alpha.17",
"@mui/x-data-grid-pro": "6.17.0",
"@mui/x-date-pickers": "6.17.0",
"@mui/x-license-pro": "6.10.2",
Expand All @@ -51,8 +52,7 @@
"invariant": "2.2.4",
"markdown-to-jsx": "7.3.2",
"react-error-boundary": "4.0.11",
"react-hook-form": "7.47.0",
"recharts": "2.9.1"
"react-hook-form": "7.47.0"
},
"devDependencies": {
"@types/react": "18.2.33",
Expand Down
Loading

0 comments on commit dd8d147

Please sign in to comment.