import { Box } from '@mui/material'; import { scaleLinear } from '@visx/scale'; import { equals, gt, lt, T } from 'ramda'; import { useMemo, useRef } from 'react'; import { Tooltip } from '../../components'; import { useHeatMapStyles } from './HeatMap.styles'; import type { HeatMapProps } from './model'; const gap = 8; const maxTileSize = 120; const smallestTileSize = 44; const toleratedRangeWidth = 10; const ResponsiveHeatMap = ({ width, children, tiles, arrowClassName, tooltipContent, tileSizeFixed, displayTooltipCondition = T, height }: HeatMapProps & { height: number; width: number; }): JSX.Element | null => { const { classes, cx } = useHeatMapStyles(); const previousTileSize = useRef(0); const tileSize = useMemo(() => { const scaleWidth = scaleLinear({ clamp: true, domain: [680, 1056], range: [76, maxTileSize] }); const tileWidth = scaleWidth(width); const tilesLength = tiles.length; const maxTotalTilesWidth = tilesLength * maxTileSize + (tilesLength - 1) * gap; const theoricalTotalTilesWidth = tilesLength * tileWidth + (tilesLength - 1) * gap; const canUpdateTileSize = Math.abs(tileWidth - previousTileSize.current) > toleratedRangeWidth; if (!canUpdateTileSize) { return previousTileSize.current; } if ( (lt(height, maxTileSize) || (lt(width, 680) && gt(maxTotalTilesWidth, width))) && !tileSizeFixed ) { return smallestTileSize; } if (lt(theoricalTotalTilesWidth, width)) { return maxTileSize; } return tileSizeFixed ? maxTileSize : tileWidth; }, [width, tiles, height, tileSizeFixed]); const isSmallestSize = equals(tileSize, smallestTileSize); const isMediumSize = !isSmallestSize && lt(tileSize, 90); previousTileSize.current = tileSize; if (equals(width, 0)) { return null; } return ( {tiles.map(({ backgroundColor, id, data }) => (
{children({ backgroundColor, data, id, isMediumSize, isSmallestSize, tileSize })}
))}
); }; export default ResponsiveHeatMap;