diff --git a/web/frontend/src/Analysis.root.svelte b/web/frontend/src/Analysis.root.svelte
index b210dcb..0aa7ca5 100644
--- a/web/frontend/src/Analysis.root.svelte
+++ b/web/frontend/src/Analysis.root.svelte
@@ -28,7 +28,7 @@
} from "./generic/utils.js";
import PlotSelection from "./analysis/PlotSelection.svelte";
import Filters from "./generic/Filters.svelte";
- import PlotTable from "./generic/PlotTable.svelte";
+ import PlotGrid from "./generic/PlotGrid.svelte";
import Histogram from "./generic/plots/Histogram.svelte";
import Pie, { colors } from "./generic/plots/Pie.svelte";
import ScatterPlot from "./generic/plots/Scatter.svelte";
@@ -70,6 +70,8 @@
...new Set([...metricsInHistograms, ...metricsInScatterplots.flat()]),
];
+ $: console.log(">>> CLUSTER", cluster)
+
const sortOptions = [
{ key: "totalWalltime", label: "Walltime" },
{ key: "totalNodeHours", label: "Node Hours" },
@@ -523,7 +525,7 @@
-
-
+
@@ -569,7 +571,7 @@
-
-
+
{/if}
diff --git a/web/frontend/src/Job.root.svelte b/web/frontend/src/Job.root.svelte
index 2827248..ca1ce9e 100644
--- a/web/frontend/src/Job.root.svelte
+++ b/web/frontend/src/Job.root.svelte
@@ -38,7 +38,7 @@
import JobSummary from "./job/JobSummary.svelte";
import EnergySummary from "./job/EnergySummary.svelte";
import ConcurrentJobs from "./generic/helper/ConcurrentJobs.svelte";
- import PlotTable from "./generic/PlotTable.svelte";
+ import PlotGrid from "./generic/PlotGrid.svelte";
import Roofline from "./generic/plots/Roofline.svelte";
import JobInfo from "./generic/joblist/JobInfo.svelte";
import MetricSelection from "./generic/select/MetricSelection.svelte";
@@ -330,50 +330,55 @@
{/if}
-
-
-
- {#if $jobMetrics.error}
+
+
+ {#if $jobMetrics.error}
+
+
{#if $initq.data.job.monitoringStatus == 0 || $initq.data.job.monitoringStatus == 2}
Not monitored or archiving failed
{/if}
{$jobMetrics.error.message}
- {:else if $jobMetrics.fetching}
+
+
+ {:else if $jobMetrics.fetching}
+
+
- {:else if $initq?.data && $jobMetrics?.data?.jobMetrics}
-
+
+ {:else if $initq?.data && $jobMetrics?.data?.jobMetrics}
+
+ {#if item.data}
+ statsTable.moreLoaded(detail)}
+ job={$initq.data.job}
+ metricName={item.metric}
+ metricUnit={$initq.data.globalMetrics.find((gm) => gm.name == item.metric)?.unit}
+ nativeScope={$initq.data.globalMetrics.find((gm) => gm.name == item.metric)?.scope}
+ rawData={item.data.map((x) => x.metric)}
+ scopes={item.data.map((x) => x.scope)}
+ {width}
+ isShared={$initq.data.job.exclusive != 1}
+ />
+ {:else}
+ No dataset returned for {item.metric}
- {#if item.data}
- statsTable.moreLoaded(detail)}
- job={$initq.data.job}
- metricName={item.metric}
- metricUnit={$initq.data.globalMetrics.find((gm) => gm.name == item.metric)?.unit}
- nativeScope={$initq.data.globalMetrics.find((gm) => gm.name == item.metric)?.scope}
- rawData={item.data.map((x) => x.metric)}
- scopes={item.data.map((x) => x.scope)}
- {width}
- isShared={$initq.data.job.exclusive != 1}
- />
- {:else}
- No dataset returned for {item.metric}
- {/if}
-
{/if}
-
-
+
+ {/if}
diff --git a/web/frontend/src/Node.root.svelte b/web/frontend/src/Node.root.svelte
index 7dba330..700b1de 100644
--- a/web/frontend/src/Node.root.svelte
+++ b/web/frontend/src/Node.root.svelte
@@ -29,7 +29,7 @@
init,
checkMetricDisabled,
} from "./generic/utils.js";
- import PlotTable from "./generic/PlotTable.svelte";
+ import PlotGrid from "./generic/PlotGrid.svelte";
import MetricPlot from "./generic/plots/MetricPlot.svelte";
import TimeSelection from "./generic/select/TimeSelection.svelte";
import Refresher from "./generic/helper/Refresher.svelte";
@@ -187,7 +187,7 @@
{:else if $nodeMetricsData.fetching || $initq.fetching}
{:else}
- No dataset returned for {item.name}
{/if}
-
+
{/if}
diff --git a/web/frontend/src/Status.root.svelte b/web/frontend/src/Status.root.svelte
index f995150..47a7918 100644
--- a/web/frontend/src/Status.root.svelte
+++ b/web/frontend/src/Status.root.svelte
@@ -32,7 +32,7 @@
transformPerNodeDataForRoofline,
} from "./generic/utils.js";
import { scaleNumbers } from "./generic/units.js";
- import PlotTable from "./generic/PlotTable.svelte";
+ import PlotGrid from "./generic/PlotGrid.svelte";
import Roofline from "./generic/plots/Roofline.svelte";
import Pie, { colors } from "./generic/plots/Pie.svelte";
import Histogram from "./generic/plots/Histogram.svelte";
@@ -651,31 +651,27 @@
{#if metricsInHistograms}
-
-
- {#key $mainQuery.data.stats[0].histMetrics}
-
-
-
- {/key}
-
-
+ {#key $mainQuery.data.stats[0].histMetrics}
+
+
+
+ {/key}
{/if}
{/if}
diff --git a/web/frontend/src/Systems.root.svelte b/web/frontend/src/Systems.root.svelte
index 8894fd9..ecd9a5b 100644
--- a/web/frontend/src/Systems.root.svelte
+++ b/web/frontend/src/Systems.root.svelte
@@ -28,7 +28,7 @@
init,
checkMetricDisabled,
} from "./generic/utils.js";
- import PlotTable from "./generic/PlotTable.svelte";
+ import PlotGrid from "./generic/PlotGrid.svelte";
import MetricPlot from "./generic/plots/MetricPlot.svelte";
import TimeSelection from "./generic/select/TimeSelection.svelte";
import Refresher from "./generic/helper/Refresher.svelte";
@@ -160,73 +160,77 @@
{/if}
-
-
- {#if $nodesQuery.error}
+{#if $nodesQuery.error}
+
+
{$nodesQuery.error.message}
- {:else if $nodesQuery.fetching || $initq.fetching}
+
+
+{:else if $nodesQuery.fetching || $initq.fetching}
+
+
- {:else}
-
- h.host.includes(hostnameFilter) &&
- h.metrics.some(
- (m) => m.name == selectedMetric && m.scope == "node",
- ),
- )
- .map((h) => ({
- host: h.host,
- subCluster: h.subCluster,
- data: h.metrics.find(
- (m) => m.name == selectedMetric && m.scope == "node",
- ),
- disabled: checkMetricDisabled(
- selectedMetric,
- cluster,
- h.subCluster,
- ),
- }))
- .sort((a, b) => a.host.localeCompare(b.host))}
+
+
+{:else}
+
+ h.host.includes(hostnameFilter) &&
+ h.metrics.some(
+ (m) => m.name == selectedMetric && m.scope == "node",
+ ),
+ )
+ .map((h) => ({
+ host: h.host,
+ subCluster: h.subCluster,
+ data: h.metrics.find(
+ (m) => m.name == selectedMetric && m.scope == "node",
+ ),
+ disabled: checkMetricDisabled(
+ selectedMetric,
+ cluster,
+ h.subCluster,
+ ),
+ }))
+ .sort((a, b) => a.host.localeCompare(b.host))}
+ >
+
+ {#if item.disabled === false && item.data}
+ c.name == cluster)}
+ subCluster={item.subCluster}
+ forNode={true}
+ />
+ {:else if item.disabled === true && item.data}
+ Metric disabled for subcluster {selectedMetric}:{item.subCluster}
+ {:else}
+ No dataset returned for {selectedMetric}
-
- {#if item.disabled === false && item.data}
- c.name == cluster)}
- subCluster={item.subCluster}
- forNode={true}
- />
- {:else if item.disabled === true && item.data}
- Metric disabled for subcluster {selectedMetric}:{item.subCluster}
- {:else}
- No dataset returned for {selectedMetric}
- {/if}
-
{/if}
-
-
+
+{/if}
diff --git a/web/frontend/src/User.root.svelte b/web/frontend/src/User.root.svelte
index 61d5420..a2347df 100644
--- a/web/frontend/src/User.root.svelte
+++ b/web/frontend/src/User.root.svelte
@@ -30,7 +30,7 @@
} from "./generic/utils.js";
import JobList from "./generic/JobList.svelte";
import Filters from "./generic/Filters.svelte";
- import PlotTable from "./generic/PlotTable.svelte";
+ import PlotGrid from "./generic/PlotGrid.svelte";
import Histogram from "./generic/plots/Histogram.svelte";
import MetricSelection from "./generic/select/MetricSelection.svelte";
import HistogramSelection from "./generic/select/HistogramSelection.svelte";
@@ -162,7 +162,7 @@
-
+
{#if $stats.error}
{$stats.error.message}
@@ -172,7 +172,7 @@
{:else}
-
+
-
- {#key $stats.data.jobsStatistics[0].histDuration}
-
- {/key}
-
-
- {#key $stats.data.jobsStatistics[0].histNumNodes}
-
- {/key}
-
+
+
+ {#key $stats.data.jobsStatistics[0].histDuration}
+
+ {/key}
+
+
+
+
+ {#key $stats.data.jobsStatistics[0].histNumNodes}
+
+ {/key}
+
+
{/if}
+
{#if metricsInHistograms}
-
- {#if $stats.error}
+ {#if $stats.error}
+
{$stats.error.message}
- {:else if !$stats.data}
+
+ {:else if !$stats.data}
+
- {:else}
-
- {#key $stats.data.jobsStatistics[0].histMetrics}
-
-
-
- {/key}
-
- {/if}
-
+
+ {:else}
+ {#key $stats.data.jobsStatistics[0].histMetrics}
+
+
+
+ {/key}
+ {/if}
{/if}
diff --git a/web/frontend/src/analysis.entrypoint.js b/web/frontend/src/analysis.entrypoint.js
index d889144..07c63f5 100644
--- a/web/frontend/src/analysis.entrypoint.js
+++ b/web/frontend/src/analysis.entrypoint.js
@@ -6,7 +6,8 @@ filterPresets.cluster = cluster
new Analysis({
target: document.getElementById('svelte-app'),
props: {
- filterPresets: filterPresets
+ filterPresets: filterPresets,
+ cluster: cluster
},
context: new Map([
['cc-config', clusterCockpitConfig]
diff --git a/web/frontend/src/generic/PlotGrid.svelte b/web/frontend/src/generic/PlotGrid.svelte
new file mode 100644
index 0000000..1c6c822
--- /dev/null
+++ b/web/frontend/src/generic/PlotGrid.svelte
@@ -0,0 +1,60 @@
+
+
+
+
+{#each rows as row}
+
+ {#each row as item (item)}
+
+
+ {#if !isPlaceholder(item)}
+
+ {/if}
+
+
+ {/each}
+
+{/each}
+
diff --git a/web/frontend/src/generic/plots/MetricPlot.svelte b/web/frontend/src/generic/plots/MetricPlot.svelte
index 7950b04..7386710 100644
--- a/web/frontend/src/generic/plots/MetricPlot.svelte
+++ b/web/frontend/src/generic/plots/MetricPlot.svelte
@@ -549,6 +549,10 @@
onMount(() => {
if (series[0].data.length > 0) {
+ if (forNode) {
+ plotWrapper.style.paddingTop = "0.5rem"
+ plotWrapper.style.paddingBottom = "0.5rem"
+ }
plotWrapper.style.backgroundColor = backgroundColor();
render();
}
@@ -562,7 +566,7 @@
{#if series[0].data.length > 0}
-
+
{:else}
Cannot render plot: No series data returned for {metric}
Math.max(maxX, x), minX);
- let maxY = Y.reduce((maxY, y) => Math.max(maxY, y), minY);
+ let maxX = X ? X.reduce((maxX, x) => Math.max(maxX, x), minX) : 1.0;
+ let maxY = Y ? Y.reduce((maxY, y) => Math.max(maxY, y), minY) : 1.0;
const w = width - paddingLeft - paddingRight;
const h = height - paddingTop - paddingBottom;
@@ -68,24 +68,26 @@
// Draw Data
let size = 3
- if (S) {
+ if (S && X && Y) {
let max = S.reduce((max, s, i) => (X[i] == null || Y[i] == null || Number.isNaN(X[i]) || Number.isNaN(Y[i])) ? max : Math.max(max, s), 0)
size = (w / 15) / max
}
ctx.fillStyle = color;
- for (let i = 0; i < X.length; i++) {
- let x = X[i], y = Y[i];
- if (x == null || y == null || Number.isNaN(x) || Number.isNaN(y))
- continue;
+ if (X?.length > 0) {
+ for (let i = 0; i < X.length; i++) {
+ let x = X[i], y = Y[i];
+ if (x == null || y == null || Number.isNaN(x) || Number.isNaN(y))
+ continue;
- const s = S ? S[i] * size : size;
- const px = getCanvasX(x);
- const py = getCanvasY(y);
+ const s = S ? S[i] * size : size;
+ const px = getCanvasX(x);
+ const py = getCanvasY(y);
- ctx.beginPath();
- ctx.arc(px, py, s, 0, Math.PI * 2, false);
- ctx.fill();
+ ctx.beginPath();
+ ctx.arc(px, py, s, 0, Math.PI * 2, false);
+ ctx.fill();
+ }
}
// Axes
diff --git a/web/frontend/src/generic/utils.js b/web/frontend/src/generic/utils.js
index 8a818ab..57248fc 100644
--- a/web/frontend/src/generic/utils.js
+++ b/web/frontend/src/generic/utils.js
@@ -397,16 +397,18 @@ function getMetricConfigDeep(metric, cluster, subCluster) {
export function convert2uplot(canvasData) {
// Prep: Uplot Data Structure
let uplotData = [[],[]] // [X, Y1, Y2, ...]
- // Iterate
- canvasData.forEach( cd => {
- if (Object.keys(cd).length == 4) { // MetricHisto Datafromat
- uplotData[0].push(cd?.max ? cd.max : 0)
- uplotData[1].push(cd.count)
- } else { // Default
- uplotData[0].push(cd.value)
- uplotData[1].push(cd.count)
- }
- })
+ // Iterate if exists
+ if (canvasData) {
+ canvasData.forEach( cd => {
+ if (Object.keys(cd).length == 4) { // MetricHisto Datafromat
+ uplotData[0].push(cd?.max ? cd.max : 0)
+ uplotData[1].push(cd.count)
+ } else { // Default
+ uplotData[0].push(cd.value)
+ uplotData[1].push(cd.count)
+ }
+ })
+ }
return uplotData
}
diff --git a/web/frontend/src/job/Metric.svelte b/web/frontend/src/job/Metric.svelte
index 4b4c8d0..ab1616a 100644
--- a/web/frontend/src/job/Metric.svelte
+++ b/web/frontend/src/job/Metric.svelte
@@ -171,7 +171,7 @@
);
-
+
{metricName} ({unit})