diff --git a/internal/graph/schema.resolvers.go b/internal/graph/schema.resolvers.go
index 3e142f9a..9bc8811d 100644
--- a/internal/graph/schema.resolvers.go
+++ b/internal/graph/schema.resolvers.go
@@ -905,26 +905,32 @@ func (r *queryResolver) ClusterMetrics(ctx context.Context, cluster string, metr
for _, metrics := range data {
clusterMetrics.NodeCount += 1
for metric, scopedMetrics := range metrics {
- _, ok := collectorData[metric]
- if !ok {
- collectorData[metric] = make([]schema.Float, 0)
- for _, scopedMetric := range scopedMetrics {
- // Collect Info
+ for _, scopedMetric := range scopedMetrics {
+ // Collect Info Once
+ _, okTimestep := collectorTimestep[metric]
+ if !okTimestep {
collectorTimestep[metric] = scopedMetric.Timestep
- collectorUnit[metric] = scopedMetric.Unit
- // Collect Initial Data
- for _, ser := range scopedMetric.Series {
- collectorData[metric] = append(collectorData[metric], ser.Data...)
- }
}
- } else {
- // Sum up values by index
- for _, scopedMetric := range scopedMetrics {
- // For This Purpose (Cluster_Wide-Sum of Node Metrics) OK
- for _, ser := range scopedMetric.Series {
+ _, okUnit := collectorUnit[metric]
+ if !okUnit {
+ collectorUnit[metric] = scopedMetric.Unit
+ }
+ // Collect Data
+ for _, ser := range scopedMetric.Series {
+ _, okData := collectorData[metric]
+ // Init With Datasize > 0
+ if !okData && len(ser.Data) != 0 {
+ collectorData[metric] = make([]schema.Float, len(ser.Data))
+ } else if !okData {
+ cclog.Debugf("ClusterMetrics Skip Init: No Data -> %s at %s; Size %d", metric, ser.Hostname, len(ser.Data))
+ }
+ // Sum if init'd and matching size
+ if okData && len(ser.Data) == len(collectorData[metric]) {
for i, val := range ser.Data {
collectorData[metric][i] += val
}
+ } else if okData {
+ cclog.Debugf("ClusterMetrics Skip Sum: Data Diff -> %s at %s; Want Size %d, Have Size %d", metric, ser.Hostname, len(collectorData[metric]), len(ser.Data))
}
}
}
diff --git a/web/frontend/src/DashPublic.root.svelte b/web/frontend/src/DashPublic.root.svelte
index 91f4664c..9c17e7d8 100644
--- a/web/frontend/src/DashPublic.root.svelte
+++ b/web/frontend/src/DashPublic.root.svelte
@@ -286,6 +286,8 @@
sort((a, b) => b.count - a.count)
});
+ const sortedClusterMetrics = $derived($statusQuery?.data?.clusterMetrics?.metrics.sort((a, b) => b.name.localeCompare(a.name)));
+
/* Functions */
function transformNodesStatsToData(subclusterData) {
let data = null
@@ -516,10 +518,10 @@
Cluster Utilization (
- {`${$statusQuery?.data?.clusterMetrics?.metrics[0]?.name} (${$statusQuery?.data?.clusterMetrics?.metrics[0]?.unit?.prefix}${$statusQuery?.data?.clusterMetrics?.metrics[0]?.unit?.base})`}
+ {`${sortedClusterMetrics[0]?.name} (${sortedClusterMetrics[0]?.unit?.prefix}${sortedClusterMetrics[0]?.unit?.base})`}
,
- {`${$statusQuery?.data?.clusterMetrics?.metrics[1]?.name} (${$statusQuery?.data?.clusterMetrics?.metrics[1]?.unit?.prefix}${$statusQuery?.data?.clusterMetrics?.metrics[1]?.unit?.base})`}
+ {`${sortedClusterMetrics[1]?.name} (${sortedClusterMetrics[1]?.unit?.prefix}${sortedClusterMetrics[1]?.unit?.base})`}
)
@@ -528,7 +530,7 @@
diff --git a/web/frontend/src/generic/plots/DoubleMetricPlot.svelte b/web/frontend/src/generic/plots/DoubleMetricPlot.svelte
index c865dd68..e94e269d 100644
--- a/web/frontend/src/generic/plots/DoubleMetricPlot.svelte
+++ b/web/frontend/src/generic/plots/DoubleMetricPlot.svelte
@@ -4,7 +4,7 @@
Only width/height should change reactively.
Properties:
- - `metricData [Data]`: Two series of metric data including unit info
+ - `metricData [Data]`: Two series of metric data including unit info, unsorted
- `timestep Number`: Data timestep
- `numNodes Number`: Number of nodes from which metric data is aggregated
- `cluster String`: Cluster name of the parent job / data [Default: ""]
@@ -46,10 +46,11 @@
let uplot = $state(null);
/* Derived */
+ const sortedMetricData = $derived(publicMode ? [...metricData] : metricData.sort((a, b) => b.name.localeCompare(a.name))); // PublicMode: Presorted
const maxX = $derived(longestSeries * timestep);
const lineWidth = $derived(publicMode ? 2 : clusterCockpitConfig.plotConfiguration_lineWidth / window.devicePixelRatio);
const longestSeries = $derived.by(() => {
- return metricData.reduce((n, m) => Math.max(n, m.data.length), 0);
+ return sortedMetricData.reduce((n, m) => Math.max(n, m.data.length), 0);
});
// Derive Plot Params
@@ -68,8 +69,8 @@
};
};
// Y
- for (let i = 0; i < metricData.length; i++) {
- pendingData.push(metricData[i]?.data);
+ for (let i = 0; i < sortedMetricData.length; i++) {
+ pendingData.push(sortedMetricData[i]?.data);
};
return pendingData;
})
@@ -84,9 +85,9 @@
}
];
// Y
- for (let i = 0; i < metricData.length; i++) {
+ for (let i = 0; i < sortedMetricData.length; i++) {
pendingSeries.push({
- label: publicMode ? null : `${metricData[i]?.name} (${metricData[i]?.unit?.prefix}${metricData[i]?.unit?.base})`,
+ label: publicMode ? null : `${sortedMetricData[i]?.name} (${sortedMetricData[i]?.unit?.prefix}${sortedMetricData[i]?.unit?.base})`,
scale: `y${i+1}`,
width: lineWidth,
stroke: fixedLineColors[i],
@@ -156,9 +157,9 @@
// X
baseOpts.axes[0].label = 'Time';
// Y1
- baseOpts.axes[1].label = `${metricData[0]?.name} (${metricData[0]?.unit?.prefix}${metricData[0]?.unit?.base})`;
+ baseOpts.axes[1].label = `${sortedMetricData[0]?.name} (${sortedMetricData[0]?.unit?.prefix}${sortedMetricData[0]?.unit?.base})`;
// Y2
- baseOpts.axes[2].label = `${metricData[1]?.name} (${metricData[1]?.unit?.prefix}${metricData[1]?.unit?.base})`;
+ baseOpts.axes[2].label = `${sortedMetricData[1]?.name} (${sortedMetricData[1]?.unit?.prefix}${sortedMetricData[1]?.unit?.base})`;
baseOpts.hooks.draw = [
(u) => {
// Draw plot type label:
@@ -212,7 +213,7 @@
style = { backgroundColor: "rgba(255, 249, 196, 0.92)", color: "black" },
} = {}) {
let legendEl;
- const dataSize = metricData.length;
+ const dataSize = sortedMetricData.length;
function init(u, opts) {
legendEl = u.root.querySelector(".u-legend");
@@ -311,7 +312,7 @@
-{#if metricData[0]?.data && metricData[0]?.data?.length > 0}
+{#if sortedMetricData[0]?.data && sortedMetricData[0]?.data?.length > 0}