diff --git a/web/frontend/src/generic/JobCompare.svelte b/web/frontend/src/generic/JobCompare.svelte index 2920eea..c5498f9 100644 --- a/web/frontend/src/generic/JobCompare.svelte +++ b/web/frontend/src/generic/JobCompare.svelte @@ -23,94 +23,91 @@ import { formatTime, roundTwoDigits } from "./units.js"; import Comparogram from "./plots/Comparogram.svelte"; - const ccconfig = getContext("cc-config"), - // initialized = getContext("initialized"), - globalMetrics = getContext("globalMetrics"); + /* Svelte 5 Props */ + let { + matchedCompareJobs = $bindable(0), + metrics = $bindable(ccconfig?.plot_list_selectedMetrics), + filterBuffer = [], + } = $props(); - export let matchedCompareJobs = 0; - export let metrics = ccconfig.plot_list_selectedMetrics; - export let filterBuffer = []; - - let filter = [...filterBuffer] || []; - let comparePlotData = {}; - let compareTableData = []; - let compareTableSorting = {}; - let jobIds = []; - let jobClusters = []; - let tableJobIDFilter = ""; - - /*uPlot*/ - let plotSync = uPlot.sync("compareJobsView"); - - /* GQL */ - const client = getContextClient(); + /* Const Init */ + const client = getContextClient(); + const ccconfig = getContext("cc-config"); + const globalMetrics = getContext("globalMetrics"); + // const initialized = getContext("initialized"); // Pull All Series For Metrics Statistics Only On Node Scope const compareQuery = gql` - query ($filter: [JobFilter!]!, $metrics: [String!]!) { - jobsMetricStats(filter: $filter, metrics: $metrics) { - id - jobId - startTime - duration - cluster - subCluster - numNodes - numHWThreads - numAccelerators - stats { - name - data { - min - avg - max + query ($filter: [JobFilter!]!, $metrics: [String!]!) { + jobsMetricStats(filter: $filter, metrics: $metrics) { + id + jobId + startTime + duration + cluster + subCluster + numNodes + numHWThreads + numAccelerators + stats { + name + data { + min + avg + max + } } } } - } `; - /* REACTIVES */ + /* Var Init*/ + let plotSync = uPlot.sync("compareJobsView"); - $: compareData = queryStore({ - client: client, - query: compareQuery, - variables:{ filter, metrics }, - }); + /* State Init */ + let filter = $state([...filterBuffer] || []); + let tableJobIDFilter = $state(""); - $: matchedCompareJobs = $compareData.data != null ? $compareData.data.jobsMetricStats.length : -1; - - $: if ($compareData.data != null) { - jobIds = []; - jobClusters = []; - comparePlotData = {}; - compareTableData = [...$compareData.data.jobsMetricStats]; - jobs2uplot($compareData.data.jobsMetricStats, metrics); - } - - $: if ((!$compareData.fetching && !$compareData.error) && metrics) { + /* Derived*/ + const compareData = $derived(queryStore({ + client: client, + query: compareQuery, + variables:{ filter, metrics }, + }) + ); + let jobIds = $derived($compareData?.data ? $compareData.data.jobsMetricStats.map((jms) => jms.jobId) : []); + let jobClusters = $derived($compareData?.data ? $compareData.data.jobsMetricStats.map((jms) => `${jms.cluster} ${jms.subCluster}`) : []); + let compareTableData = $derived($compareData?.data ? [...$compareData.data.jobsMetricStats] : []); + let comparePlotData = $derived($compareData?.data ? jobs2uplot($compareData.data.jobsMetricStats, metrics) : {}); + let compareTableSorting = $derived.by(() => { + let pendingSort = {}; // Meta - compareTableSorting['meta'] = { + pendingSort['meta'] = { startTime: { dir: "down", active: true }, duration: { dir: "up", active: false }, cluster: { dir: "up", active: false }, }; // Resources - compareTableSorting['resources'] = { + pendingSort['resources'] = { Nodes: { dir: "up", active: false }, Threads: { dir: "up", active: false }, Accs: { dir: "up", active: false }, }; - // Metrics for (let metric of metrics) { - compareTableSorting[metric] = { + pendingSort[metric] = { min: { dir: "up", active: false }, avg: { dir: "up", active: false }, max: { dir: "up", active: false }, }; } - } + return pendingSort; + }); - /* FUNCTIONS */ + /* Effect */ + $effect(() => { + matchedCompareJobs = $compareData?.data != null ? $compareData.data.jobsMetricStats.length : -1; + }); + + /* Functions */ // (Re-)query and optionally set new filters; Query will be started reactively. export function queryJobs(filters) { if (filters != null) { @@ -178,42 +175,42 @@ } function jobs2uplot(jobs, metrics) { + // Proxy Init + let pendingComparePlotData = {}; // Resources Init - comparePlotData['resources'] = {unit:'', data: [[],[],[],[],[],[]]} // data: [X, XST, XRT, YNODES, YTHREADS, YACCS] + pendingComparePlotData['resources'] = {unit:'', data: [[],[],[],[],[],[]]} // data: [X, XST, XRT, YNODES, YTHREADS, YACCS] // Metric Init for (let m of metrics) { // Get Unit const rawUnit = globalMetrics.find((gm) => gm.name == m)?.unit const metricUnit = (rawUnit?.prefix ? rawUnit.prefix : "") + (rawUnit?.base ? rawUnit.base : "") - comparePlotData[m] = {unit: metricUnit, data: [[],[],[],[],[],[]]} // data: [X, XST, XRT, YMIN, YAVG, YMAX] + pendingComparePlotData[m] = {unit: metricUnit, data: [[],[],[],[],[],[]]} // data: [X, XST, XRT, YMIN, YAVG, YMAX] } // Iterate jobs if exists if (jobs) { let plotIndex = 0 jobs.forEach((j) => { - // Collect JobIDs & Clusters for X-Ticks and Legend - jobIds.push(j.jobId) - jobClusters.push(`${j.cluster} ${j.subCluster}`) // Resources - comparePlotData['resources'].data[0].push(plotIndex) - comparePlotData['resources'].data[1].push(j.startTime) - comparePlotData['resources'].data[2].push(j.duration) - comparePlotData['resources'].data[3].push(j.numNodes) - comparePlotData['resources'].data[4].push(j?.numHWThreads?j.numHWThreads:0) - comparePlotData['resources'].data[5].push(j?.numAccelerators?j.numAccelerators:0) + pendingComparePlotData['resources'].data[0].push(plotIndex) + pendingComparePlotData['resources'].data[1].push(j.startTime) + pendingComparePlotData['resources'].data[2].push(j.duration) + pendingComparePlotData['resources'].data[3].push(j.numNodes) + pendingComparePlotData['resources'].data[4].push(j?.numHWThreads?j.numHWThreads:0) + pendingComparePlotData['resources'].data[5].push(j?.numAccelerators?j.numAccelerators:0) // Metrics for (let s of j.stats) { - comparePlotData[s.name].data[0].push(plotIndex) - comparePlotData[s.name].data[1].push(j.startTime) - comparePlotData[s.name].data[2].push(j.duration) - comparePlotData[s.name].data[3].push(s.data.min) - comparePlotData[s.name].data[4].push(s.data.avg) - comparePlotData[s.name].data[5].push(s.data.max) + pendingComparePlotData[s.name].data[0].push(plotIndex) + pendingComparePlotData[s.name].data[1].push(j.startTime) + pendingComparePlotData[s.name].data[2].push(j.duration) + pendingComparePlotData[s.name].data[3].push(s.data.min) + pendingComparePlotData[s.name].data[4].push(s.data.avg) + pendingComparePlotData[s.name].data[5].push(s.data.max) } plotIndex++ }) } + return {...pendingComparePlotData}; } // Adapt for Persisting Job Selections in DB later down the line @@ -242,7 +239,6 @@ // } // }); // } - {#if $compareData.fetching} @@ -269,7 +265,7 @@ xticks={jobIds} xinfo={jobClusters} ylabel={'Resource Counts'} - data={comparePlotData['resources'].data} + data={comparePlotData['resources']?.data} {plotSync} forResources /> @@ -285,8 +281,8 @@ xinfo={jobClusters} ylabel={m} metric={m} - yunit={comparePlotData[m].unit} - data={comparePlotData[m].data} + yunit={comparePlotData[m]?.unit} + data={comparePlotData[m]?.data} {plotSync} /> @@ -318,7 +314,7 @@ -