chore: dashbord ui
This commit is contained in:
+6
-6
@@ -7,7 +7,7 @@ const DeleteCssPlugin = require('./plugins/delete-css-plugin');
|
|||||||
import proxy from './proxy';
|
import proxy from './proxy';
|
||||||
import routes from './routes';
|
import routes from './routes';
|
||||||
const env = process.env.NODE_ENV;
|
const env = process.env.NODE_ENV;
|
||||||
const isProduction = env === 'production';
|
const isProduction = env === 'production1';
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
proxy: {
|
proxy: {
|
||||||
@@ -48,11 +48,11 @@ export default defineConfig({
|
|||||||
ignoreOrder: true
|
ignoreOrder: true
|
||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
config.plugin('delete-css').use(DeleteCssPlugin, [
|
// config.plugin('delete-css').use(DeleteCssPlugin, [
|
||||||
{
|
// {
|
||||||
outputPath: path.resolve(__dirname, '../', 'dist')
|
// outputPath: path.resolve(__dirname, '../', 'dist')
|
||||||
}
|
// }
|
||||||
]);
|
// ]);
|
||||||
config.output
|
config.output
|
||||||
.filename('js/[name].[contenthash:8].js')
|
.filename('js/[name].[contenthash:8].js')
|
||||||
.chunkFilename('js/[name].[contenthash:8].chunk.js');
|
.chunkFilename('js/[name].[contenthash:8].chunk.js');
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ const BarChart: React.FC<BarChartProps> = (props) => {
|
|||||||
data,
|
data,
|
||||||
xField,
|
xField,
|
||||||
yField,
|
yField,
|
||||||
title,
|
|
||||||
// colorField: 'name',
|
// colorField: 'name',
|
||||||
direction: 'vertical',
|
direction: 'vertical',
|
||||||
height,
|
height,
|
||||||
@@ -31,7 +30,12 @@ const BarChart: React.FC<BarChartProps> = (props) => {
|
|||||||
xAxis: true
|
xAxis: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
title: {
|
||||||
|
title,
|
||||||
|
style: {
|
||||||
|
align: 'center'
|
||||||
|
}
|
||||||
|
},
|
||||||
split: {
|
split: {
|
||||||
type: 'line',
|
type: 'line',
|
||||||
line: {
|
line: {
|
||||||
@@ -44,7 +48,7 @@ const BarChart: React.FC<BarChartProps> = (props) => {
|
|||||||
},
|
},
|
||||||
|
|
||||||
style: {
|
style: {
|
||||||
fill: '#2fbf85',
|
fill: '#54cc98',
|
||||||
radiusTopLeft: 8,
|
radiusTopLeft: 8,
|
||||||
radiusTopRight: 8,
|
radiusTopRight: 8,
|
||||||
width: 30
|
width: 30
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
import { Gauge } from '@ant-design/plots';
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
interface GaugeChartProps {
|
||||||
|
target: number;
|
||||||
|
total: number;
|
||||||
|
width?: number;
|
||||||
|
height?: number;
|
||||||
|
title?: string;
|
||||||
|
thresholds: number[];
|
||||||
|
rangColor: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
const GaugeChart: React.FC<GaugeChartProps> = (props) => {
|
||||||
|
const { target, total, width, height, thresholds, rangColor, title } = props;
|
||||||
|
const config = {
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
autoFit: true,
|
||||||
|
data: {
|
||||||
|
target,
|
||||||
|
total,
|
||||||
|
name: 'score',
|
||||||
|
thresholds
|
||||||
|
},
|
||||||
|
legend: false,
|
||||||
|
scale: {
|
||||||
|
color: {
|
||||||
|
range: rangColor
|
||||||
|
}
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
titleFontSize: 14,
|
||||||
|
style: {
|
||||||
|
align: 'center'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
style: {
|
||||||
|
textContent: (target: number, total: number) => {
|
||||||
|
return `${(target / total) * 100}%`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return <Gauge {...config} />;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default GaugeChart;
|
||||||
@@ -13,7 +13,6 @@ const BarChart: React.FC<BarChartProps> = (props) => {
|
|||||||
data,
|
data,
|
||||||
xField,
|
xField,
|
||||||
yField,
|
yField,
|
||||||
title,
|
|
||||||
// colorField: 'name',
|
// colorField: 'name',
|
||||||
direction: 'vertical',
|
direction: 'vertical',
|
||||||
height,
|
height,
|
||||||
@@ -31,7 +30,12 @@ const BarChart: React.FC<BarChartProps> = (props) => {
|
|||||||
xAxis: true
|
xAxis: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
title: {
|
||||||
|
title,
|
||||||
|
style: {
|
||||||
|
align: 'center'
|
||||||
|
}
|
||||||
|
},
|
||||||
split: {
|
split: {
|
||||||
type: 'line',
|
type: 'line',
|
||||||
line: {
|
line: {
|
||||||
@@ -44,7 +48,7 @@ const BarChart: React.FC<BarChartProps> = (props) => {
|
|||||||
},
|
},
|
||||||
|
|
||||||
style: {
|
style: {
|
||||||
fill: '#2fbf85',
|
fill: '#54cc98',
|
||||||
radiusTopLeft: 8,
|
radiusTopLeft: 8,
|
||||||
radiusTopRight: 8,
|
radiusTopRight: 8,
|
||||||
height: 30
|
height: 30
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
import { Line } from '@ant-design/plots';
|
||||||
|
|
||||||
|
interface LineChartProps {
|
||||||
|
title?: string;
|
||||||
|
height?: number;
|
||||||
|
data: any[];
|
||||||
|
color?: string[];
|
||||||
|
xField?: string;
|
||||||
|
yField?: string;
|
||||||
|
slider?: boolean;
|
||||||
|
}
|
||||||
|
const LineChart: React.FC<LineChartProps> = (props) => {
|
||||||
|
const { data, title, color, xField, yField, slider, height } = props;
|
||||||
|
const config = {
|
||||||
|
title,
|
||||||
|
height,
|
||||||
|
xField: xField || 'time',
|
||||||
|
yField: yField || 'value',
|
||||||
|
color: color || ['red', 'blue', 'green'],
|
||||||
|
colorField: 'type',
|
||||||
|
autoFit: true,
|
||||||
|
slider,
|
||||||
|
shapeField: 'smooth',
|
||||||
|
axis: {
|
||||||
|
x: {
|
||||||
|
textStyle: {
|
||||||
|
autoRoate: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
point: {
|
||||||
|
shapeField: 'circle',
|
||||||
|
sizeField: 2
|
||||||
|
},
|
||||||
|
style: {
|
||||||
|
lineWidth: 1.5
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
itemMarker: {
|
||||||
|
symbol: 'circle'
|
||||||
|
},
|
||||||
|
color: {
|
||||||
|
layout: { justifyContent: 'center' }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
title: 'time',
|
||||||
|
items: [{ channel: 'y' }]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Line data={data} {...config} />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default LineChart;
|
||||||
@@ -26,6 +26,9 @@ html {
|
|||||||
--ant-table-row-selected-bg: #f0fff6;
|
--ant-table-row-selected-bg: #f0fff6;
|
||||||
--ant-table-row-selected-hover-bg: #d8f2e4;
|
--ant-table-row-selected-hover-bg: #d8f2e4;
|
||||||
--ant-table-row-hover-bg: #e6e6e6;
|
--ant-table-row-hover-bg: #e6e6e6;
|
||||||
|
--color-chart-red: #ff7875;
|
||||||
|
--color-chart-green: #54cc98;
|
||||||
|
--color-chart-glod: #ffd666;
|
||||||
// --color-text-1: #000;
|
// --color-text-1: #000;
|
||||||
|
|
||||||
--seal-transition-func: cubic-bezier(0, 0, 1, 1);
|
--seal-transition-func: cubic-bezier(0, 0, 1, 1);
|
||||||
|
|||||||
@@ -0,0 +1,161 @@
|
|||||||
|
import ContentWrapper from '@/components/content-wrapper';
|
||||||
|
import { Col, Row, Table } from 'antd';
|
||||||
|
|
||||||
|
const modelColumns = [
|
||||||
|
{
|
||||||
|
title: 'Name',
|
||||||
|
dataIndex: 'name',
|
||||||
|
key: 'name'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Allocated GPUs',
|
||||||
|
dataIndex: 'allocated',
|
||||||
|
key: 'allocated',
|
||||||
|
render: (text: any, record: any) => <span>{record.gpu.allocated}</span>
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'GPU Utilization',
|
||||||
|
dataIndex: 'utilization',
|
||||||
|
key: 'utilization',
|
||||||
|
render: (text: any, record: any) => <span>{record.gpu.utilization}</span>
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Running Instances',
|
||||||
|
dataIndex: 'running',
|
||||||
|
key: 'running',
|
||||||
|
render: (text: any, record: any) => <span>{record.instances.running}</span>
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Pending Instances',
|
||||||
|
dataIndex: 'pending',
|
||||||
|
key: 'pending',
|
||||||
|
render: (text: any, record: any) => <span>{record.instances.pending}</span>
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
const projectColumns = [
|
||||||
|
{
|
||||||
|
title: 'Name',
|
||||||
|
dataIndex: 'name',
|
||||||
|
key: 'name'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Token Quota',
|
||||||
|
dataIndex: 'quota',
|
||||||
|
key: 'quota'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Token Utilization',
|
||||||
|
dataIndex: 'utilization',
|
||||||
|
key: 'utilization'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Members',
|
||||||
|
dataIndex: 'members',
|
||||||
|
key: 'members'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
const modelData = [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
name: 'qwen2',
|
||||||
|
gpu: { allocated: 4, utilization: '50%' },
|
||||||
|
instances: { running: 1, pending: 0 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
name: 'llama3:70b',
|
||||||
|
gpu: { allocated: 3, utilization: '70%' },
|
||||||
|
instances: { running: 1, pending: 0 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
name: 'llama3',
|
||||||
|
gpu: { allocated: 5, utilization: '20%' },
|
||||||
|
instances: { running: 1, pending: 0 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 4,
|
||||||
|
name: 'gemma',
|
||||||
|
gpu: { allocated: 1, utilization: '25%' },
|
||||||
|
instances: { running: 1, pending: 0 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 5,
|
||||||
|
name: 'phi3',
|
||||||
|
gpu: { allocated: 2, utilization: '46%' },
|
||||||
|
instances: { running: 1, pending: 0 }
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
const projectData = [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
name: 'copilot-dev',
|
||||||
|
quota: 100,
|
||||||
|
utilization: 50,
|
||||||
|
members: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
name: 'rag-wiki',
|
||||||
|
quota: 200,
|
||||||
|
utilization: 70,
|
||||||
|
members: 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
name: 'smart-auto-agent',
|
||||||
|
quota: 100,
|
||||||
|
utilization: 20,
|
||||||
|
members: 5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 4,
|
||||||
|
name: 'office-auto-docs',
|
||||||
|
quota: 100,
|
||||||
|
utilization: 25,
|
||||||
|
members: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 5,
|
||||||
|
name: 'smart-customer-service',
|
||||||
|
quota: 100,
|
||||||
|
utilization: 46,
|
||||||
|
members: 2
|
||||||
|
}
|
||||||
|
];
|
||||||
|
const ActiveTable = () => {
|
||||||
|
return (
|
||||||
|
<Row>
|
||||||
|
<Col span={12}>
|
||||||
|
<ContentWrapper
|
||||||
|
contentStyle={{ paddingRight: 0 }}
|
||||||
|
title={<span style={{ lineHeight: '48px' }}>Active Models</span>}
|
||||||
|
>
|
||||||
|
<Table
|
||||||
|
columns={modelColumns}
|
||||||
|
dataSource={modelData}
|
||||||
|
pagination={false}
|
||||||
|
rowKey="id"
|
||||||
|
/>
|
||||||
|
</ContentWrapper>
|
||||||
|
</Col>
|
||||||
|
<Col span={12}>
|
||||||
|
<ContentWrapper
|
||||||
|
title={<span style={{ lineHeight: '48px' }}>Active Projects</span>}
|
||||||
|
>
|
||||||
|
<Table
|
||||||
|
columns={projectColumns}
|
||||||
|
dataSource={projectData}
|
||||||
|
pagination={false}
|
||||||
|
rowKey="id"
|
||||||
|
/>
|
||||||
|
</ContentWrapper>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ActiveTable;
|
||||||
+2
-43
@@ -1,6 +1,5 @@
|
|||||||
import PageTools from '@/components/page-tools';
|
import LineChart from '@/components/charts/line-chart';
|
||||||
import { generateRandomArray } from '@/utils';
|
import { generateRandomArray } from '@/utils';
|
||||||
import { Line } from '@ant-design/plots';
|
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
|
||||||
const mockData = {
|
const mockData = {
|
||||||
@@ -43,50 +42,10 @@ const UtilizationOvertime: React.FC = () => {
|
|||||||
};
|
};
|
||||||
const data = generateData();
|
const data = generateData();
|
||||||
|
|
||||||
const handleSelectDate = (date: string) => {
|
|
||||||
console.log('dateString============', date);
|
|
||||||
};
|
|
||||||
const config = {
|
|
||||||
// title: 'Resource Utilization',
|
|
||||||
xField: 'time',
|
|
||||||
yField: 'value',
|
|
||||||
color: ['red', 'blue', 'green'],
|
|
||||||
colorField: 'type',
|
|
||||||
autoFit: true,
|
|
||||||
slider: false,
|
|
||||||
shapeField: 'smooth',
|
|
||||||
axis: {
|
|
||||||
x: {
|
|
||||||
textStyle: {
|
|
||||||
autoRoate: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
point: {
|
|
||||||
shapeField: 'circle',
|
|
||||||
sizeField: 2
|
|
||||||
},
|
|
||||||
style: {
|
|
||||||
lineWidth: 1.4
|
|
||||||
},
|
|
||||||
legend: {
|
|
||||||
color: {
|
|
||||||
layout: { justifyContent: 'center' }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
tooltip: {
|
|
||||||
title: 'time',
|
|
||||||
items: [{ channel: 'y' }]
|
|
||||||
}
|
|
||||||
// label: {
|
|
||||||
// autoRotate: true
|
|
||||||
// }
|
|
||||||
};
|
|
||||||
// <DatePicker onChange={handleSelectDate} style={{ width: 300 }} />
|
// <DatePicker onChange={handleSelectDate} style={{ width: 300 }} />
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<PageTools marginBottom={10} marginTop={0} left={false} right={false} />
|
<LineChart height={400} data={data} />
|
||||||
<Line height={400} data={data} {...config} />
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
import GaugeChart from '@/components/charts/gauge';
|
||||||
|
import PageTools from '@/components/page-tools';
|
||||||
|
import { Col, DatePicker, Row } from 'antd';
|
||||||
|
import ResourceUtilization from './resource-utilization';
|
||||||
|
|
||||||
|
const SystemLoad = () => {
|
||||||
|
const handleSelectDate = (date: string) => {
|
||||||
|
console.log('dateString============', date);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="system-load">
|
||||||
|
<PageTools
|
||||||
|
marginBottom={10}
|
||||||
|
marginTop={0}
|
||||||
|
left={false}
|
||||||
|
right={
|
||||||
|
<DatePicker onChange={handleSelectDate} style={{ width: 300 }} />
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<ResourceUtilization />
|
||||||
|
<Row style={{ width: '100%' }}>
|
||||||
|
<Col span={6}>
|
||||||
|
<GaugeChart
|
||||||
|
title="GPU Compute Utilization"
|
||||||
|
total={100}
|
||||||
|
target={20}
|
||||||
|
// height={320}
|
||||||
|
thresholds={[50, 70, 100]}
|
||||||
|
rangColor={['#54cc98', '#ffd666', '#ff7875']}
|
||||||
|
></GaugeChart>
|
||||||
|
</Col>
|
||||||
|
<Col span={6}>
|
||||||
|
<GaugeChart
|
||||||
|
title="GPU Memory Utilization"
|
||||||
|
total={100}
|
||||||
|
target={30}
|
||||||
|
// height={320}
|
||||||
|
thresholds={[50, 70, 100]}
|
||||||
|
rangColor={['#54cc98', '#ffd666', '#ff7875']}
|
||||||
|
></GaugeChart>
|
||||||
|
</Col>
|
||||||
|
<Col span={6}>
|
||||||
|
<GaugeChart
|
||||||
|
title="CPU Compute Utilization"
|
||||||
|
total={100}
|
||||||
|
target={40}
|
||||||
|
// height={320}
|
||||||
|
thresholds={[50, 70, 100]}
|
||||||
|
rangColor={['#54cc98', '#ffd666', '#ff7875']}
|
||||||
|
></GaugeChart>
|
||||||
|
</Col>
|
||||||
|
<Col span={6}>
|
||||||
|
<GaugeChart
|
||||||
|
title="CPU Memory Utilization"
|
||||||
|
total={100}
|
||||||
|
target={70}
|
||||||
|
// height={320}
|
||||||
|
thresholds={[50, 70, 100]}
|
||||||
|
rangColor={['#54cc98', '#ffd666', '#ff7875']}
|
||||||
|
></GaugeChart>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SystemLoad;
|
||||||
@@ -0,0 +1,156 @@
|
|||||||
|
import ColumnBar from '@/components/charts/column-bar';
|
||||||
|
import HBar from '@/components/charts/h-bar';
|
||||||
|
import PageTools from '@/components/page-tools';
|
||||||
|
import { generateRandomArray } from '@/utils';
|
||||||
|
import { PageContainer } from '@ant-design/pro-components';
|
||||||
|
import { Col, DatePicker, Row } from 'antd';
|
||||||
|
|
||||||
|
const times = [
|
||||||
|
'june 1',
|
||||||
|
'june 2',
|
||||||
|
'june 3',
|
||||||
|
'june 4',
|
||||||
|
'june 5',
|
||||||
|
'june 6',
|
||||||
|
'june 7'
|
||||||
|
];
|
||||||
|
|
||||||
|
const users = ['Jim', 'Lucy', 'Lily', 'Tom', 'Jack', 'Rose', 'Jerry'];
|
||||||
|
const projects = [
|
||||||
|
'copilot-dev',
|
||||||
|
'rag-wiki',
|
||||||
|
'smart-auto-agent',
|
||||||
|
'office-auto-docs',
|
||||||
|
'smart-customer-service'
|
||||||
|
];
|
||||||
|
|
||||||
|
const APIRequestData = generateRandomArray({
|
||||||
|
length: times.length,
|
||||||
|
max: 100,
|
||||||
|
min: 0,
|
||||||
|
offset: 10
|
||||||
|
});
|
||||||
|
|
||||||
|
const TokensData = generateRandomArray({
|
||||||
|
length: times.length,
|
||||||
|
max: 2000,
|
||||||
|
min: 200,
|
||||||
|
offset: 200
|
||||||
|
});
|
||||||
|
|
||||||
|
const usersData = generateRandomArray({
|
||||||
|
length: users.length,
|
||||||
|
max: 100,
|
||||||
|
min: 0,
|
||||||
|
offset: 10
|
||||||
|
});
|
||||||
|
|
||||||
|
const projectsData = generateRandomArray({
|
||||||
|
length: projects.length,
|
||||||
|
max: 100,
|
||||||
|
min: 0,
|
||||||
|
offset: 10
|
||||||
|
});
|
||||||
|
|
||||||
|
const userDataList = usersData
|
||||||
|
.map((val, i) => {
|
||||||
|
return {
|
||||||
|
time: users[i],
|
||||||
|
value: val
|
||||||
|
};
|
||||||
|
})
|
||||||
|
.sort((a, b) => b.value - a.value);
|
||||||
|
|
||||||
|
const projectDataList = projectsData
|
||||||
|
.map((val, i) => {
|
||||||
|
return {
|
||||||
|
time: projects[i],
|
||||||
|
value: val
|
||||||
|
};
|
||||||
|
})
|
||||||
|
.sort((a, b) => b.value - a.value);
|
||||||
|
|
||||||
|
const dataList = APIRequestData.map((val, i) => {
|
||||||
|
console.log('val', val);
|
||||||
|
return {
|
||||||
|
time: times[i],
|
||||||
|
value: val
|
||||||
|
};
|
||||||
|
});
|
||||||
|
const tokenUsage = TokensData.map((val, i) => {
|
||||||
|
console.log('val', val);
|
||||||
|
return {
|
||||||
|
time: times[i],
|
||||||
|
value: val
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const Usage = () => {
|
||||||
|
const handleSelectDate = (dateString: string) => {
|
||||||
|
console.log('dateString============', dateString);
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<PageContainer ghost title="Usage">
|
||||||
|
<PageTools
|
||||||
|
marginBottom={10}
|
||||||
|
marginTop={0}
|
||||||
|
left={false}
|
||||||
|
right={
|
||||||
|
<DatePicker onChange={handleSelectDate} style={{ width: 300 }} />
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</PageContainer>
|
||||||
|
<Row style={{ width: '100%' }}>
|
||||||
|
<Col span={12}>
|
||||||
|
<PageContainer title={false}>
|
||||||
|
<ColumnBar
|
||||||
|
title="API Request"
|
||||||
|
data={dataList}
|
||||||
|
xField="time"
|
||||||
|
yField="value"
|
||||||
|
height={360}
|
||||||
|
></ColumnBar>
|
||||||
|
</PageContainer>
|
||||||
|
</Col>
|
||||||
|
<Col span={12}>
|
||||||
|
<PageContainer title={false}>
|
||||||
|
<ColumnBar
|
||||||
|
title="Tokens"
|
||||||
|
data={tokenUsage}
|
||||||
|
xField="time"
|
||||||
|
yField="value"
|
||||||
|
height={360}
|
||||||
|
></ColumnBar>
|
||||||
|
</PageContainer>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Row style={{ width: '100%' }}>
|
||||||
|
<Col span={12}>
|
||||||
|
<PageContainer title={false}>
|
||||||
|
<HBar
|
||||||
|
title="Top Users"
|
||||||
|
data={userDataList}
|
||||||
|
xField="time"
|
||||||
|
yField="value"
|
||||||
|
height={360}
|
||||||
|
></HBar>
|
||||||
|
</PageContainer>
|
||||||
|
</Col>
|
||||||
|
<Col span={12}>
|
||||||
|
<PageContainer title={false}>
|
||||||
|
<HBar
|
||||||
|
title="Top Projects"
|
||||||
|
data={projectDataList}
|
||||||
|
xField="time"
|
||||||
|
yField="value"
|
||||||
|
height={360}
|
||||||
|
></HBar>
|
||||||
|
</PageContainer>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Usage;
|
||||||
@@ -1,94 +1,10 @@
|
|||||||
import BarChart from '@/components/bar-chart';
|
|
||||||
import HBar from '@/components/bar-chart/h-bar';
|
|
||||||
import ContentWrapper from '@/components/content-wrapper';
|
|
||||||
import DividerLine from '@/components/divider-line';
|
import DividerLine from '@/components/divider-line';
|
||||||
import PageTools from '@/components/page-tools';
|
|
||||||
import { generateRandomArray } from '@/utils';
|
|
||||||
import { PageContainer } from '@ant-design/pro-components';
|
import { PageContainer } from '@ant-design/pro-components';
|
||||||
import { Col, Row } from 'antd';
|
import ActiveTable from './components/active-table';
|
||||||
import GPUUtilization from './components/gpu-utilization';
|
|
||||||
import Overview from './components/over-view';
|
import Overview from './components/over-view';
|
||||||
import UtilizationOvertime from './components/utilization-overtime';
|
import SystemLoad from './components/system-load';
|
||||||
|
import Usage from './components/usage';
|
||||||
|
|
||||||
const times = [
|
|
||||||
'june 1',
|
|
||||||
'june 2',
|
|
||||||
'june 3',
|
|
||||||
'june 4',
|
|
||||||
'june 5',
|
|
||||||
'june 6',
|
|
||||||
'june 7'
|
|
||||||
];
|
|
||||||
|
|
||||||
const users = ['Jim', 'Lucy', 'Lily', 'Tom', 'Jack', 'Rose', 'Jerry'];
|
|
||||||
const projects = [
|
|
||||||
'copilot-dev',
|
|
||||||
'rag-wiki',
|
|
||||||
'smart-auto-agent',
|
|
||||||
'office-auto-docs',
|
|
||||||
'smart-customer-service'
|
|
||||||
];
|
|
||||||
|
|
||||||
const APIRequestData = generateRandomArray({
|
|
||||||
length: times.length,
|
|
||||||
max: 100,
|
|
||||||
min: 0,
|
|
||||||
offset: 10
|
|
||||||
});
|
|
||||||
|
|
||||||
const TokensData = generateRandomArray({
|
|
||||||
length: times.length,
|
|
||||||
max: 2000,
|
|
||||||
min: 200,
|
|
||||||
offset: 200
|
|
||||||
});
|
|
||||||
|
|
||||||
const usersData = generateRandomArray({
|
|
||||||
length: users.length,
|
|
||||||
max: 100,
|
|
||||||
min: 0,
|
|
||||||
offset: 10
|
|
||||||
});
|
|
||||||
|
|
||||||
const projectsData = generateRandomArray({
|
|
||||||
length: projects.length,
|
|
||||||
max: 100,
|
|
||||||
min: 0,
|
|
||||||
offset: 10
|
|
||||||
});
|
|
||||||
|
|
||||||
const userDataList = usersData
|
|
||||||
.map((val, i) => {
|
|
||||||
return {
|
|
||||||
time: users[i],
|
|
||||||
value: val
|
|
||||||
};
|
|
||||||
})
|
|
||||||
.sort((a, b) => b.value - a.value);
|
|
||||||
|
|
||||||
const projectDataList = projectsData
|
|
||||||
.map((val, i) => {
|
|
||||||
return {
|
|
||||||
time: projects[i],
|
|
||||||
value: val
|
|
||||||
};
|
|
||||||
})
|
|
||||||
.sort((a, b) => b.value - a.value);
|
|
||||||
|
|
||||||
const dataList = APIRequestData.map((val, i) => {
|
|
||||||
console.log('val', val);
|
|
||||||
return {
|
|
||||||
time: times[i],
|
|
||||||
value: val
|
|
||||||
};
|
|
||||||
});
|
|
||||||
const tokenUsage = TokensData.map((val, i) => {
|
|
||||||
console.log('val', val);
|
|
||||||
return {
|
|
||||||
time: times[i],
|
|
||||||
value: val
|
|
||||||
};
|
|
||||||
});
|
|
||||||
const Dashboard: React.FC = () => {
|
const Dashboard: React.FC = () => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -97,97 +13,12 @@ const Dashboard: React.FC = () => {
|
|||||||
</PageContainer>
|
</PageContainer>
|
||||||
<DividerLine></DividerLine>
|
<DividerLine></DividerLine>
|
||||||
<PageContainer ghost title="System Load">
|
<PageContainer ghost title="System Load">
|
||||||
<UtilizationOvertime></UtilizationOvertime>
|
<SystemLoad></SystemLoad>
|
||||||
</PageContainer>
|
</PageContainer>
|
||||||
<DividerLine></DividerLine>
|
<DividerLine></DividerLine>
|
||||||
<PageContainer ghost title={false}>
|
<Usage></Usage>
|
||||||
<Row gutter={20} style={{ marginTop: '0px' }}>
|
|
||||||
<Col span={12}>
|
|
||||||
<PageTools
|
|
||||||
marginBottom={10}
|
|
||||||
marginTop={0}
|
|
||||||
left={
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
height: '34px',
|
|
||||||
display: 'flex',
|
|
||||||
justifyContent: 'flex-start',
|
|
||||||
alignItems: 'center'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
VRAM
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
></PageTools>
|
|
||||||
<GPUUtilization></GPUUtilization>
|
|
||||||
</Col>
|
|
||||||
<Col span={12}>
|
|
||||||
<PageTools
|
|
||||||
marginBottom={10}
|
|
||||||
marginTop={0}
|
|
||||||
left={
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
height: '34px',
|
|
||||||
display: 'flex',
|
|
||||||
alignItems: 'center'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
GPU Utilization
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
></PageTools>
|
|
||||||
<GPUUtilization></GPUUtilization>
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
</PageContainer>
|
|
||||||
<DividerLine></DividerLine>
|
<DividerLine></DividerLine>
|
||||||
<Row gutter={10}>
|
<ActiveTable></ActiveTable>
|
||||||
<Col span={12}>
|
|
||||||
<ContentWrapper
|
|
||||||
contentStyle={{ paddingRight: 0 }}
|
|
||||||
title={<span style={{ lineHeight: '48px' }}>API Request</span>}
|
|
||||||
>
|
|
||||||
<BarChart data={dataList} xField="time" yField="value"></BarChart>
|
|
||||||
</ContentWrapper>
|
|
||||||
</Col>
|
|
||||||
<Col span={12}>
|
|
||||||
<ContentWrapper
|
|
||||||
contentStyle={{ paddingRight: 0 }}
|
|
||||||
title={<span style={{ lineHeight: '48px' }}>Tokens</span>}
|
|
||||||
>
|
|
||||||
<BarChart data={tokenUsage} xField="time" yField="value"></BarChart>
|
|
||||||
</ContentWrapper>
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
<Row gutter={10}>
|
|
||||||
<Col span={12}>
|
|
||||||
<ContentWrapper
|
|
||||||
contentStyle={{ paddingRight: 0 }}
|
|
||||||
title={<span style={{ lineHeight: '48px' }}>Top Users</span>}
|
|
||||||
>
|
|
||||||
<HBar
|
|
||||||
data={userDataList}
|
|
||||||
xField="time"
|
|
||||||
yField="value"
|
|
||||||
height={360}
|
|
||||||
></HBar>
|
|
||||||
</ContentWrapper>
|
|
||||||
</Col>
|
|
||||||
<Col span={12}>
|
|
||||||
<ContentWrapper
|
|
||||||
contentStyle={{ paddingRight: 0 }}
|
|
||||||
title={<span style={{ lineHeight: '48px' }}>Top Projects</span>}
|
|
||||||
>
|
|
||||||
<HBar
|
|
||||||
data={projectDataList}
|
|
||||||
xField="time"
|
|
||||||
yField="value"
|
|
||||||
height={300}
|
|
||||||
></HBar>
|
|
||||||
</ContentWrapper>
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user