77 lines
1.6 KiB
JavaScript
77 lines
1.6 KiB
JavaScript
|
import React, { useMemo } from "react";
|
||
|
import useHover from "./useHover";
|
||
|
import {
|
||
|
AspectRatio,
|
||
|
Box,
|
||
|
Button,
|
||
|
Heading,
|
||
|
HStack,
|
||
|
Icon,
|
||
|
Input,
|
||
|
Stat,
|
||
|
StatLabel,
|
||
|
StatNumber,
|
||
|
StatHelpText,
|
||
|
StatArrow,
|
||
|
StatGroup,
|
||
|
Tooltip,
|
||
|
} from "@chakra-ui/react";
|
||
|
import prettifyStatisticName from "./PrettifyStatisticName";
|
||
|
|
||
|
const randomColor = () =>
|
||
|
`hsl(${Math.floor(Math.random() * 359)}, ${
|
||
|
50 + Math.floor(Math.random() * 50)
|
||
|
}%, ${25 + Math.floor(Math.random() * 50)}%)`;
|
||
|
|
||
|
const StackedBarSegment = ({ aggregate, total }) => {
|
||
|
const color = useMemo(randomColor, []);
|
||
|
|
||
|
const [hoverRef, isHovered] = useHover();
|
||
|
|
||
|
return (
|
||
|
<Tooltip
|
||
|
hasArrow
|
||
|
label={`${aggregate.value
|
||
|
.toString()
|
||
|
.replace(
|
||
|
/\B(?<!\.\d*)(?=(\d{3})+(?!\d))/g,
|
||
|
","
|
||
|
)} ${prettifyStatisticName(aggregate.type, aggregate.name)}`}
|
||
|
>
|
||
|
<Box
|
||
|
width={aggregate.value / total}
|
||
|
height="100%"
|
||
|
filter={isHovered ? "clear" : "saturate(0.15)"}
|
||
|
backgroundColor={color}
|
||
|
ref={hoverRef}
|
||
|
></Box>
|
||
|
</Tooltip>
|
||
|
);
|
||
|
};
|
||
|
|
||
|
const StackedBar = ({ heading, aggregates }) => {
|
||
|
const total = aggregates.reduce((acc, val) => acc + val.value, 0);
|
||
|
|
||
|
return (
|
||
|
<>
|
||
|
<Heading size="xs" mt="4" fontWeight="medium">
|
||
|
{heading}
|
||
|
</Heading>
|
||
|
<HStack
|
||
|
width="100%"
|
||
|
height="8"
|
||
|
spacing="0"
|
||
|
rounded="md"
|
||
|
overflow="hidden"
|
||
|
mt="2"
|
||
|
>
|
||
|
{aggregates.map((x, i) => (
|
||
|
<StackedBarSegment key={i} aggregate={x} total={total} />
|
||
|
))}
|
||
|
</HStack>
|
||
|
</>
|
||
|
);
|
||
|
};
|
||
|
|
||
|
export default StackedBar;
|