Skip to content

Commit 01cf281

Browse files
committed
refactor: extract shared ResourceUsageChart and clean up system components
1 parent 02c486d commit 01cf281

File tree

4 files changed

+154
-268
lines changed

4 files changed

+154
-268
lines changed

dashboard/lib/components/system/cpu.tsx

Lines changed: 28 additions & 130 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,39 @@
11
'use client';
22

33
import { Clock } from "lucide-react";
4-
import { Line } from "react-chartjs-2";
5-
import {
6-
Chart as ChartJS,
7-
CategoryScale,
8-
LinearScale,
9-
PointElement,
10-
LineElement,
11-
Title,
12-
Tooltip,
13-
Legend,
14-
Filler
15-
} from "chart.js";
164
import { HistoryData, SystemInfo } from "../../types";
175
import { gradient } from "../../colors";
6+
import { ResourceUsageChart } from "./resource-usage-chart";
7+
8+
function formatUptime(seconds: number) {
9+
const units = [
10+
{ label: 'y', value: 31536000 }, // 1 year = 60 * 60 * 24 * 365
11+
{ label: 'd', value: 86400 }, // 1 day = 60 * 60 * 24
12+
{ label: 'h', value: 3600 }, // 1 hour = 60 * 60
13+
{ label: 'm', value: 60 }, // 1 minute = 60
14+
{ label: 's', value: 1 } // 1 second
15+
];
16+
17+
const result = [];
18+
for (const { label, value } of units) {
19+
const amount = Math.floor(seconds / value);
20+
if (amount > 0) {
21+
result.push(`${amount}${label}`);
22+
seconds %= value;
23+
}
24+
}
25+
return result.length > 0 ? result.join(' ') : '0s';
26+
}
1827

19-
// Register Chart.js components
20-
ChartJS.register(
21-
CategoryScale,
22-
LinearScale,
23-
PointElement,
24-
LineElement,
25-
Title,
26-
Tooltip,
27-
Legend,
28-
Filler
29-
);
28+
const getColorForUsage = (usage: number) => {
29+
if (usage < 50) return "#1af073"; // green
30+
if (usage < 80) return "#ffaa4b"; // amber
31+
return "#ff5050"; // red
32+
};
3033

