Skip to content

Commit 005a1d0

Browse files
committed
Fix job&queue layout probelm
Signed-off-by: Monokaix <[email protected]>
1 parent cf87c45 commit 005a1d0

File tree

2 files changed

+254
-293
lines changed

2 files changed

+254
-293
lines changed

frontend/src/components/Charts/JobStatusPieChart.jsx

Lines changed: 150 additions & 171 deletions
Original file line numberDiff line numberDiff line change
@@ -6,190 +6,169 @@ import { Chart as ChartJS, ArcElement, Tooltip, Legend, Title } from "chart.js";
66
ChartJS.register(ArcElement, Tooltip, Legend, Title);
77

88
const JobStatusPieChart = ({ data }) => {
9-
if (!data || !Array.isArray(data)) {
10-
return (
11-
<Box sx={{ height: 300, width: "100%", position: "relative" }}>
12-
<Typography>No data available</Typography>
13-
</Box>
14-
);
15-
}
16-
17-
const statusCounts = data.reduce(
18-
(acc, job) => {
19-
const status = job.status;
20-
if (status?.succeeded) {
21-
acc.Completed++;
22-
} else if (
23-
status?.state?.phase === "Running" ||
24-
status?.state?.phase === "Pending"
25-
) {
26-
acc.Running++;
27-
} else if (status?.state?.phase === "Failed") {
28-
acc.Failed++;
29-
}
30-
return acc;
31-
},
32-
{
33-
Completed: 0,
34-
Running: 0,
35-
Failed: 0,
9+
if (!data || !Array.isArray(data)) {
10+
return (
11+
<Box sx={{ height: 300, width: "100%", position: "relative" }}>
12+
<Typography>No data available</Typography>
13+
</Box>
14+
);
3615
}
37-
);
3816

39-
const total = Object.values(statusCounts).reduce((a, b) => a + b, 0);
40-
const colors = {
41-
Completed: "#4caf50",
42-
Running: "#2196f3",
43-
Failed: "#f44336",
44-
};
17+
const statusCounts = data.reduce(
18+
(acc, job) => {
19+
const status = job.status;
20+
if (status?.succeeded) {
21+
acc.Completed++;
22+
} else if (
23+
status?.state?.phase === "Running" ||
24+
status?.state?.phase === "Pending"
25+
) {
26+
acc.Running++;
27+
} else if (status?.state?.phase === "Failed") {
28+
acc.Failed++;
29+
}
30+
return acc;
31+
},
32+
{
33+
Completed: 0,
34+
Running: 0,
35+
Failed: 0,
36+
}
37+
);
4538

46-
const chartData = {
47-
labels: Object.keys(statusCounts),
48-
datasets: [
49-
{
50-
data: Object.values(statusCounts),
51-
backgroundColor: Object.values(colors),
52-
borderColor: "white",
53-
borderWidth: 2,
54-
hoverBorderColor: "white",
55-
hoverBorderWidth: 3,
56-
},
57-
],
58-
};
39+
const total = Object.values(statusCounts).reduce((a, b) => a + b, 0);
40+
const colors = {
41+
Completed: "#4caf50",
42+
Running: "#2196f3",
43+
Failed: "#f44336",
44+
};
5945

60-
const options = {
61-
responsive: true,
62-
maintainAspectRatio: false,
63-
cutout: "70%",
64-
plugins: {
65-
legend: {
66-
display: false,
67-
},
68-
tooltip: {
69-
enabled: false,
70-
},
71-
},
72-
};
46+
const chartData = {
47+
labels: Object.keys(statusCounts),
48+
datasets: [
49+
{
50+
data: Object.values(statusCounts),
51+
backgroundColor: Object.values(colors),
52+
borderColor: "white",
53+
borderWidth: 2,
54+
hoverBorderColor: "white",
55+
hoverBorderWidth: 3,
56+
},
57+
],
58+
};
7359

74-
const CustomLegend = () => (
75-
<Box sx={{ pl: 2 }}>
76-
{Object.entries(statusCounts).map(([status, count]) => (
77-
<Box
78-
key={status}
79-
sx={{
80-
display: "flex",
81-
alignItems: "center",
82-
mb: 1.5,
83-
}}
84-
>
85-
<Box
86-
sx={{
87-
width: 12,
88-
height: 12,
89-
borderRadius: "50%",
90-
backgroundColor: colors[status],
91-
mr: 1,
92-
}}
93-
/>
94-
<Typography variant="body2" sx={{ mr: 2 }}>
95-
{status}
96-
</Typography>
97-
<Typography variant="body2" color="text.secondary">
98-
{count} ({total > 0 ? ((count / total) * 100).toFixed(1) : 0}%)
99-
</Typography>
100-
</Box>
101-
))}
102-
</Box>
103-
);
60+
const options = {
61+
responsive: true,
62+
maintainAspectRatio: false,
63+
cutout: "70%",
64+
plugins: {
65+
legend: {
66+
display: false,
67+
},
68+
tooltip: {
69+
enabled: false,
70+
},
71+
},
72+
};
10473

105-
const hasData = Object.values(statusCounts).some((count) => count > 0);
74+
const hasData = Object.values(statusCounts).some((count) => count > 0);
10675

107-
return (
108-
<Box
109-
sx={{
110-
height: "100%",
111-
display: "flex",
112-
flexDirection: "column",
113-
}}
114-
>
115-
<Typography variant="h6" align="center" sx={{ mb: 1 }}>
116-
Jobs Status
117-
</Typography>
118-
119-
<Grid container spacing={2} sx={{ flex: 1 }}>
120-
<Grid item xs={8}>
121-
<Box
76+
return (
77+
<Box
12278
sx={{
123-
height: "75%", // 增加饼图高度至卡片的约2/3
124-
position: "relative",
125-
display: "flex",
126-
alignItems: "center",
127-
justifyContent: "center",
128-
mt: 2, // 向下微调位置
79+
height: "100%",
80+
display: "flex",
81+
flexDirection: "column",
12982
}}
130-
>
131-
<Doughnut
132-
data={chartData}
133-
options={{
134-
...options,
135-
maintainAspectRatio: false,
136-
}}
137-
/>
138-
<Typography
139-
variant="h4"
140-
sx={{
141-
position: "absolute",
142-
top: "50%",
143-
left: "50%",
144-
transform: "translate(-50%, -50%)",
145-
textAlign: "center",
146-
}}
147-
>
148-
{total}
83+
>
84+
<Typography variant="h6" align="center" sx={{ mb: 1 }}>
85+
Jobs Status
14986
</Typography>
150-
</Box>
151-
</Grid>
152-
<Grid item xs={4}>
153-
<Box
154-
sx={{
155-
display: "flex",
156-
flexDirection: "column",
157-
justifyContent: "flex-start", // 将图例向上对齐
158-
mt: 4, // 向上移动图例
159-
}}
160-
>
161-
{Object.entries(statusCounts).map(([status, count]) => (
162-
<Box
163-
key={status}
87+
88+
<Box
16489
sx={{
165-
display: "flex",
166-
alignItems: "center",
167-
mb: 1.5,
90+
display: "flex",
91+
flexDirection: "row",
92+
justifyContent: "space-between",
93+
alignItems: "flex-start",
94+
flexWrap: "wrap", // 使内容在屏幕较窄时自动换行
95+
gap: 2, // 适当的间距
96+
width: "100%",
16897
}}
169-
>
98+
>
99+
<Box
100+
sx={{
101+
flex: 1,
102+
minWidth: "250px", // 保证图表不会过小
103+
height: "300px", // 固定高度,以便适应各种屏幕
104+
position: "relative",
105+
display: "flex",
106+
alignItems: "center",
107+
justifyContent: "center",
108+
}}
109+
>
110+
<Doughnut
111+
data={chartData}
112+
options={{
113+
...options,
114+
maintainAspectRatio: false,
115+
}}
116+
/>
117+
<Typography
118+
variant="h4"
119+
sx={{
120+
position: "absolute",
121+
top: "50%",
122+
left: "50%",
123+
transform: "translate(-50%, -50%)",
124+
textAlign: "center",
125+
}}
126+
>
127+
{total}
128+
</Typography>
129+
</Box>
130+
170131
<Box
171-
sx={{
172-
width: 12,
173-
height: 12,
174-
borderRadius: "50%",
175-
backgroundColor: colors[status],
176-
mr: 1,
177-
}}
178-
/>
179-
<Typography variant="body2" sx={{ mr: 2 }}>
180-
{status}
181-
</Typography>
182-
<Typography variant="body2" color="text.secondary">
183-
{count} ({total > 0 ? ((count / total) * 100).toFixed(1) : 0}
184-
%)
185-
</Typography>
186-
</Box>
187-
))}
188-
</Box>
189-
</Grid>
190-
</Grid>
191-
</Box>
192-
);
132+
sx={{
133+
flex: 1,
134+
minWidth: "250px", // 保证图例不会过小
135+
display: "flex",
136+
flexDirection: "column",
137+
justifyContent: "flex-start", // 图例顶部对齐
138+
alignItems: "flex-start", // 左对齐
139+
textAlign: "left",
140+
}}
141+
>
142+
{Object.entries(statusCounts).map(([status, count]) => (
143+
<Box
144+
key={status}
145+
sx={{
146+
display: "flex",
147+
alignItems: "center",
148+
mb: 1.5,
149+
}}
150+
>
151+
<Box
152+
sx={{
153+
width: 12,
154+
height: 12,
155+
borderRadius: "50%",
156+
backgroundColor: colors[status],
157+
mr: 1,
158+
}}
159+
/>
160+
<Typography variant="body2" sx={{ mr: 2, minWidth: 70 }}>
161+
{status}
162+
</Typography>
163+
<Typography variant="body2" color="text.secondary">
164+
{count} ({total > 0 ? ((count / total) * 100).toFixed(1) : 0}%)
165+
</Typography>
166+
</Box>
167+
))}
168+
</Box>
169+
</Box>
170+
</Box>
171+
);
193172
};
194173

195174
export default JobStatusPieChart;

0 commit comments

Comments
 (0)