Merge pull request #193 from ClusterCockpit/71_improve_systemsview

71 improve systemsview
This commit is contained in:
Jan Eitzinger 2023-08-11 10:54:04 +02:00 committed by GitHub
commit ea0c0de687
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 48 additions and 8 deletions

View File

@ -11,6 +11,7 @@
} from "sveltestrap"; } from "sveltestrap";
import { queryStore, gql, getContextClient } from "@urql/svelte"; import { queryStore, gql, getContextClient } from "@urql/svelte";
import TimeSelection from "./filters/TimeSelection.svelte"; import TimeSelection from "./filters/TimeSelection.svelte";
import Refresher from './joblist/Refresher.svelte';
import PlotTable from "./PlotTable.svelte"; import PlotTable from "./PlotTable.svelte";
import MetricPlot from "./plots/MetricPlot.svelte"; import MetricPlot from "./plots/MetricPlot.svelte";
import { getContext } from "svelte"; import { getContext } from "svelte";
@ -160,6 +161,13 @@
No currently running jobs. No currently running jobs.
{/if} {/if}
</Col> </Col>
<Col>
<Refresher on:reload={() => {
const diff = Date.now() - to
from = new Date(from.getTime() + diff)
to = new Date(to.getTime() + diff)
}} />
</Col>
<Col> <Col>
<TimeSelection bind:from bind:to /> <TimeSelection bind:from bind:to />
</Col> </Col>

View File

@ -1,5 +1,6 @@
<script> <script>
import { init, checkMetricDisabled } from './utils.js' import { init, checkMetricDisabled } from './utils.js'
import Refresher from './joblist/Refresher.svelte'
import { Row, Col, Input, InputGroup, InputGroupText, Icon, Spinner, Card } from 'sveltestrap' import { Row, Col, Input, InputGroup, InputGroupText, Icon, Spinner, Card } from 'sveltestrap'
import { queryStore, gql, getContextClient } from '@urql/svelte' import { queryStore, gql, getContextClient } from '@urql/svelte'
import TimeSelection from './filters/TimeSelection.svelte' import TimeSelection from './filters/TimeSelection.svelte'
@ -78,6 +79,13 @@
{:else if $initq.fetching} {:else if $initq.fetching}
<Spinner/> <Spinner/>
{:else} {:else}
<Col>
<Refresher on:reload={() => {
const diff = Date.now() - to
from = new Date(from.getTime() + diff)
to = new Date(to.getTime() + diff)
}} />
</Col>
<Col> <Col>
<TimeSelection <TimeSelection
bind:from={from} bind:from={from}

View File

@ -7,6 +7,7 @@
export let customEnabled = true export let customEnabled = true
export let anyEnabled = false export let anyEnabled = false
export let options = { export let options = {
'Last quarter hour': 15*60,
'Last half hour': 30*60, 'Last half hour': 30*60,
'Last hour': 60*60, 'Last hour': 60*60,
'Last 2hrs': 2*60*60, 'Last 2hrs': 2*60*60,

View File

@ -38,6 +38,7 @@
export let cluster export let cluster
export let subCluster export let subCluster
export let isShared = false export let isShared = false
export let forNode = false
if (useStatsSeries == null) if (useStatsSeries == null)
useStatsSeries = statisticsSeries != null useStatsSeries = statisticsSeries != null
@ -160,17 +161,34 @@
: null : null
const plotSeries = [{label: 'Runtime', value: (u, ts, sidx, didx) => didx == null ? null : formatTime(ts)}] const plotSeries = [{label: 'Runtime', value: (u, ts, sidx, didx) => didx == null ? null : formatTime(ts)}]
const plotData = [new Array(longestSeries)] const plotData = [new Array(longestSeries)]
for (let i = 0; i < longestSeries; i++) // TODO: Cache/Reuse this array?
plotData[0][i] = i * timestep if (forNode === true) {
// Negative Timestamp Buildup
for (let i = 0; i <= longestSeries; i++) {
plotData[0][i] = (longestSeries - i) * timestep * -1
}
} else {
// Positive Timestamp Buildup
for (let j = 0; j < longestSeries; j++) // TODO: Cache/Reuse this array?
plotData[0][j] = j * timestep
}
let plotBands = undefined let plotBands = undefined
if (useStatsSeries) { if (useStatsSeries) {
plotData.push(statisticsSeries.min) plotData.push(statisticsSeries.min)
plotData.push(statisticsSeries.max) plotData.push(statisticsSeries.max)
plotData.push(statisticsSeries.mean) plotData.push(statisticsSeries.mean)
if (forNode === true) { // timestamp 0 with null value for reversed time axis
if (plotData[1].length != 0) plotData[1].push(null)
if (plotData[2].length != 0) plotData[2].push(null)
if (plotData[3].length != 0) plotData[3].push(null)
}
plotSeries.push({ label: 'min', scale: 'y', width: lineWidth, stroke: 'red' }) plotSeries.push({ label: 'min', scale: 'y', width: lineWidth, stroke: 'red' })
plotSeries.push({ label: 'max', scale: 'y', width: lineWidth, stroke: 'green' }) plotSeries.push({ label: 'max', scale: 'y', width: lineWidth, stroke: 'green' })
plotSeries.push({ label: 'mean', scale: 'y', width: lineWidth, stroke: 'black' }) plotSeries.push({ label: 'mean', scale: 'y', width: lineWidth, stroke: 'black' })
plotBands = [ plotBands = [
{ series: [2,3], fill: 'rgba(0,255,0,0.1)' }, { series: [2,3], fill: 'rgba(0,255,0,0.1)' },
{ series: [3,1], fill: 'rgba(255,0,0,0.1)' } { series: [3,1], fill: 'rgba(255,0,0,0.1)' }
@ -178,6 +196,7 @@
} else { } else {
for (let i = 0; i < series.length; i++) { for (let i = 0; i < series.length; i++) {
plotData.push(series[i].data) plotData.push(series[i].data)
if (forNode === true && plotData[1].length != 0) plotData[1].push(null) // timestamp 0 with null value for reversed time axis
plotSeries.push({ plotSeries.push({
label: scope === 'node' ? resources[i].hostname : label: scope === 'node' ? resources[i].hostname :
// scope === 'accelerator' ? resources[0].accelerators[i] : // scope === 'accelerator' ? resources[0].accelerators[i] :
@ -200,7 +219,7 @@
{ {
scale: 'x', scale: 'x',
space: 35, space: 35,
incrs: timeIncrs(timestep, maxX), incrs: timeIncrs(timestep, maxX, forNode),
values: (_, vals) => vals.map(v => formatTime(v)) values: (_, vals) => vals.map(v => formatTime(v))
}, },
{ {
@ -340,12 +359,16 @@
} }
} }
export function timeIncrs(timestep, maxX) { export function timeIncrs(timestep, maxX, forNode) {
let incrs = [] if (forNode === true) {
for (let t = timestep; t < maxX; t *= 10) return [60, 300, 900, 1800, 3600, 7200, 14400, 21600] // forNode fixed increments
incrs.push(t, t * 2, t * 3, t * 5) } else {
let incrs = []
for (let t = timestep; t < maxX; t *= 10)
incrs.push(t, t * 2, t * 3, t * 5)
return incrs return incrs
}
} }
export function findThresholds(metricConfig, scope, subCluster) { export function findThresholds(metricConfig, scope, subCluster) {