You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

430 lines
12 KiB
TypeScript

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/* eslint-disable eqeqeq */
/* eslint-disable react/no-unknown-property */
import { PageContainer, ProCard } from '@ant-design/pro-components';
import { Image } from 'antd';
import { fabric } from 'fabric';
import React, { useEffect, useRef, useState } from 'react';
// type
import { ComputePowerPoolItem } from './typing';
// TODO bug左侧
// state
const poolsData: ComputePowerPoolItem[] = [
{
name: '玩手机监控',
type: 0,
proportion: 39,
PretreatmentEfficiency: 15,
color: '#FAA90B',
},
{
name: '离岗监控',
type: 1,
proportion: 30,
PretreatmentEfficiency: 20,
color: '#3879FE',
},
{
name: '空闲算力',
type: 2,
proportion: 1,
PretreatmentEfficiency: 0,
},
];
/**子组件 */
// 参数信息项
const InfoPreview: React.FC<{
name: string;
des: string;
}> = ({ name, des }) => {
return (
<div
style={{
padding: 0,
margin: 0,
display: 'flex',
justifyContent: 'center',
flexDirection: 'column',
minWidth: '13vw',
}}
>
<h6 style={{ color: '#333333', fontSize: 14, fontWeight: 700 }}>{name}</h6>
<div style={{ color: '#666666', fontSize: 14 }}>{des}</div>
</div>
);
};
// 占比信息
const OccupyProportion: React.FC<{
pools: ComputePowerPoolItem[];
}> = ({ pools }) => {
const poolDefault = {
processBarOptions: {
top: 3, // 矩形左上角在y轴的位置
left: 0, // 矩形左上角在x轴的位置
height: 32, // 矩形的高
stroke: 'transparent', // 边框颜色
strokeWidth: 2, // 边框宽度
rx: 15, // 圆角的横向半径
ry: 15, // 圆角的纵向半径
selectable: false,
},
buttonBgOptions: {
width: 20,
height: 40,
fill: 'white', // 填充颜色
strokeWidth: 2, // 边框宽度
left: 0,
top: 0,
selectable: false,
hasControls: false,
},
buttonImageOptions: {
selectable: false,
hasControls: false,
},
buttonGroupOptions: {
width: 20,
height: 40,
top: 0,
lockMovementY: true,
hasControls: false,
// selectable: false,
},
};
const [clipPathData, setClipPathData] = useState({
width: 1000, // 宽
height: 80, // 高
});
const canvasRef = useRef(null);
const [cvs, setCanvas] = useState(null);
const [rect1Witdh, setRect1Witdh] = useState((pools[0].proportion / 100) * clipPathData.width);
const [rect2Witdh, setRect2Witdh] = useState((pools[1].proportion / 100) * clipPathData.width);
useEffect(() => {
const canvasObject = new fabric.Canvas(canvasRef.current);
// 整个进度条 底色块
const rect0 = new fabric.Rect({
...poolDefault.processBarOptions,
width: clipPathData.width, // 矩形的宽
fill: '#E5E5E5', // 填充色
});
// 玩手机监控
const rect1 = new fabric.Rect({
...poolDefault.processBarOptions,
width: rect1Witdh, // 矩形的宽
fill: '#FAA90B', // 填充色
});
// 离岗监控
const rect2 = new fabric.Rect({
...poolDefault.processBarOptions,
left: rect1Witdh,
width: rect2Witdh, // 矩形的宽
fill: '#3879FE', // 填充色
});
// 创建矩形对象
const bgRect1 = new fabric.Rect(poolDefault.buttonBgOptions);
const bgRect2 = new fabric.Rect(poolDefault.buttonBgOptions);
// 添加背景图片到矩形
fabric.Image.fromURL('/images/computePowerAllocation/slideBtn1.png', function (img) {
// 设置图片的宽度和高度为矩形的宽度和高度
img.set({ width: bgRect1.width, height: bgRect1.height, ...poolDefault.buttonImageOptions });
// 将图片置于矩形的底部
// bgRect1.set({ originX: 'center', originY: 'center' });
canvasObject.add(
new fabric.Group([bgRect1, img], {
...poolDefault.buttonGroupOptions,
buttonId: '1',
left: rect1Witdh - 10,
}),
);
// 更新Canvas以应用更改
canvasObject.renderAll();
});
fabric.Image.fromURL('/images/computePowerAllocation/slideBtn2.png', function (img) {
// 设置图片的宽度和高度为矩形的宽度和高度
img.set({ width: bgRect2.width, height: bgRect2.height, ...poolDefault.buttonImageOptions });
// 将图片置于矩形的底部
// bgRect1.set({ originX: 'center', originY: 'center' });
canvasObject.add(
new fabric.Group([bgRect2, img], {
...poolDefault.buttonGroupOptions,
buttonId: '2',
left: rect1Witdh + rect2Witdh - 10,
}),
);
// 更新Canvas以应用更改
canvasObject.renderAll();
});
canvasObject.add(rect0);
canvasObject.add(rect1);
canvasObject.add(rect2);
canvasObject.on('object:moving', (event) => {
// 获取事件的目标对象
const targetObject = event.target;
console.log(targetObject.buttonId, 'targetObject', canvasObject.item(3));
// 算力按钮
switch (targetObject.buttonId) {
case '1':
// 算力按钮1
if (targetObject?.left >= clipPathData.width - 20) {
targetObject?.set({
left: clipPathData.width - 20,
});
}
if (targetObject?.left <= 0) {
targetObject?.set({
left: 0,
});
}
const currObject1Width = targetObject?.left + 10;
canvasObject.item(1).set({
width: currObject1Width,
});
canvasObject.item(2).set({
left: targetObject?.left + 10,
});
canvasObject.item(4).set({
left: canvasObject.item(2).left - 10 + canvasObject.item(2).width,
});
if (currObject1Width + canvasObject.item(2).width >= clipPathData.width) {
canvasObject.item(2).set({
width: clipPathData.width - currObject1Width,
});
canvasObject.item(4).set({
left: clipPathData.width - 20,
});
}
break;
case '2':
// 算力按钮2
if (targetObject?.left >= clipPathData.width - 20) {
targetObject?.set({
left: clipPathData.width - 20,
});
}
const currObject11Width = canvasObject.item(1).width;
const currObject22Width = canvasObject.item(2).width;
if(targetObject?.left <= currObject11Width+ 10){
targetObject?.set({
left: currObject11Width + 10,
});
}
// if (targetObject?.left <= rect1Witdh) {
// targetObject?.set({
// left: currObject11Width + currObject22Width,
// });
// }
console.log(currObject11Width, 'button2', currObject22Width)
canvasObject.item(2).set({
width: targetObject?.left - currObject11Width + 10,
});
// canvasObject.item(2).set({
// left: targetObject?.left + 10,
// });
// canvasObject.item(2).set({
// width: targetObject?.left -rect1Witdh + 10,
// });
break;
}
// set_category_fk_id_open(false);
// 检查目标对象是否为组合对象
setRect1Witdh(targetObject?.left);
canvasObject.renderAll();
});
canvasObject.renderAll();
setCanvas(canvasObject);
return () => {
canvasObject.dispose();
};
}, []);
return (
<div className="occupyProportion_box">
<div
className="occupy_up"
style={{ marginTop: 24, marginBottom: 20, padding: 0, position: 'relative', width: '100%' }}
>
<canvas ref={canvasRef} {...clipPathData} ></canvas>
{/* <ul
className="occupy_progress"
style={{
width: '100%',
height: 32,
backgroundColor: '#E5E5E5',
borderRadius: 16,
padding: 0,
overflow: 'hidden',
display: 'flex',
}}
>
{pools.map((item, index) => {
return (
<li
key={index}
style={{
height: 32,
width: `${item.proportion}%`,
padding: 0,
backgroundColor: item?.color || '#E5E5E5',
}}
></li>
);
})}
</ul>
<ul>
<li
style={{
position: 'absolute',
left: `calc(${pools[0].proportion - 0.8}% )`,
top: -4,
padding: 0,
width: 20,
}}
>
<Image
width={20}
src={'/images/computePowerAllocation/slideBtn1.png'}
preview={false}
></Image>
</li>
<li
style={{
position: 'absolute',
left: `${pools[0].proportion + pools[1].proportion - 0.8}%`,
top: -4,
width: 20,
}}
>
<Image
width={20}
src={'/images/computePowerAllocation/slideBtn2.png'}
preview={false}
></Image>
</li>
</ul> */}
</div>
<div className="occupy_des">
<ul
style={{
display: 'flex',
paddingLeft: 0,
paddingBottom: 24,
margin: 0,
}}
>
{pools.map((item, index) => {
return (
<li key={index} style={{ marginRight: 35 }}>
<span
style={{
width: 12,
height: 12,
display: 'inline-block',
background: item?.color || '#E5E5E5',
}}
></span>
<span style={{ paddingLeft: 8 }}>
{item.name}{item.proportion}%
</span>
{item.type != 2 ? (
<span style={{ paddingLeft: 8 }}>
<span style={{ fontWeight: 700 }}>{item.PretreatmentEfficiency} /</span>
</span>
) : (
<></>
)}
</li>
);
})}
</ul>
</div>
</div>
);
};
/**
* @算力资源池页面组件
* @returns
*/
const ComputePowerAllocation: React.FC = () => {
return (
<PageContainer>
<ProCard
title="算力资源池"
style={{ background: 'white' }}
headStyle={{ padding: 20, borderBottom: '1px solid #E0E0E0' }}
bodyStyle={{
paddingLeft: 9,
paddingRight: 9,
paddingTop: 0,
paddingBottom: 0,
margin: 0,
}}
gutter={24}
wrap
ghost
>
{/* 参数信息 */}
<ProCard
gutter={24}
style={{ padding: 0, margin: 0 }}
bodyStyle={{
paddingTop: 24,
paddingBottom: 24,
paddingLeft: 0,
paddingRight: 0,
margin: 0,
display: 'flex',
alignItems: 'center',
borderBottom: '1px solid #E0E0E0',
}}
>
<Image
width={62}
src={'/images/computePowerAllocation/icon1.png'}
placeholder={
<Image preview={false} src={'/images/computePowerAllocation/icon1.png'} width={62} />
}
/>
<div
style={{
paddingLeft: 17,
paddingRight: 17,
margin: 0,
display: 'flex',
justifyContent: 'center',
flexDirection: 'column',
}}
>
<InfoPreview name="苏胜天算力资源池" des="算力资源999Tops"></InfoPreview>
</div>
<InfoPreview
name="硬件组成"
des="NVIDIA GeForce 4090 | NVIDIA GeForce 4090 | NVIDIA GeForce 4090 |"
></InfoPreview>
</ProCard>
{/* 占比信息 */}
<ProCard
gutter={24}
style={{ padding: 0, margin: 0 }}
bodyStyle={{ padding: 0, margin: 0 }}
>
<OccupyProportion pools={poolsData as ComputePowerPoolItem[]} />
</ProCard>
</ProCard>
</PageContainer>
);
};
export default ComputePowerAllocation;