File size: 3,050 Bytes
f36a767 d684338 f36a767 d684338 f36a767 d684338 f36a767 9efd53f d684338 f36a767 d684338 f36a767 d684338 f36a767 d684338 9efd53f f36a767 d684338 f36a767 983d047 f36a767 983d047 f36a767 9efd53f f36a767 9efd53f f36a767 9efd53f f36a767 9efd53f f36a767 d684338 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
import { TaskExecutorHeartbeatItem } from '@/interfaces/database/user-setting';
import { Divider, Flex } from 'antd';
import {
Bar,
BarChart,
CartesianGrid,
Legend,
Rectangle,
ResponsiveContainer,
Tooltip,
XAxis,
} from 'recharts';
import { formatDate, formatTime } from '@/utils/date';
import dayjs from 'dayjs';
import { get } from 'lodash';
import JsonView from 'react18-json-view';
import 'react18-json-view/src/style.css';
import styles from './index.less';
interface IProps {
data: Record<string, TaskExecutorHeartbeatItem[]>;
}
const CustomTooltip = ({ active, payload, ...restProps }: any) => {
if (active && payload && payload.length) {
const taskExecutorHeartbeatItem: TaskExecutorHeartbeatItem = get(
payload,
'0.payload',
{},
);
return (
<div className="custom-tooltip">
<div className="bg-slate-50 p-2 rounded-md border border-indigo-100">
<div className="font-semibold text-lg">
{formatDate(restProps.label)}
</div>
<JsonView
src={taskExecutorHeartbeatItem}
displaySize={30}
className="w-full max-h-[300px] break-words overflow-auto"
/>
</div>
</div>
);
}
return null;
};
const TaskBarChat = ({ data }: IProps) => {
return Object.entries(data).map(([key, val]) => {
const data = val.map((x) => ({
...x,
now: dayjs(x.now).valueOf(),
}));
const firstItem = data[0];
const lastItem = data[data.length - 1];
const domain = [firstItem?.now, lastItem?.now];
return (
<Flex key={key} className={styles.taskBar} vertical>
<div className="flex gap-8">
<b className={styles.taskBarTitle}>ID: {key}</b>
<b className={styles.taskBarTitle}>Lag: {lastItem?.lag}</b>
<b className={styles.taskBarTitle}>Pending: {lastItem?.pending}</b>
</div>
<ResponsiveContainer>
<BarChart data={data}>
<XAxis
dataKey="now"
type="number"
scale={'time'}
domain={domain}
tickFormatter={(x) => formatTime(x)}
allowDataOverflow
angle={60}
padding={{ left: 20, right: 20 }}
tickMargin={20}
/>
<CartesianGrid strokeDasharray="3 3" />
<Tooltip
wrapperStyle={{ pointerEvents: 'auto' }}
content={<CustomTooltip></CustomTooltip>}
trigger="click"
/>
<Legend wrapperStyle={{ bottom: -22 }} />
<Bar
dataKey="done"
fill="#2fe235"
activeBar={<Rectangle fill="pink" stroke="blue" />}
/>
<Bar
dataKey="failed"
fill="#ef3b74"
activeBar={<Rectangle fill="gold" stroke="purple" />}
/>
</BarChart>
</ResponsiveContainer>
<Divider></Divider>
</Flex>
);
});
};
export default TaskBarChat;
|