chore: dashboard load optimization

This commit is contained in:
jialin
2024-07-05 18:51:13 +08:00
parent e9d8828dcd
commit 8c66c482b2
10 changed files with 238 additions and 227 deletions
+1
View File
@@ -65,6 +65,7 @@ const BarChart: React.FC<ChartProps> = (props) => {
});
const optionsConfig = {
...options,
animation: false,
title: {
...titleConfig,
text: title
+1
View File
@@ -64,6 +64,7 @@ const BarChart: React.FC<ChartProps> = (props) => {
});
const optionsConfig = {
...options,
animation: false,
title: {
...options.title,
left: 'start',
+7 -7
View File
@@ -9,7 +9,7 @@ import {
yAxis
} from '@/components/echarts/config';
import _ from 'lodash';
import { useEffect, useState } from 'react';
import { memo } from 'react';
import { ChartProps } from './types';
const LineChart: React.FC<ChartProps> = (props) => {
@@ -23,7 +23,6 @@ const LineChart: React.FC<ChartProps> = (props) => {
smooth,
title
} = props;
const [dataOptions, setDataOptions] = useState({});
const options = {
title: {
@@ -49,7 +48,7 @@ const LineChart: React.FC<ChartProps> = (props) => {
series: []
};
useEffect(() => {
const generateOptions = (): any => {
const data = _.map(seriesData, (item: any) => {
return {
...item,
@@ -67,6 +66,7 @@ const LineChart: React.FC<ChartProps> = (props) => {
});
const optionsConfig = {
...options,
animation: false,
title: {
...titleConfig,
text: title
@@ -80,9 +80,9 @@ const LineChart: React.FC<ChartProps> = (props) => {
},
series: data
};
console.log('optionsConfig========line=', optionsConfig);
setDataOptions(optionsConfig);
}, [seriesData, xAxisData, title]);
return optionsConfig;
};
const dataOptions = generateOptions();
return (
<Chart
height={height}
@@ -92,4 +92,4 @@ const LineChart: React.FC<ChartProps> = (props) => {
);
};
export default LineChart;
export default memo(LineChart);
+1 -1
View File
@@ -12,6 +12,6 @@
}
.ant-progress.ant-progress-circle .ant-progress-text {
font-size: 24px;
font-size: 20px;
}
}
+1 -1
View File
@@ -18,7 +18,7 @@ const UitilBar: React.FC<UitilBarProps> = (props) => {
gapDegree = 170,
strokeWidth = 10,
title,
size = 160,
size = 150,
strokeColor,
trailColor = 'rgba(221,221,221,.5)'
} = props;
+4
View File
@@ -261,6 +261,10 @@ body {
background-color: var(--color-fill-1);
height: 100%;
.ant-pro-sider-logo {
padding-left: 20px;
}
.ant-pro-sider .ant-layout-sider-children {
background-color: var(--color-fill-sider);
// box-shadow: var(--box-shadow-base);
+11 -8
View File
@@ -39,23 +39,26 @@ export default function useWindowResize() {
setIsDesktop(true);
setCurrentPoint('xl');
}, []);
const handleResize = _.throttle(() => {
setSize({
width: window.innerWidth,
height: window.innerHeight
});
}, 200);
const handleResize = useCallback(
_.throttle(() => {
setSize({
width: window.innerWidth,
height: window.innerHeight
});
}, 200),
[]
);
useEffect(() => {
window.addEventListener('resize', handleResize);
return () => {
window.removeEventListener('resize', handleResize);
};
}, []);
}, [handleResize]);
useEffect(() => {
checkBreakpoint(size.width);
}, [size.width]);
}, [size.width, checkBreakpoint]);
return { size, isMobile, isTablet, isDesktop, currentPoint };
}
@@ -2,7 +2,7 @@ import Chart from '@/components/echarts/chart';
import { getLocale, useIntl } from '@umijs/max';
import dayjs from 'dayjs';
import _ from 'lodash';
import { useContext } from 'react';
import { memo, useContext } from 'react';
import { DashboardContext } from '../config/dashboard-context';
const chartColorMap = {
@@ -114,15 +114,10 @@ const UtilizationOvertime: React.FC = () => {
const intl = useIntl();
const locale = getLocale();
let dataOptions: any = {};
// const [dataOptions, setDataOptions] = useState<any>(option);
const data = useContext(DashboardContext)?.system_load?.history || {};
const typeList = ['gpu', 'cpu', 'memory', 'gpu_memory'];
const labelFormatter = (value: any) => {
return `${value}%`;
};
const generateData = () => {
const legendData: string[] = [];
const xAxisData: string[] = [];
@@ -130,7 +125,6 @@ const UtilizationOvertime: React.FC = () => {
list = _.map(typeList, (item: string) => {
const itemConfig = _.get(TypeKeyMap, item, {});
console.log('itemConfig', itemConfig);
const name = itemConfig.intl
? intl.formatMessage({ id: itemConfig.label })
: itemConfig.label;
@@ -161,6 +155,7 @@ const UtilizationOvertime: React.FC = () => {
dataOptions = {
...option,
animation: false,
legend: {
...option.legend,
data: legendData
@@ -173,9 +168,6 @@ const UtilizationOvertime: React.FC = () => {
};
};
generateData();
// useEffect(() => {
// generateData();
// }, [data, locale]);
return (
<>
@@ -184,4 +176,4 @@ const UtilizationOvertime: React.FC = () => {
);
};
export default UtilizationOvertime;
export default memo(UtilizationOvertime);
@@ -0,0 +1,201 @@
import PageTools from '@/components/page-tools';
import { useIntl } from '@umijs/max';
import { Col, DatePicker, Row } from 'antd';
import dayjs from 'dayjs';
import _ from 'lodash';
import { memo, useCallback, useContext } from 'react';
import { DashboardContext } from '../../config/dashboard-context';
import RequestTokenInner from './request-token-inner';
import TopUser from './top-user';
const baseColorMap = {
baseL2: 'rgba(13,171,219,0.8)',
baseL1: 'rgba(0,34,255,0.8)',
base: 'rgba(0,85,255,0.8)',
baseR1: 'rgba(0,255,233,0.8)',
baseR2: 'rgba(48,0,255,0.8)',
baseR3: 'rgba(85,167,255,0.8)'
};
const getCurrentMonthDays = () => {
const now = dayjs();
const daysInMonth = now.daysInMonth();
const year = dayjs().year();
const month = dayjs().month() + 1;
const dates = [];
for (let day = 1; day <= daysInMonth; day++) {
dates.push(dayjs(`${year}-${month}-${day}`).format('YYYY-MM-DD'));
}
return dates;
};
const UsageInner: React.FC<{ paddingRight: string }> = ({ paddingRight }) => {
const intl = useIntl();
const currentDate = dayjs();
const currentMonthDays = getCurrentMonthDays();
let requestData: {
name: string;
color: string;
areaStyle: any;
data: { time: string; value: number }[];
}[] = [];
let tokenData: { time: string; value: number }[] = [];
let userData: { name: string; value: number }[] = [];
const xAxisData: string[] = currentMonthDays;
let topUserList: string[] = [];
const { model_usage } = useContext(DashboardContext);
const data = model_usage || {};
const handleSelectDate = (date: any) => {
// fetchData?.();
};
const generateData = useCallback(() => {
const requestList: {
name: string;
color: string;
areaStyle: any;
data: { time: string; value: number }[];
} = {
name: 'API requests',
areaStyle: {},
color: baseColorMap.base,
data: []
};
const completionData: any = {
name: 'Completion tokens',
color: baseColorMap.base,
data: []
};
const prompData: any = {
name: 'Prompt tokens',
color: baseColorMap.baseR3,
data: []
};
const topUserPrompt: any = {
name: 'Prompt tokens',
color: baseColorMap.baseR3,
data: []
};
const topUserCompletion: any = {
name: 'Completion tokens',
color: baseColorMap.base,
data: []
};
const users: string[] = [];
_.each(xAxisData, (date: string) => {
// tokens data
const item = _.find(data.completion_token_history, (item: any) => {
return dayjs(item.timestamp * 1000).format('YYYY-MM-DD') === date;
});
if (!item) {
completionData.data.push({
titme: date,
value: 0
});
} else {
completionData.data.push({
value: item.value,
time: dayjs(item.timestamp * 1000).format('YYYY-MM-DD')
});
}
const promptItem = _.find(data.prompt_token_history, (item: any) => {
return dayjs(item.timestamp * 1000).format('YYYY-MM-DD') === date;
});
if (!promptItem) {
prompData.data.push({
value: 0,
time: date
});
} else {
prompData.data.push({
value: promptItem.value,
time: dayjs(promptItem.timestamp * 1000).format('YYYY-MM-DD')
});
}
// ============== api request data =================
const requestItem = _.find(data.api_request_history, (item: any) => {
return dayjs(item.timestamp * 1000).format('YYYY-MM-DD') === date;
});
if (!requestItem) {
requestList.data.push({
time: date,
value: 0
});
} else {
requestList.data.push({
time: dayjs(requestItem.timestamp * 1000).format('YYYY-MM-DD'),
value: requestItem.value
});
}
});
// ========== top users ============
_.each(data.top_users, (item: any) => {
users.push(item.username);
topUserPrompt.data.push({
name: item.username,
value: item.prompt_token_count
});
topUserCompletion.data.push({
name: item.username,
value: item.completion_token_count
});
});
requestData = [requestList];
userData = [topUserCompletion, topUserPrompt];
topUserList = users;
tokenData = [completionData, prompData];
}, [data, xAxisData]);
generateData();
return (
<>
<PageTools
style={{ margin: '26px 0px' }}
left={<span>{intl.formatMessage({ id: 'dashboard.usage' })}</span>}
right={
<DatePicker
onChange={handleSelectDate}
style={{ width: 300 }}
picker="month"
defaultValue={currentDate}
/>
}
/>
<Row style={{ width: '100%' }} gutter={[0, 20]}>
<Col
xs={24}
sm={24}
md={24}
lg={24}
xl={16}
style={{ paddingRight: paddingRight }}
>
<RequestTokenInner
requestData={requestData}
xAxisData={xAxisData}
tokenData={tokenData}
></RequestTokenInner>
</Col>
<Col xs={24} sm={24} md={24} lg={24} xl={8}>
<TopUser userData={userData} topUserList={topUserList}></TopUser>
</Col>
</Row>
</>
);
};
export default memo(UsageInner);
+8 -199
View File
@@ -1,214 +1,23 @@
import PageTools from '@/components/page-tools';
import breakpoints from '@/config/breakpoints';
import useWindowResize from '@/hooks/use-window-resize';
import { useIntl } from '@umijs/max';
import { Col, DatePicker, Row } from 'antd';
import dayjs from 'dayjs';
import _ from 'lodash';
import { useContext, useEffect, useState } from 'react';
import { DashboardContext } from '../config/dashboard-context';
import RequestTokenInner from './usage-inner/request-token-inner';
import TopUser from './usage-inner/top-user';
const baseColorMap = {
baseL2: 'rgba(13,171,219,0.8)',
baseL1: 'rgba(0,34,255,0.8)',
base: 'rgba(0,85,255,0.8)',
baseR1: 'rgba(0,255,233,0.8)',
baseR2: 'rgba(48,0,255,0.8)',
baseR3: 'rgba(85,167,255,0.8)'
};
const getCurrentMonthDays = () => {
const now = dayjs();
const daysInMonth = now.daysInMonth();
const year = dayjs().year();
const month = dayjs().month() + 1;
const dates = [];
for (let day = 1; day <= daysInMonth; day++) {
dates.push(dayjs(`${year}-${month}-${day}`).format('YYYY-MM-DD'));
}
return dates;
};
import { useEffect, useState } from 'react';
import UserInner from './usage-inner';
const Usage = () => {
const intl = useIntl();
const { size } = useWindowResize();
const {
size: { width }
} = useWindowResize();
const [paddingRight, setPaddingRight] = useState<string>('20px');
console.log('usage========');
const currentDate = dayjs();
const currentMonthDays = getCurrentMonthDays();
let requestData: {
name: string;
color: string;
areaStyle: any;
data: { time: string; value: number }[];
}[] = [];
let tokenData: { time: string; value: number }[] = [];
let userData: { name: string; value: number }[] = [];
const xAxisData: string[] = currentMonthDays;
let topUserList: string[] = [];
const { model_usage, fetchData } = useContext(DashboardContext);
const data = model_usage || {};
const handleSelectDate = (date: any) => {
// fetchData?.();
};
const generateData = () => {
const requestList: {
name: string;
color: string;
areaStyle: any;
data: { time: string; value: number }[];
} = {
name: 'API requests',
areaStyle: {},
color: baseColorMap.base,
data: []
};
const completionData: any = {
name: 'Completion tokens',
color: baseColorMap.base,
data: []
};
const prompData: any = {
name: 'Prompt tokens',
color: baseColorMap.baseR3,
data: []
};
const topUserPrompt: any = {
name: 'Prompt tokens',
color: baseColorMap.baseR3,
data: []
};
const topUserCompletion: any = {
name: 'Completion tokens',
color: baseColorMap.base,
data: []
};
const users: string[] = [];
_.each(xAxisData, (date: string) => {
// tokens data
const item = _.find(data.completion_token_history, (item: any) => {
return dayjs(item.timestamp * 1000).format('YYYY-MM-DD') === date;
});
if (!item) {
completionData.data.push({
titme: date,
value: 0
});
} else {
completionData.data.push({
value: item.value,
time: dayjs(item.timestamp * 1000).format('YYYY-MM-DD')
});
}
const promptItem = _.find(data.prompt_token_history, (item: any) => {
return dayjs(item.timestamp * 1000).format('YYYY-MM-DD') === date;
});
if (!promptItem) {
prompData.data.push({
value: 0,
time: date
});
} else {
prompData.data.push({
value: promptItem.value,
time: dayjs(promptItem.timestamp * 1000).format('YYYY-MM-DD')
});
}
// ============== api request data =================
const requestItem = _.find(data.api_request_history, (item: any) => {
return dayjs(item.timestamp * 1000).format('YYYY-MM-DD') === date;
});
if (!requestItem) {
requestList.data.push({
time: date,
value: 0
});
} else {
requestList.data.push({
time: dayjs(requestItem.timestamp * 1000).format('YYYY-MM-DD'),
value: requestItem.value
});
}
});
// ========== top users ============
_.each(data.top_users, (item: any) => {
users.push(item.username);
topUserPrompt.data.push({
name: item.username,
value: item.prompt_token_count
});
topUserCompletion.data.push({
name: item.username,
value: item.completion_token_count
});
});
requestData = [requestList];
userData = [topUserCompletion, topUserPrompt];
topUserList = users;
tokenData = [completionData, prompData];
};
useEffect(() => {
if (size.width < breakpoints.xl) {
if (width < breakpoints.xl) {
setPaddingRight('0');
} else {
setPaddingRight('20px');
}
}, [size.width]);
}, [width]);
generateData();
return (
<>
<PageTools
style={{ margin: '26px 0px' }}
left={<span>{intl.formatMessage({ id: 'dashboard.usage' })}</span>}
right={
<DatePicker
onChange={handleSelectDate}
style={{ width: 300 }}
picker="month"
defaultValue={currentDate}
/>
}
/>
<Row style={{ width: '100%' }} gutter={[0, 20]}>
<Col
xs={24}
sm={24}
md={24}
lg={24}
xl={16}
style={{ paddingRight: paddingRight }}
>
<RequestTokenInner
requestData={requestData}
xAxisData={xAxisData}
tokenData={tokenData}
></RequestTokenInner>
</Col>
<Col xs={24} sm={24} md={24} lg={24} xl={8}>
<TopUser userData={userData} topUserList={topUserList}></TopUser>
</Col>
</Row>
</>
);
return <UserInner paddingRight={paddingRight}></UserInner>;
};
export default Usage;