TanStack / react-charts

⚛️ Simple, immersive & interactive charts for React
https://react-charts.tanstack.com
MIT License
3k stars 246 forks source link

Pure scrolling performance with react-charts #288

Open Karpengold opened 2 years ago

Karpengold commented 2 years ago

Hi, I'm using 2 charts on one page, after directing from this page to another page with the table I got performance issues with scrolling (it is not smooth). If I reload page, remove charts or redirect from other page without react-charts everything works fine. Unmounting event is being triggered during navigation between pages.

There is a chart component

const Chart: FC= ({ data }) => {
  const theme = useTheme();

  useEffect(() => {
    logger.log('mount chart');
    return () => {
      logger.log('unmount chart');
    };
  }, []);
  const memo = useMemo(() => [{ data }], [data]);
  const primaryAxis = useMemo<AxisTimeOptions<typeof data[number]>>(
    () => ({
      getValue: datum => datum.date,
      showGrid: false,
      formatters: {
        cursor: datum => datum?.toLocaleDateString(),
      },
      styles: {
        line: {
          display: 'none',
        },
        tick: {
          display: 'none',
        },
      },
    }),
    [],
  );

  const secondaryAxes = useMemo<AxisOptions<typeof data[number]>[]>(
    () => [
      {
        getValue: datum => datum.score,
        elementType: 'area',
        show: false,
      },
    ],
    [],
  );

  const renderSVG = useCallback(
    () => (
      <defs>
        <linearGradient
          id='linear-gradient'
          x1='0%'
          y1='0%'
          x2='0%'
          y2='100%'>
          <stop
            offset='0%'
            stopColor={
              theme.palette.mode === 'light'
                ? lighten(theme.palette.primary.main, 0.8)
                : lighten(theme.palette.primary.main, 0.2)
            }
          />
          <stop
            offset='100%'
            stopColor={theme.palette.background.paper + '22'}
          />
        </linearGradient>
      </defs>
    ),
    [
      theme.palette.background.paper,
      theme.palette.primary.main,
      theme.palette.mode,
    ],
  );

  const getSeriesStyle = useCallback(
    () => ({
      fill: 'url(#linear-gradient)',
      opacity: 1,
    }),
    [],
  );

  return (
    <Chart
      className={classes.orgChart}
      options={{
        defaultColors: [theme.palette.primary.main],
        padding: {
          top: 0,
          bottom: 0,
          left: 0,
          right: 0,
        },
        data: memo,
        primaryAxis,
        secondaryAxes,
        dark: theme.palette.mode === 'dark',
        tooltip: false,
        getSeriesStyle,
        renderSVG,
      }}
    />
  );
};
Karpengold commented 2 years ago

react-chart-portal component causes this issue. It helps but it would be nice to have some better solution

useEffect(() => {
    return () => {
      const portal = document.getElementById('react-charts-portal');
      portal && portal.parentNode?.removeChild(portal);
    };
  }, []);