Skip to content

Commit 6da16dd

Browse files
committed
Replace PI consumption table with pie chart
1 parent aae6848 commit 6da16dd

2 files changed

Lines changed: 55 additions & 61 deletions

File tree

src/slurmcostmanager.css

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -164,20 +164,6 @@ nav button:hover {
164164
height: 60px;
165165
display: block;
166166
}
167-
.pi-table {
168-
width: 100%;
169-
border-collapse: collapse;
170-
margin-top: 1em;
171-
}
172-
.pi-table th,
173-
.pi-table td {
174-
border: 1px solid #ccc;
175-
padding: 0.25em 0.5em;
176-
}
177-
.pi-bar {
178-
height: 8px;
179-
background: #4e79a7;
180-
}
181167
.filter-bar {
182168
display: flex;
183169
flex-wrap: wrap;

src/slurmcostmanager.js

Lines changed: 55 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -279,54 +279,62 @@ function HistoricalUsageChart({ monthly }) {
279279
return React.createElement('div', { className: 'chart-container' }, React.createElement('canvas', { ref: canvasRef, width: 600, height: 300 }));
280280
}
281281

282-
function PiConsumptionTable({ details }) {
283-
const totals = {};
284-
details.forEach(acc => {
285-
(acc.users || []).forEach(u => {
286-
totals[u.user] = (totals[u.user] || 0) + (u.core_hours || 0);
282+
function PiConsumptionChart({ details }) {
283+
const canvasRef = useRef(null);
284+
useEffect(() => {
285+
if (!canvasRef.current) return;
286+
287+
const totals = {};
288+
details.forEach(acc => {
289+
(acc.users || []).forEach(u => {
290+
totals[u.user] = (totals[u.user] || 0) + (u.core_hours || 0);
291+
});
287292
});
288-
});
289-
const entries = Object.entries(totals).map(([user, core]) => ({ user, core }));
290-
entries.sort((a, b) => b.core - a.core);
291-
const top = entries.slice(0, 10);
292-
const max = top[0] ? top[0].core : 0;
293+
294+
const entries = Object.entries(totals).map(([user, core]) => ({ user, core }));
295+
entries.sort((a, b) => b.core - a.core);
296+
const top = entries.slice(0, 10);
297+
298+
const colors = [
299+
'#4e79a7',
300+
'#f28e2b',
301+
'#e15759',
302+
'#76b7b2',
303+
'#59a14f',
304+
'#edc949',
305+
'#af7aa1',
306+
'#ff9da7',
307+
'#9c755f',
308+
'#bab0ac'
309+
];
310+
311+
const chart = new Chart(canvasRef.current.getContext('2d'), {
312+
type: 'pie',
313+
data: {
314+
labels: top.map(e => e.user),
315+
datasets: [
316+
{
317+
data: top.map(e => e.core),
318+
backgroundColor: colors.slice(0, top.length)
319+
}
320+
]
321+
},
322+
options: {
323+
responsive: false,
324+
maintainAspectRatio: false,
325+
plugins: {
326+
legend: { position: 'right' }
327+
}
328+
}
329+
});
330+
331+
return () => chart.destroy();
332+
}, [details]);
333+
293334
return React.createElement(
294-
'table',
295-
{ className: 'pi-table' },
296-
React.createElement(
297-
'thead',
298-
null,
299-
React.createElement(
300-
'tr',
301-
null,
302-
React.createElement('th', null, 'PI'),
303-
React.createElement('th', null, 'CPU Hours')
304-
)
305-
),
306-
React.createElement(
307-
'tbody',
308-
null,
309-
top.map((e, i) =>
310-
React.createElement(
311-
'tr',
312-
{ key: i },
313-
React.createElement('td', null, e.user),
314-
React.createElement(
315-
'td',
316-
null,
317-
React.createElement(
318-
'div',
319-
{ style: { display: 'flex', alignItems: 'center' } },
320-
React.createElement('div', {
321-
className: 'pi-bar',
322-
style: { width: `${max ? (e.core / max) * 100 : 0}%` }
323-
}),
324-
React.createElement('span', { style: { marginLeft: '0.5em' } }, e.core)
325-
)
326-
)
327-
)
328-
)
329-
)
335+
'div',
336+
{ className: 'chart-container', style: { width: '300px', height: '300px' } },
337+
React.createElement('canvas', { ref: canvasRef, width: 300, height: 300 })
330338
);
331339
}
332340

@@ -496,7 +504,7 @@ function Summary({ summary, details, daily, monthly }) {
496504
})
497505
),
498506
React.createElement('h3', null, 'Top 10 PIs by consumption'),
499-
React.createElement(PiConsumptionTable, { details }),
507+
React.createElement(PiConsumptionChart, { details }),
500508
React.createElement('h3', null, 'CPU/GPU-hrs per Slurm account'),
501509
React.createElement(AccountsChart, { details }),
502510
React.createElement('h3', null, 'Historical CPU/GPU-hrs (monthly)'),

0 commit comments

Comments
 (0)