mirror of
https://github.com/ClusterCockpit/cc-backend
synced 2026-01-28 06:51:45 +01:00
chage to adaptive row sizes for publicDash
This commit is contained in:
@@ -348,282 +348,288 @@
|
|||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Card style="height: 98vh;">
|
<Row>
|
||||||
<CardBody class="align-content-center p-2">
|
<Col>
|
||||||
<Row>
|
<Refresher
|
||||||
|
hideSelector
|
||||||
|
initially={60}
|
||||||
|
onRefresh={(interval) => {
|
||||||
|
from = new Date(Date.now() - 5 * 60 * 1000);
|
||||||
|
to = new Date(Date.now());
|
||||||
|
clusterFrom = new Date(Date.now() - (8 * 60 * 60 * 1000))
|
||||||
|
|
||||||
|
if (interval) stackedFrom += Math.floor(interval / 1000);
|
||||||
|
else stackedFrom += 1 // Workaround: TimeSelection not linked, just trigger new data on manual refresh
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
|
||||||
|
{#if $statusQuery.fetching || $statesTimed.fetching}
|
||||||
|
<Row class="justify-content-center">
|
||||||
|
<Col xs="auto">
|
||||||
|
<Spinner />
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
|
||||||
|
{:else if $statusQuery.error || $statesTimed.error}
|
||||||
|
<Row class="mb-2">
|
||||||
|
<Col class="d-flex justify-content-end">
|
||||||
|
<Button color="secondary" href="/">
|
||||||
|
<Icon name="x"/>
|
||||||
|
</Button>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Row cols={{xs:1, md:2}}>
|
||||||
|
{#if $statusQuery.error}
|
||||||
<Col>
|
<Col>
|
||||||
<Refresher
|
<Card color="danger"><CardBody>Error Requesting Status Data: {$statusQuery.error.message}</CardBody></Card>
|
||||||
hideSelector
|
|
||||||
initially={60}
|
|
||||||
onRefresh={(interval) => {
|
|
||||||
from = new Date(Date.now() - 5 * 60 * 1000);
|
|
||||||
to = new Date(Date.now());
|
|
||||||
clusterFrom = new Date(Date.now() - (8 * 60 * 60 * 1000))
|
|
||||||
|
|
||||||
if (interval) stackedFrom += Math.floor(interval / 1000);
|
|
||||||
else stackedFrom += 1 // Workaround: TimeSelection not linked, just trigger new data on manual refresh
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
{/if}
|
||||||
{#if $statusQuery.fetching || $statesTimed.fetching}
|
{#if $statesTimed.error}
|
||||||
<Row class="justify-content-center">
|
<Col>
|
||||||
<Col xs="auto">
|
<Card color="danger"><CardBody>Error Requesting Node Scheduler States: {$statesTimed.error.message}</CardBody></Card>
|
||||||
<Spinner />
|
</Col>
|
||||||
</Col>
|
{/if}
|
||||||
</Row>
|
</Row>
|
||||||
|
|
||||||
{:else if $statusQuery.error || $statesTimed.error}
|
{:else}
|
||||||
<Row class="mb-2">
|
<!-- View Supposed to be Viewed at Max Viewport Size -->
|
||||||
<Col class="d-flex justify-content-end">
|
<div class="align-content-center p-2">
|
||||||
<Button color="secondary" href="/">
|
<Row cols={{xs:1, md:2}} style="height: 24vh; margin-bottom: 1rem;">
|
||||||
<Icon name="x"/>
|
<Col> <!-- General Cluster Info Card -->
|
||||||
</Button>
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
<Row cols={{xs:1, md:2}}>
|
|
||||||
{#if $statusQuery.error}
|
|
||||||
<Col>
|
|
||||||
<Card color="danger"><CardBody>Error Requesting Status Data: {$statusQuery.error.message}</CardBody></Card>
|
|
||||||
</Col>
|
|
||||||
{/if}
|
|
||||||
{#if $statesTimed.error}
|
|
||||||
<Col>
|
|
||||||
<Card color="danger"><CardBody>Error Requesting Node Scheduler States: {$statesTimed.error.message}</CardBody></Card>
|
|
||||||
</Col>
|
|
||||||
{/if}
|
|
||||||
</Row>
|
|
||||||
|
|
||||||
{:else}
|
|
||||||
<Row cols={{xs:1, md:2}}>
|
|
||||||
<Col> <!-- General Cluster Info Card -->
|
|
||||||
<Card class="h-100">
|
|
||||||
<CardHeader>
|
|
||||||
<Row>
|
|
||||||
<Col xs="11" class="text-center">
|
|
||||||
<h2 class="mb-0">Cluster {presetCluster.charAt(0).toUpperCase() + presetCluster.slice(1)}</h2>
|
|
||||||
</Col>
|
|
||||||
<Col xs="1" class="d-flex justify-content-end">
|
|
||||||
<Button color="light" href="/">
|
|
||||||
<Icon name="x"/>
|
|
||||||
</Button>
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
</CardHeader>
|
|
||||||
<CardBody>
|
|
||||||
<h4>CPU(s)</h4><p><strong>{[...clusterInfo?.processorTypes].join(', ')}</strong></p>
|
|
||||||
</CardBody>
|
|
||||||
</Card>
|
|
||||||
</Col>
|
|
||||||
|
|
||||||
<Col> <!-- Utilization Info Card -->
|
|
||||||
<Card class="h-100">
|
<Card class="h-100">
|
||||||
<CardBody>
|
<CardHeader>
|
||||||
<Row class="mb-1">
|
<Row>
|
||||||
<Col xs={4} class="d-inline-flex align-items-center justify-content-center">
|
<Col xs="11" class="text-center">
|
||||||
<Badge color="primary" style="font-size:x-large;margin-right:0.25rem;">
|
<h2 class="mb-0">Cluster {presetCluster.charAt(0).toUpperCase() + presetCluster.slice(1)}</h2>
|
||||||
{clusterInfo?.runningJobs}
|
</Col>
|
||||||
</Badge>
|
<Col xs="1" class="d-flex justify-content-end">
|
||||||
<div style="font-size:large;">
|
<Button color="light" href="/">
|
||||||
Running Jobs
|
<Icon name="x"/>
|
||||||
</div>
|
</Button>
|
||||||
</Col>
|
</Col>
|
||||||
<Col xs={4} class="d-inline-flex align-items-center justify-content-center">
|
</Row>
|
||||||
<Badge color="primary" style="font-size:x-large;margin-right:0.25rem;">
|
</CardHeader>
|
||||||
{clusterInfo?.activeUsers}
|
<CardBody>
|
||||||
</Badge>
|
<h4>CPU(s)</h4><p><strong>{[...clusterInfo?.processorTypes].join(', ')}</strong></p>
|
||||||
<div style="font-size:large;">
|
</CardBody>
|
||||||
Active Users
|
</Card>
|
||||||
</div>
|
</Col>
|
||||||
</Col>
|
|
||||||
<Col xs={4} class="d-inline-flex align-items-center justify-content-center">
|
<Col> <!-- Utilization Info Card -->
|
||||||
<Badge color="primary" style="font-size:x-large;margin-right:0.25rem;">
|
<Card class="h-100">
|
||||||
{clusterInfo?.allocatedNodes}
|
<CardBody>
|
||||||
</Badge>
|
<Row class="mb-1">
|
||||||
<div style="font-size:large;">
|
<Col xs={4} class="d-inline-flex align-items-center justify-content-center">
|
||||||
Active Nodes
|
<Badge color="primary" style="font-size:x-large;margin-right:0.25rem;">
|
||||||
</div>
|
{clusterInfo?.runningJobs}
|
||||||
</Col>
|
</Badge>
|
||||||
</Row>
|
<div style="font-size:large;">
|
||||||
<Row class="mt-1 mb-2">
|
Running Jobs
|
||||||
|
</div>
|
||||||
|
</Col>
|
||||||
|
<Col xs={4} class="d-inline-flex align-items-center justify-content-center">
|
||||||
|
<Badge color="primary" style="font-size:x-large;margin-right:0.25rem;">
|
||||||
|
{clusterInfo?.activeUsers}
|
||||||
|
</Badge>
|
||||||
|
<div style="font-size:large;">
|
||||||
|
Active Users
|
||||||
|
</div>
|
||||||
|
</Col>
|
||||||
|
<Col xs={4} class="d-inline-flex align-items-center justify-content-center">
|
||||||
|
<Badge color="primary" style="font-size:x-large;margin-right:0.25rem;">
|
||||||
|
{clusterInfo?.allocatedNodes}
|
||||||
|
</Badge>
|
||||||
|
<div style="font-size:large;">
|
||||||
|
Active Nodes
|
||||||
|
</div>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Row class="mt-1 mb-2">
|
||||||
|
<Col xs={4} class="d-inline-flex align-items-center justify-content-center">
|
||||||
|
<Badge color="secondary" style="font-size:x-large;margin-right:0.25rem;">
|
||||||
|
{clusterInfo?.flopRate} {clusterInfo?.flopRateUnit}
|
||||||
|
</Badge>
|
||||||
|
<div style="font-size:large;">
|
||||||
|
Total Flop Rate
|
||||||
|
</div>
|
||||||
|
</Col>
|
||||||
|
<Col xs={4} class="d-inline-flex align-items-center justify-content-center">
|
||||||
|
<Badge color="secondary" style="font-size:x-large;margin-right:0.25rem;">
|
||||||
|
{clusterInfo?.memBwRate} {clusterInfo?.memBwRateUnit}
|
||||||
|
</Badge>
|
||||||
|
<div style="font-size:large;">
|
||||||
|
Total Memory Bandwidth
|
||||||
|
</div>
|
||||||
|
</Col>
|
||||||
|
{#if clusterInfo?.totalAccs !== 0}
|
||||||
<Col xs={4} class="d-inline-flex align-items-center justify-content-center">
|
<Col xs={4} class="d-inline-flex align-items-center justify-content-center">
|
||||||
<Badge color="secondary" style="font-size:x-large;margin-right:0.25rem;">
|
<Badge color="secondary" style="font-size:x-large;margin-right:0.25rem;">
|
||||||
{clusterInfo?.flopRate} {clusterInfo?.flopRateUnit}
|
{clusterInfo?.gpuPwr} {clusterInfo?.gpuPwrUnit}
|
||||||
</Badge>
|
</Badge>
|
||||||
<div style="font-size:large;">
|
<div style="font-size:large;">
|
||||||
Total Flop Rate
|
Total GPU Power
|
||||||
</div>
|
</div>
|
||||||
</Col>
|
</Col>
|
||||||
|
{:else}
|
||||||
<Col xs={4} class="d-inline-flex align-items-center justify-content-center">
|
<Col xs={4} class="d-inline-flex align-items-center justify-content-center">
|
||||||
<Badge color="secondary" style="font-size:x-large;margin-right:0.25rem;">
|
<Badge color="secondary" style="font-size:x-large;margin-right:0.25rem;">
|
||||||
{clusterInfo?.memBwRate} {clusterInfo?.memBwRateUnit}
|
{clusterInfo?.cpuPwr} {clusterInfo?.cpuPwrUnit}
|
||||||
</Badge>
|
</Badge>
|
||||||
<div style="font-size:large;">
|
<div style="font-size:large;">
|
||||||
Total Memory Bandwidth
|
Total CPU Power
|
||||||
</div>
|
</div>
|
||||||
</Col>
|
</Col>
|
||||||
{#if clusterInfo?.totalAccs !== 0}
|
{/if}
|
||||||
<Col xs={4} class="d-inline-flex align-items-center justify-content-center">
|
</Row>
|
||||||
<Badge color="secondary" style="font-size:x-large;margin-right:0.25rem;">
|
<Row class="my-1 align-items-baseline">
|
||||||
{clusterInfo?.gpuPwr} {clusterInfo?.gpuPwrUnit}
|
<Col xs={2} style="font-size:large;">
|
||||||
</Badge>
|
Active Cores
|
||||||
<div style="font-size:large;">
|
</Col>
|
||||||
Total GPU Power
|
<Col xs={8}>
|
||||||
</div>
|
<Progress multi max={clusterInfo?.totalCores} style="height:2.5rem;font-size:x-large;">
|
||||||
</Col>
|
<Progress bar color="success" value={clusterInfo?.allocatedCores} title={`${clusterInfo?.allocatedCores} active`}>{formatNumber(clusterInfo?.allocatedCores)}</Progress>
|
||||||
{:else}
|
<Progress bar color="light" value={clusterInfo?.idleCores} title={`${clusterInfo?.idleCores} idle`}>{formatNumber(clusterInfo?.idleCores)}</Progress>
|
||||||
<Col xs={4} class="d-inline-flex align-items-center justify-content-center">
|
</Progress>
|
||||||
<Badge color="secondary" style="font-size:x-large;margin-right:0.25rem;">
|
</Col>
|
||||||
{clusterInfo?.cpuPwr} {clusterInfo?.cpuPwrUnit}
|
<Col xs={2} style="font-size:large;">
|
||||||
</Badge>
|
Idle Cores
|
||||||
<div style="font-size:large;">
|
</Col>
|
||||||
Total CPU Power
|
</Row>
|
||||||
</div>
|
{#if clusterInfo?.totalAccs !== 0}
|
||||||
</Col>
|
|
||||||
{/if}
|
|
||||||
</Row>
|
|
||||||
<Row class="my-1 align-items-baseline">
|
<Row class="my-1 align-items-baseline">
|
||||||
<Col xs={2} style="font-size:large;">
|
<Col xs={2} style="font-size:large;">
|
||||||
Active Cores
|
Active GPU
|
||||||
</Col>
|
</Col>
|
||||||
<Col xs={8}>
|
<Col xs={8}>
|
||||||
<Progress multi max={clusterInfo?.totalCores} style="height:2.5rem;font-size:x-large;">
|
<Progress multi max={clusterInfo?.totalAccs} style="height:2.5rem;font-size:x-large;">
|
||||||
<Progress bar color="success" value={clusterInfo?.allocatedCores} title={`${clusterInfo?.allocatedCores} active`}>{formatNumber(clusterInfo?.allocatedCores)}</Progress>
|
<Progress bar color="success" value={clusterInfo?.allocatedAccs} title={`${clusterInfo?.allocatedAccs} active`}>{formatNumber(clusterInfo?.allocatedAccs)}</Progress>
|
||||||
<Progress bar color="light" value={clusterInfo?.idleCores} title={`${clusterInfo?.idleCores} idle`}>{formatNumber(clusterInfo?.idleCores)}</Progress>
|
<Progress bar color="light" value={clusterInfo?.idleAccs} title={`${clusterInfo?.idleAccs} idle`}>{formatNumber(clusterInfo?.idleAccs)}</Progress>
|
||||||
</Progress>
|
</Progress>
|
||||||
</Col>
|
</Col>
|
||||||
<Col xs={2} style="font-size:large;">
|
<Col xs={2} style="font-size:large;">
|
||||||
Idle Cores
|
Idle GPU
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
{#if clusterInfo?.totalAccs !== 0}
|
|
||||||
<Row class="my-1 align-items-baseline">
|
|
||||||
<Col xs={2} style="font-size:large;">
|
|
||||||
Active GPU
|
|
||||||
</Col>
|
|
||||||
<Col xs={8}>
|
|
||||||
<Progress multi max={clusterInfo?.totalAccs} style="height:2.5rem;font-size:x-large;">
|
|
||||||
<Progress bar color="success" value={clusterInfo?.allocatedAccs} title={`${clusterInfo?.allocatedAccs} active`}>{formatNumber(clusterInfo?.allocatedAccs)}</Progress>
|
|
||||||
<Progress bar color="light" value={clusterInfo?.idleAccs} title={`${clusterInfo?.idleAccs} idle`}>{formatNumber(clusterInfo?.idleAccs)}</Progress>
|
|
||||||
</Progress>
|
|
||||||
</Col>
|
|
||||||
<Col xs={2} style="font-size:large;">
|
|
||||||
Idle GPU
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
{/if}
|
|
||||||
</CardBody>
|
|
||||||
</Card>
|
|
||||||
</Col>
|
|
||||||
|
|
||||||
<!-- Total Cluster Metric in Time SUMS-->
|
|
||||||
<Col class="text-center">
|
|
||||||
<h5 class="mt-2 mb-0">
|
|
||||||
Cluster Utilization (
|
|
||||||
<span style="color: #0000ff;">
|
|
||||||
{`${$statusQuery?.data?.clusterMetrics?.metrics[0]?.name} (${$statusQuery?.data?.clusterMetrics?.metrics[0]?.unit?.prefix}${$statusQuery?.data?.clusterMetrics?.metrics[0]?.unit?.base})`}
|
|
||||||
</span>,
|
|
||||||
<span style="color: #ff0000;">
|
|
||||||
{`${$statusQuery?.data?.clusterMetrics?.metrics[1]?.name} (${$statusQuery?.data?.clusterMetrics?.metrics[1]?.unit?.prefix}${$statusQuery?.data?.clusterMetrics?.metrics[1]?.unit?.base})`}
|
|
||||||
</span>
|
|
||||||
)
|
|
||||||
</h5>
|
|
||||||
<div>
|
|
||||||
{#key $statusQuery?.data?.clusterMetrics}
|
|
||||||
<DoubleMetric
|
|
||||||
timestep={$statusQuery?.data?.clusterMetrics[0]?.timestep || 60}
|
|
||||||
numNodes={$statusQuery?.data?.clusterMetrics?.nodeCount || 0}
|
|
||||||
metricData={$statusQuery?.data?.clusterMetrics?.metrics || []}
|
|
||||||
publicMode
|
|
||||||
/>
|
|
||||||
{/key}
|
|
||||||
</div>
|
|
||||||
</Col>
|
|
||||||
|
|
||||||
<Col> <!-- Nodes Roofline -->
|
|
||||||
<div>
|
|
||||||
{#key $statusQuery?.data?.nodeMetrics}
|
|
||||||
<Roofline
|
|
||||||
colorBackground
|
|
||||||
useColors={false}
|
|
||||||
useLegend={false}
|
|
||||||
allowSizeChange
|
|
||||||
cluster={presetCluster}
|
|
||||||
subCluster={clusterInfo?.roofData ? clusterInfo.roofData : null}
|
|
||||||
roofData={transformNodesStatsToData($statusQuery?.data?.nodeMetrics)}
|
|
||||||
nodesData={transformNodesStatsToInfo($statusQuery?.data?.nodeMetrics)}
|
|
||||||
fixTitle="Node Utilization"
|
|
||||||
yMinimum={1.0}
|
|
||||||
/>
|
|
||||||
{/key}
|
|
||||||
</div>
|
|
||||||
</Col>
|
|
||||||
<Col> <!-- Pie Last States -->
|
|
||||||
<Row>
|
|
||||||
{#if refinedStateData.length > 0}
|
|
||||||
<Col class="px-3 mt-2 mt-lg-0">
|
|
||||||
<div bind:clientWidth={colWidthStates}>
|
|
||||||
{#key refinedStateData}
|
|
||||||
<Pie
|
|
||||||
canvasId="hpcpie-slurm"
|
|
||||||
size={colWidthStates * 0.66}
|
|
||||||
sliceLabel="Nodes"
|
|
||||||
quantities={refinedStateData.map(
|
|
||||||
(sd) => sd.count,
|
|
||||||
)}
|
|
||||||
entities={refinedStateData.map(
|
|
||||||
(sd) => sd.state,
|
|
||||||
)}
|
|
||||||
fixColors={refinedStateData.map(
|
|
||||||
(sd) => colors['nodeStates'][sd.state],
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
{/key}
|
|
||||||
</div>
|
|
||||||
</Col>
|
|
||||||
<Col class="px-4 py-2">
|
|
||||||
{#key refinedStateData}
|
|
||||||
<Table>
|
|
||||||
<tr class="mb-2">
|
|
||||||
<th></th>
|
|
||||||
<th class="h4">State</th>
|
|
||||||
<th class="h4">Count</th>
|
|
||||||
</tr>
|
|
||||||
{#each refinedStateData as sd, i}
|
|
||||||
<tr>
|
|
||||||
<td><Icon name="circle-fill" style="color: {colors['nodeStates'][sd.state]}; font-size: 30px;"/></td>
|
|
||||||
<td class="h5">{sd.state.charAt(0).toUpperCase() + sd.state.slice(1)}</td>
|
|
||||||
<td class="h5">{sd.count}</td>
|
|
||||||
</tr>
|
|
||||||
{/each}
|
|
||||||
</Table>
|
|
||||||
{/key}
|
|
||||||
</Col>
|
|
||||||
{:else}
|
|
||||||
<Col>
|
|
||||||
<Card body color="warning" class="mx-4 my-2"
|
|
||||||
>Cannot render state status: No state data returned for <code>Pie Chart</code></Card
|
|
||||||
>
|
|
||||||
</Col>
|
|
||||||
{/if}
|
{/if}
|
||||||
</Row>
|
</CardBody>
|
||||||
</Col>
|
</Card>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
|
||||||
<Col> <!-- Stacked SchedState -->
|
<Row cols={{xs:1, md:2}} style="height: 35vh; margin-bottom: 1rem;">
|
||||||
<div>
|
<!-- Total Cluster Metric in Time SUMS-->
|
||||||
{#key $statesTimed?.data?.nodeStatesTimed}
|
<Col class="text-center">
|
||||||
<Stacked
|
<h5 class="mt-2 mb-0">
|
||||||
data={$statesTimed?.data?.nodeStatesTimed}
|
Cluster Utilization (
|
||||||
height={260}
|
<span style="color: #0000ff;">
|
||||||
ylabel="Nodes"
|
{`${$statusQuery?.data?.clusterMetrics?.metrics[0]?.name} (${$statusQuery?.data?.clusterMetrics?.metrics[0]?.unit?.prefix}${$statusQuery?.data?.clusterMetrics?.metrics[0]?.unit?.base})`}
|
||||||
yunit = "#Count"
|
</span>,
|
||||||
title = "Cluster Status"
|
<span style="color: #ff0000;">
|
||||||
stateType = "Node"
|
{`${$statusQuery?.data?.clusterMetrics?.metrics[1]?.name} (${$statusQuery?.data?.clusterMetrics?.metrics[1]?.unit?.prefix}${$statusQuery?.data?.clusterMetrics?.metrics[1]?.unit?.base})`}
|
||||||
/>
|
</span>
|
||||||
{/key}
|
)
|
||||||
</div>
|
</h5>
|
||||||
</Col>
|
<div>
|
||||||
</Row>
|
{#key $statusQuery?.data?.clusterMetrics}
|
||||||
{/if}
|
<DoubleMetric
|
||||||
</CardBody>
|
timestep={$statusQuery?.data?.clusterMetrics[0]?.timestep || 60}
|
||||||
</Card>
|
numNodes={$statusQuery?.data?.clusterMetrics?.nodeCount || 0}
|
||||||
|
metricData={$statusQuery?.data?.clusterMetrics?.metrics || []}
|
||||||
|
publicMode
|
||||||
|
/>
|
||||||
|
{/key}
|
||||||
|
</div>
|
||||||
|
</Col>
|
||||||
|
|
||||||
|
<Col> <!-- Nodes Roofline -->
|
||||||
|
<div>
|
||||||
|
{#key $statusQuery?.data?.nodeMetrics}
|
||||||
|
<Roofline
|
||||||
|
colorBackground
|
||||||
|
useColors={false}
|
||||||
|
useLegend={false}
|
||||||
|
allowSizeChange
|
||||||
|
cluster={presetCluster}
|
||||||
|
subCluster={clusterInfo?.roofData ? clusterInfo.roofData : null}
|
||||||
|
roofData={transformNodesStatsToData($statusQuery?.data?.nodeMetrics)}
|
||||||
|
nodesData={transformNodesStatsToInfo($statusQuery?.data?.nodeMetrics)}
|
||||||
|
fixTitle="Node Utilization"
|
||||||
|
yMinimum={1.0}
|
||||||
|
height={330}
|
||||||
|
/>
|
||||||
|
{/key}
|
||||||
|
</div>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
|
||||||
|
<Row cols={{xs:1, md:2}} style="height: 35vh;">
|
||||||
|
<Col> <!-- Pie Last States -->
|
||||||
|
<Row>
|
||||||
|
{#if refinedStateData.length > 0}
|
||||||
|
<Col class="px-3 mt-2 mt-lg-0">
|
||||||
|
<div bind:clientWidth={colWidthStates}>
|
||||||
|
{#key refinedStateData}
|
||||||
|
<Pie
|
||||||
|
canvasId="hpcpie-slurm"
|
||||||
|
size={colWidthStates * 0.66}
|
||||||
|
sliceLabel="Nodes"
|
||||||
|
quantities={refinedStateData.map(
|
||||||
|
(sd) => sd.count,
|
||||||
|
)}
|
||||||
|
entities={refinedStateData.map(
|
||||||
|
(sd) => sd.state,
|
||||||
|
)}
|
||||||
|
fixColors={refinedStateData.map(
|
||||||
|
(sd) => colors['nodeStates'][sd.state],
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
{/key}
|
||||||
|
</div>
|
||||||
|
</Col>
|
||||||
|
<Col class="px-4 py-2">
|
||||||
|
{#key refinedStateData}
|
||||||
|
<Table>
|
||||||
|
<tr class="mb-2">
|
||||||
|
<th></th>
|
||||||
|
<th class="h4">State</th>
|
||||||
|
<th class="h4">Count</th>
|
||||||
|
</tr>
|
||||||
|
{#each refinedStateData as sd, i}
|
||||||
|
<tr>
|
||||||
|
<td><Icon name="circle-fill" style="color: {colors['nodeStates'][sd.state]}; font-size: 30px;"/></td>
|
||||||
|
<td class="h5">{sd.state.charAt(0).toUpperCase() + sd.state.slice(1)}</td>
|
||||||
|
<td class="h5">{sd.count}</td>
|
||||||
|
</tr>
|
||||||
|
{/each}
|
||||||
|
</Table>
|
||||||
|
{/key}
|
||||||
|
</Col>
|
||||||
|
{:else}
|
||||||
|
<Col>
|
||||||
|
<Card body color="warning" class="mx-4 my-2"
|
||||||
|
>Cannot render state status: No state data returned for <code>Pie Chart</code></Card
|
||||||
|
>
|
||||||
|
</Col>
|
||||||
|
{/if}
|
||||||
|
</Row>
|
||||||
|
</Col>
|
||||||
|
|
||||||
|
<Col> <!-- Stacked SchedState -->
|
||||||
|
<div>
|
||||||
|
{#key $statesTimed?.data?.nodeStatesTimed}
|
||||||
|
<Stacked
|
||||||
|
data={$statesTimed?.data?.nodeStatesTimed}
|
||||||
|
height={300}
|
||||||
|
ylabel="Nodes"
|
||||||
|
yunit = "#Count"
|
||||||
|
title = "Cluster Status"
|
||||||
|
stateType = "Node"
|
||||||
|
/>
|
||||||
|
{/key}
|
||||||
|
</div>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
|||||||
Reference in New Issue
Block a user