import React, { memo, useCallback, useEffect, useState } from 'react'; import { Bar, BarChart, CartesianGrid, ResponsiveContainer, Tooltip, XAxis, YAxis } from 'recharts'; import type { Margin } from 'recharts/types/util/types'; import { useTheme } from '@mui/material/styles'; import { useTick, formatterData, setDomainCalc, fixChartsClasses } from '../../utils'; import type { ChartTooltipProps, ValueType, NameType } from '../../utils'; import type { Theme } from '../@styles/theme-provider'; import { CustomTooltip } from './CustomTooltip'; import type { CustomTooltipProps } from './CustomTooltip'; export interface ChartBarStackedProps { data: Record>>; tooltip?: boolean; tooltipProps?: Partial; height?: number; domainMax?: number; domainCalc?: boolean; tickCountY?: number; dataKeyX?: CustomTooltipProps['format']; dynamicNamedData?: { dataName: string; percentValue: string; value: string; }; chartMargin?: Margin; } const ChartBarStacked = (props: ChartBarStackedProps) => { const theme = useTheme(); const { data = {}, tooltip, tooltipProps, height, domainMax = 100, domainCalc = false, tickCountY, dataKeyX = 'name', dynamicNamedData = { dataName: 'appVersion', percentValue: 'percentage', value: 'count' }, chartMargin = { left: -24, right: 6 } } = props; const classes = fixChartsClasses(); const [uniqKeys, setUniqKeys] = useState([]); const [arrColorNew, setArrColorNew] = useState<{ color?: string; isLast: boolean }[]>([]); // to check colors output const [chartDataSet, setChartDataSet] = useState[]>( [] ); useEffect(() => { const sysNames = Object.keys(data); const tempChartData: Record[] = []; sysNames.forEach((item: string, ind) => { tempChartData.push({ name: item }); data[item].forEach(ver => { const title = `${item}_!${ver[dynamicNamedData.dataName]}`; tempChartData[ind][title] = ver[dynamicNamedData.percentValue]; }); }); const arr: string[] = []; const arrColor: string[] = []; tempChartData.forEach(bar => { const keys = Object.keys(bar); keys.splice(keys.indexOf('name'), 1); for (let i = 0; i < keys.length; i += 1) { const temp = i % 16; arrColor.push(theme.palette.specialColors[temp]); } arr.push(...keys); }); setUniqKeys(arr); const arrNew: { color?: string; isLast: boolean }[] = []; sysNames.forEach(item => { data[item].forEach((elem, index: number) => { arrNew.push({ color: theme.palette.specialColors[index + 1 < 16 ? index + 1 : (index % 16) + 1], isLast: data[item].length === index + 1 }); }); }); setArrColorNew(arrNew); arr.forEach(item => { const indices = []; const element = item; let idx = arr.indexOf(element); while (idx !== -1) { indices.push(idx); idx = arr.indexOf(element, idx + 1); } for (let i = 1; i < indices.length; i += 1) { arrColor.splice(indices[i], 1); } }); sysNames.forEach((item, ind) => { data[item].forEach(ver => { const title = `${item}_!${ver[dynamicNamedData.dataName]}`; tempChartData[ind][`${title}-count`] = ver[dynamicNamedData.value]; }); }); setChartDataSet(tempChartData); }, [data, dynamicNamedData, theme.palette.specialColors]); const horizontalTick = { fontSize: theme.typography.caption1.fontSize, fill: theme.palette.primary[600], fontFamily: 'Inter' }; const tick = useTick(); const formatter = useCallback((value: string) => formatterData(value, dataKeyX), [dataKeyX]); const setDomain = useCallback( (dataMax: number | undefined) => setDomainCalc(dataMax, domainCalc, domainMax), [domainMax, domainCalc] ); return ( {tooltip && ( } {...tooltipProps} /> )} {uniqKeys?.map((entry, index) => ( ))} ); }; ChartBarStacked.defaultProps = { data: [], tooltip: true, height: 325, dataKeyX: 'date', domainCalc: false, domainMax: 100, tickCountY: 10, dynamicNamedData: { dataName: 'appVersion', percentValue: 'percentage', value: 'count' } }; const m = memo(ChartBarStacked); export { m as ChartBarStacked };