Skip to content

Commit

Permalink
Scatter Plot Widget: Add a skeleton for loading state (#690)
Browse files Browse the repository at this point in the history
  • Loading branch information
vmilan authored May 26, 2023
1 parent e312dd4 commit 6aedc01
Show file tree
Hide file tree
Showing 10 changed files with 100 additions and 12 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## Not released

- ScatterPlot Widget: Add a skeleton for loading state [#690](https://github.com/CartoDB/carto-react/pull/690)
- Table Widget: Add a skeleton for loading state [#689](https://github.com/CartoDB/carto-react/pull/689)
- TimeSeries Widget: Add a skeleton for loading state [#686](https://github.com/CartoDB/carto-react/pull/686)
- Pie & ComparativePie Widgets: Add a skeleton for loading state [#682](https://github.com/CartoDB/carto-react/pull/682)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import { render } from '../widgets/utils/testUtils';
import ScatterPlotWidgetUI from '../../src/widgets/ScatterPlotWidgetUI';
import ScatterPlotWidgetUI from '../../src/widgets/ScatterPlotWidgetUI/ScatterPlotWidgetUI';
import { mockEcharts } from './testUtils';

describe('ScatterPlotWidgetUI', () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/react-ui/src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import LegendCategories from './widgets/legend/LegendCategories';
import LegendIcon from './widgets/legend/LegendIcon';
import LegendProportion from './widgets/legend/LegendProportion';
import LegendRamp from './widgets/legend/LegendRamp';
import ScatterPlotWidgetUI from './widgets/ScatterPlotWidgetUI';
import ScatterPlotWidgetUI from './widgets/ScatterPlotWidgetUI/ScatterPlotWidgetUI';
import TimeSeriesWidgetUI from './widgets/TimeSeriesWidgetUI/TimeSeriesWidgetUI';
import {
useTimeSeriesContext,
Expand Down
2 changes: 1 addition & 1 deletion packages/react-ui/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import LegendCategories from './widgets/legend/LegendCategories';
import LegendIcon from './widgets/legend/LegendIcon';
import LegendProportion from './widgets/legend/LegendProportion';
import LegendRamp from './widgets/legend/LegendRamp';
import ScatterPlotWidgetUI from './widgets/ScatterPlotWidgetUI';
import ScatterPlotWidgetUI from './widgets/ScatterPlotWidgetUI/ScatterPlotWidgetUI';
import TimeSeriesWidgetUI from './widgets/TimeSeriesWidgetUI/TimeSeriesWidgetUI';
import FeatureSelectionWidgetUI from './widgets/FeatureSelectionWidgetUI';
import RangeWidgetUI from './widgets/RangeWidgetUI/RangeWidgetUI';
Expand Down
1 change: 1 addition & 0 deletions packages/react-ui/src/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ export type ScatterPlotWidgetUI = {
xAxisFormatter?: Function;
yAxisFormatter?: Function;
tooltipFormatter?: Function;
isLoading?: boolean;
};

export type TimeSeriesWidgetUIData = { name: number; value: number }[];
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import React from 'react';
import { Box, styled } from '@mui/material';
import { Skeleton } from '@mui/material';
import { SKELETON_HEIGHT, SkeletonGraphGrid } from '../SkeletonWidgets';
import { BREAKPOINTS } from '../../theme/themeConstants';

const GraphGrid = styled(SkeletonGraphGrid)(({ theme }) => ({
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
marginLeft: theme.spacing(4),
containerType: 'inline-size',

[`@container (max-width: ${BREAKPOINTS.XS}px)`]: {
' > div': {
maxWidth: '75%'
}
}
}));

const DotsBox = styled(Box)(({ theme }) => ({
position: 'relative',
display: 'flex',
justifyContent: 'space-between',
width: '80%',
maxWidth: '50%'
}));

const ScatterPlotSkeleton = ({ height }) => {
function getRandomValue() {
// get a random integer value between 0 and 5
return Math.floor(Math.random() * 5);
}

return (
<Box height={height || SKELETON_HEIGHT}>
<Box mb={4}>
<Skeleton width={48} height={8} />
</Box>

<GraphGrid height={'80%'}>
{[...Array(3)].map((_, i) => (
// Every row is placed with an incremental margin left to reinforce the effect of a scatter plot
<DotsBox key={i} ml={i * 3}>
{[...Array(4)].map((_, i) => (
// Random margins are used to create the effect of a scatter plot
<Box mt={getRandomValue()} ml={getRandomValue()}>
<Skeleton variant='circular' width={12} height={12} />
</Box>
))}
</DotsBox>
))}
</GraphGrid>
</Box>
);
};

export default ScatterPlotSkeleton;
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { useTheme } from '@mui/material';
import PropTypes from 'prop-types';
import React, { useRef, useState, useEffect } from 'react';
import { areChartPropsEqual } from './utils/chartUtils';
import ReactEcharts from '../custom-components/echarts-for-react';
import { areChartPropsEqual } from '../utils/chartUtils';
import ReactEcharts from '../../custom-components/echarts-for-react';
import ScatterPlotSkeleton from './ScatterPlotSkeleton';

function __generateDefaultConfig(
{ tooltipFormatter, xAxisFormatter = (v) => v, yAxisFormatter = (v) => v },
Expand Down Expand Up @@ -76,7 +77,8 @@ function ScatterPlotWidgetUI({
animation,
xAxisFormatter,
yAxisFormatter,
tooltipFormatter
tooltipFormatter,
isLoading
}) {
const theme = useTheme();
const chartInstance = useRef();
Expand All @@ -100,12 +102,16 @@ function ScatterPlotWidgetUI({
});
}, [data, name, animation, theme, xAxisFormatter, yAxisFormatter, tooltipFormatter]);

const HEIGHT = 225;

if (isLoading) return <ScatterPlotSkeleton height={HEIGHT} />;

return (
<EchartsWrapper
ref={chartInstance}
option={options}
lazyUpdate={true}
style={{ height: 225 }}
style={{ height: HEIGHT }}
/>
);
}
Expand Down
2 changes: 0 additions & 2 deletions packages/react-ui/src/widgets/SkeletonWidgets.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ export const SkeletonBarsGrid = styled(Box)(({ theme }) => ({
display: 'flex',
alignItems: 'flex-end',
justifyContent: 'space-between',
width: '100%',
position: 'relative',
padding: theme.spacing(0, 2),

Expand All @@ -28,7 +27,6 @@ export const SkeletonGraphGrid = styled(Box)(({ theme }) => ({
display: 'flex',
alignItems: 'flex-end',
justifyContent: 'space-between',
width: '100%',

// Square grid effect
backgroundImage: `linear-gradient(${theme.palette.grey[50]} 0.5px, transparent 0.5px, transparent calc(100% - 0.5px), ${theme.palette.grey[50]} calc(100% - 0.5px)), linear-gradient(90deg, ${theme.palette.grey[50]} 0.5px, transparent 0.5px, transparent calc(100% - 0.5px), ${theme.palette.grey[50]} calc(100% - 0.5px))`,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from 'react';
import ScatterPlotWidgetUI from '../../../src/widgets/ScatterPlotWidgetUI';
import ScatterPlotWidgetUI from '../../../src/widgets/ScatterPlotWidgetUI/ScatterPlotWidgetUI';
import { Label, ThinContainer } from '../../utils/storyStyles';

const options = {
title: 'Organisms/Widgets/ScatterPlotWidgetUI',
Expand All @@ -22,9 +23,28 @@ const dataDefault = [

const Template = (args) => <ScatterPlotWidgetUI {...args} />;

const LoadingTemplate = (args) => {
return (
<>
<Label variant='body1' mb={3}>
{'Limited width'}
</Label>
<ThinContainer>
<ScatterPlotWidgetUI {...args} />
</ThinContainer>

<Label variant='body1' mt={8} mb={3}>
{'Responsive'}
</Label>
<ScatterPlotWidgetUI {...args} />
</>
);
};

const defaultProps = { data: dataDefault, name: 'name' };

export const Default = Template.bind({});
const DefaultProps = { data: dataDefault, name: 'name' };
Default.args = DefaultProps;
Default.args = defaultProps;

export const xAxisFormatter = Template.bind({});
const xAxisFormatterProps = {
Expand All @@ -50,3 +70,6 @@ const tooltipFormatterProps = {
};

tooltipFormatter.args = tooltipFormatterProps;

export const Loading = LoadingTemplate.bind({});
Loading.args = { ...defaultProps, isLoading: true };
1 change: 1 addition & 0 deletions packages/react-widgets/src/widgets/ScatterPlotWidget.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ function ScatterPlotWidget({
xAxisFormatter={xAxisFormatter}
yAxisFormatter={yAxisFormatter}
animation={animation}
isLoading={isLoading}
/>
)}
</WidgetWithAlert>
Expand Down

0 comments on commit 6aedc01

Please sign in to comment.