3134
// CPU Core visualization component
3235
const CPUCores = ({ coreUsages }: { coreUsages: number[] }) => {
33-
// Get color based on usage percentage
34-
const getColorForUsage = (usage: number) => {
36+
const getCoreColor = (usage: number) => {
3537
return gradient[Math.min(Math.floor(usage / 10), 9)]
3638
};
3739

@@ -42,7 +44,7 @@ const CPUCores = ({ coreUsages }: { coreUsages: number[] }) => {
4244
<div key={index} className="flex flex-col items-center">
4345
<div
4446
className="min-h-8 h-full w-full rounded-xs grid place-items-center"
45-
style={{ backgroundColor: getColorForUsage(coreUsage) }}
47+
style={{ backgroundColor: getCoreColor(coreUsage) }}
4648
title={`Core ${index}: ${coreUsage.toFixed(1)}%`}
4749
>
4850
<div className="text-xs text-[var(--text)] opacity-70 font-semibold">{coreUsage.toFixed(0)}%</div>
@@ -54,79 +56,6 @@ const CPUCores = ({ coreUsages }: { coreUsages: number[] }) => {
5456
);
5557
};
5658

57-
// Single resource usage chart component
58-
const ResourceUsageChart = ({ data, timestamps, label, color, height = "h-32" }: {data: any, timestamps: any, label: any, color: string, height?: string}) => {
59-
const chartOptions = {
60-
responsive: true,
61-
maintainAspectRatio: false,
62-
// animation: {
63-
// duration: 500
64-
// },
65-
scales: {
66-
x: {
67-
display: false
68-
},
69-
y: {
70-
min: 0,
71-
max: 100,
72-
ticks: {
73-
stepSize: 25,
74-
color: 'rgba(107, 114, 128, 0.7)',
75-
font: {
76-
size: 10
77-
}
78-
},
79-
grid: {
80-
color: 'rgba(229, 231, 235, 0.3)'
81-
}
82-
}
83-
},
84-
plugins: {
85-
legend: {
86-
display: false
87-
},
88-
tooltip: {
89-
intersect: false,
90-
mode: 'index',
91-
callbacks: {
92-
title: function (tooltipItems: any) {
93-
return new Date(timestamps[tooltipItems[0].dataIndex]).toLocaleTimeString();
94-
}
95-
}
96-
}
97-
},
98-
elements: {
99-
point: {
100-
radius: 0,
101-
hoverRadius: 3
102-
},
103-
line: {
104-
tension: 0.3,
105-
}
106-
}
107-
};
108-
109-
const chartData = {
110-
labels: timestamps,
111-
datasets: [
112-
{
113-
label: label,
114-
data: data,
115-
borderColor: color,
116-
backgroundColor: `${color}20`, // 20 = 12% opacity in hex
117-
fill: true,
118-
borderWidth: 2
119-
}
120-
]
121-
};
122-
123-
return (
124-
<div className={`w-[100%] ${height}`}>
125-
<Line options={chartOptions as any} data={chartData} />
126-
</div>
127-
);
128-
};
129-
13059
export function CPU({ resources, loading, historyData }: { resources: SystemInfo | null, loading: boolean, historyData: HistoryData }) {
13160
if (!resources) {
13261
return (
@@ -149,38 +78,8 @@ export function CPU({ resources, loading, historyData }: { resources: SystemInfo
14978
);
15079
}
15180

152-
function formatUptime(seconds: number) {
153-
const units = [
154-
{ label: 'y', value: 31536000 }, // 1 year = 60 * 60 * 24 * 365
155-
{ label: 'd', value: 86400 }, // 1 day = 60 * 60 * 24
156-
{ label: 'h', value: 3600 }, // 1 hour = 60 * 60
157-
{ label: 'm', value: 60 }, // 1 minute = 60
158-
{ label: 's', value: 1 } // 1 second
159-
];
160-
161-
const result = [];
162-
163-
for (const { label, value } of units) {
164-
const amount = Math.floor(seconds / value);
165-
if (amount > 0) {
166-
result.push(`${amount}${label}`);
167-
seconds %= value;
168-
}
169-
}
170-
171-
return result.length > 0 ? result.join(' ') : '0s';
172-
}
173-
174-
// Get percentage values
17581
const cpuUsage = resources.cpu.usage;
17682
const cpuCoreUsage = resources.cpu.coreUsage;
177-
178-
const getColorForUsage = (usage: number) => {
179-
if (usage < 50) return "#1af073"; // green
180-
if (usage < 80) return "#ffaa4b"; // amber
181-
return "#ff5050"; // red
182-
};
183-
18483
const currentCPUColor = getColorForUsage(cpuUsage || 0);
18584

18685
return (
@@ -202,7 +101,6 @@ export function CPU({ resources, loading, historyData }: { resources: SystemInfo
202101

203102
{/* CPU Usage Chart */}
204103
<div className="mt-4">
205-
{/* <div className="text-xs font-medium mb-1 text-gray-500">CPU Usage History</div> */}
206104
<ResourceUsageChart
207105
data={historyData.cpuUsage}
208106
timestamps={historyData.timestamps}

dashboard/lib/components/system/memory.tsx

Lines changed: 5 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,8 @@
11
'use client';
22

3-
import { Line } from "react-chartjs-2";
4-
import {
5-
Chart as ChartJS,
6-
CategoryScale,
7-
LinearScale,
8-
PointElement,
9-
LineElement,
10-
Title,
11-
Tooltip,
12-
Legend,
13-
Filler
14-
} from "chart.js";
153
import { HistoryData, SystemInfo } from "../../types";
164
import { formatBytes } from "../../format";
17-
18-
// Register Chart.js components
19-
ChartJS.register(
20-
CategoryScale,
21-
LinearScale,
22-
PointElement,
23-
LineElement,
24-
Title,
25-
Tooltip,
26-
Legend,
27-
Filler
28-
);
5+
import { ResourceUsageChart } from "./resource-usage-chart";
296

307
// Custom circular progress component
318
const CircularProgress = ({ value, text, color }: { value: number, text: string, color: string }) => {
@@ -63,77 +40,10 @@ const CircularProgress = ({ value, text, color }: { value: number, text: string,
6340
);
6441
};
6542

66-
// Single resource usage chart component
67-
const ResourceUsageChart = ({ data, timestamps, label, color, height = "h-32" }: { data: any, timestamps: any, label: string, color: string, height?: string }) => {
68-
const chartOptions = {
69-
responsive: true,
70-
maintainAspectRatio: false,
71-
animation: {
72-
73-
},
74-
scales: {
75-
x: {
76-
display: false
77-
},
78-
y: {
79-
min: 0,
80-
max: 100,
81-
ticks: {
82-
stepSize: 25,
83-
color: 'rgba(107, 114, 128, 0.7)',
84-
font: {
85-
size: 10
86-
}
87-
},
88-
grid: {
89-
color: 'rgba(229, 231, 235, 0.3)'
90-
}
91-
}
92-
},
93-
plugins: {
94-
legend: {
95-
display: false
96-
},
97-
tooltip: {
98-
intersect: false,
99-
mode: 'index',
100-
callbacks: {
101-
title: function (tooltipItems: any) {
102-
return new Date(timestamps[tooltipItems[0].dataIndex]).toLocaleTimeString();
103-
}
104-
}
105-
}
106-
},
107-
elements: {
108-
point: {
109-
radius: 0,
110-
hoverRadius: 3
111-
},
112-
line: {
113-
tension: 0.3,
114-
}
115-
}
116-
};
117-
118-
const chartData = {
119-
labels: timestamps,
120-
datasets: [
121-
{
122-
label: label,
123-
data: data,
124-
borderColor: color,
125-
backgroundColor: `${color}20`, // 20 = 12% opacity in hex
126-
fill: true,
127-
borderWidth: 2
128-
}
129-
]
130-
};
131-
132-
return (
133-
<div className={`w-[100%] ${height}`}>
134-
<Line options={chartOptions as any} data={chartData} />
135-
</div>
136-
);
43+
const getColorForUsage = (usage: number) => {
44+
if (usage < 60) return "#1af073"; // green
45+
if (usage < 90) return "#ffaa4b"; // amber
46+
return "#ff5050"; // red
13747
};
13848

13949
export function Memory({ resources, loading, historyData }: { resources: SystemInfo | null, loading: boolean, historyData: HistoryData }) {
@@ -162,14 +72,6 @@ export function Memory({ resources, loading, historyData }: { resources: SystemI
16272
const totalUsedMemory = ((resources.memory.total - resources.memory.free) / resources.memory.total) * 100;
16373
const availableMemory = ((resources.memory.total - resources.memory.available) / resources.memory.total) * 100;
16474

165-
// Get color based on usage percentage
166-
const getColorForUsage = (usage: number) => {
167-
if (usage < 60) return "#1af073"; // green
168-
if (usage < 90) return "#ffaa4b"; // amber
169-
return "#ff5050"; // red
170-
};
171-
172-
// Get the current memory usage color instead of using a fixed color
17375
const currentMemColor = getColorForUsage(totalUsedMemory);
17476

17577
return (

0 commit comments

Comments
 (0)