Files
collection-portal/src/components/leaderboard/PerformanceChart.tsx
Aman Singh a7b475d190 TP-31863 |performance level dynamic| Aman Singh (#466)
* TP-31863 | initial commit | Aman Singh

* TP-0000 | Level icon with level number within it and color as prop | Herik

* TP-31863 | second commit | Aman Singh

* TP-0000 | Level icon implemented in the list with colors | Herik

* TP-31863 | third commit | Aman Singh

* TP-31863 | forth commit | Aman Singh

* TP-31863 | integration done | Aman Singh

* TP-31863 | design review done | Aman Singh

* TP-31863 | design review done -1 | Aman Singh

* TP-31863 | EM review done| Aman Singh

* TP-31863 | EM review done -1| Aman Singh

* TP-31863 | EM review done| Aman Singh

* TP-0000 | maxLevel after UAT | Herik

* TP-31863 |removed tooltip sachin suggestion| Aman Singh

Co-authored-by: Herik Modi <herik.modi@navi.com>
2023-07-05 20:46:16 +05:30

172 lines
5.0 KiB
TypeScript

import React from 'react';
import {
CartesianGrid,
Legend,
Line,
LineChart,
Tooltip,
TooltipProps,
XAxis,
YAxis
} from 'recharts';
import { NameType, ValueType } from 'recharts/types/component/DefaultTooltipContent';
import { IPerformance } from 'src/reducers/leaderboardSlice';
import { dateFormat, getWeekDay } from 'src/utils/DateHelper';
import { LEVEL_ICONS } from './Leaderboard';
import styles from './Leaderboard.module.scss';
import cx from 'classnames';
import { tickFormatterHandler } from 'src/utils/Chart.utils';
import { LevelIcon } from 'src/assets/icons/LevelIcon';
import { levelColorsList } from '../AgentprogressMeter/constant';
import { useSelector } from 'react-redux';
import { RootState } from 'src/store';
export enum formatYAxisTypes {
COMPACT_FORMATTED_AMOUNT
}
interface IPerformanceChart {
data: IPerformance;
width?: number;
height?: number;
legendWrapperStyle?: React.CSSProperties;
graphWrapperContainerClass?: string;
isWeekData?: boolean;
}
const axisFontStyle = { fontFamily: 'Inter', fontWeight: '400', fontSize: '12px', fill: '#1c1c1c' };
const formatYAxisValues = (value: number): string => `L${value}`;
const PerformanceChart: React.FC<IPerformanceChart> = props => {
const {
data,
width = 350,
height = 150,
legendWrapperStyle,
graphWrapperContainerClass = '',
isWeekData = false
} = props;
const maxPerformance = useSelector((state: RootState) => state.leaderboard.maxLevel);
const newData = data?.data?.map(item => ({
...item,
level: Number(item?.level?.replace('L', ''))
}));
const yAxisLevels = [];
for (let i = 1; i <= maxPerformance; i++) {
yAxisLevels.push(i);
}
if (!newData) {
return <div className={styles.dataNotFound}>Data Not Available</div>;
}
return (
<div className={cx(styles.graphWrapper, graphWrapperContainerClass)}>
<LineChart className={styles.lineChart} width={width} height={height} data={newData}>
<defs>
<linearGradient id="colorPerf" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" stopColor="#5EC60C" />
<stop offset="100%" stopColor="#ED5736" />
</linearGradient>
</defs>
<CartesianGrid opacity={0.5} verticalPoints={[0]} />
<XAxis
ticks={data.xaxisDomainValues}
tick={{ ...axisFontStyle, fontSize: '12px' }}
dataKey="xaxis"
tickLine={true}
padding={'no-gap'}
minTickGap={0}
interval={0}
dx={isWeekData ? -5 : -15}
dy={5}
tickFormatter={date => tickFormatterHandler(date, isWeekData)}
/>
<Legend
wrapperStyle={{ ...axisFontStyle, top: -10, ...legendWrapperStyle }}
iconSize={5}
iconType="circle"
layout="horizontal"
verticalAlign="top"
align="right"
className={styles.legends}
content={<RenderCustomizedLegend hasChanges={data.hasLevelChanged} />}
/>
<Tooltip wrapperStyle={{ outline: 'none' }} content={<CustomTooltip />} />
<YAxis
ticks={yAxisLevels}
axisLine={false}
tickLine={false}
tick={axisFontStyle}
tickFormatter={formatYAxisValues}
interval={0}
domain={['auto', 'auto']}
scale={'time'}
/>
<Line
isAnimationActive={false}
stroke={data.hasLevelChanged ? 'url(#colorPerf)' : '#5EC60C'}
strokeWidth={2}
dot={false}
dataKey="level"
/>
</LineChart>
</div>
);
};
export default PerformanceChart;
const CustomTooltip: React.FC<TooltipProps<ValueType, NameType>> = ({ active, payload, label }) => {
if (active && payload && payload.length) {
if (!payload?.[0].value) return null;
return (
<div
style={{
height: 'fit-content',
border: '#E8E8E8',
background: '#ffffff',
borderRadius: 4,
padding: 4,
boxShadow:
' 0px 1px 3px rgba(0, 0, 0, 0.1), 0px 2px 1px rgba(0, 0, 0, 0.06), 0px 1px 1px rgba(0, 0, 0, 0.08)'
}}
>
<p className={styles.perfLevel}>
<span>Perf Level</span>{' '}
<LevelIcon
level={payload[0].value as number}
color={levelColorsList[(payload[0].value as number) - 1]}
/>
{/* {LEVEL_ICONS[(payload[0].value as number) - 1]} */}
</p>
<p className={styles.date}>{`${dateFormat(new Date(label), 'DD MMM')}`}</p>
</div>
);
}
return null;
};
const RenderCustomizedLegend: React.FC<{ hasChanges: boolean }> = ({ hasChanges }) => {
if (hasChanges) {
return (
<div className={styles.performanceLegend}>
<div className={styles.legendContainer}>
<div className={styles.goingDown} />
<span>Going Down</span>
</div>
<div className={styles.legendContainer}>
<div className={styles.goingUp} />
<span>Going Up</span>
</div>
</div>
);
}
return null;
};