* 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>
172 lines
5.0 KiB
TypeScript
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;
|
|
};
|