Reduce uplot example code to common

denominator
This commit is contained in:
Christoph Kluge 2023-09-04 10:37:20 +02:00
parent f5c43d60d3
commit c1b5134627
2 changed files with 151 additions and 92 deletions

View File

@ -33,7 +33,8 @@
let plotWidths = [], let plotWidths = [],
colWidth1 = 0, colWidth1 = 0,
colWidth2; colWidth2 = 0,
colWidth3 = 0;
let from = new Date(Date.now() - 5 * 60 * 1000), let from = new Date(Date.now() - 5 * 60 * 1000),
to = new Date(Date.now()); to = new Date(Date.now());
const topOptions = [ const topOptions = [
@ -668,7 +669,10 @@
</Row> </Row>
<Row> <Row>
<Col> <Col>
<Rooflineuplot/> <div bind:clientWidth={colWidth3}>
<Rooflineuplot
width={colWidth3 - 25}
/>
</Col> </Col>
</Row> </Row>
{/if} {/if}

View File

@ -4,10 +4,28 @@
import { onMount, onDestroy } from 'svelte' import { onMount, onDestroy } from 'svelte'
import { Card } from 'sveltestrap' import { Card } from 'sveltestrap'
export let flopsAny = null
export let memBw = null
export let cluster = null
export let maxY = null
export let width = 500
export let height = 300
export let tiles = null
export let colorDots = true
export let showTime = true
export let data = null
let plotWrapper = null let plotWrapper = null
let uplot = null let uplot = null
let timeoutId = null let timeoutId = null
// Three Render-Cases:
// #1 Single-Job Roofline -> Has Time-Information: Use data, allow colorDots && showTime
// #2 MultiNode Roofline - > Has No Time-Information: Transform from nodeData, only "IST"-state of nodes, no timeInfo
// #3 Multi-Job Roofline -> No Time Information? -> Use Backend-Prepared "Tiles" with increasing occupancy for stronger values
// Start Demo Data
function randInt(min, max) { function randInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min; return Math.floor(Math.random() * (max - min + 1)) + min;
} }
@ -27,21 +45,52 @@
return arr; return arr;
} }
let points = 10000; let points = 100;
let series = 5; let series = 2;
let time = []
console.time("prep"); for (let i = 0; i < points; ++i)
time[i] = i;
let data = filledArr(series, v => [ data = filledArr(series, v => [
filledArr(points, i => randInt(0,500)), filledArr(points, i => randInt(0,200)),
filledArr(points, i => randInt(0,500)), filledArr(points, i => randInt(0,200)),
]); ]);
data[0] = null; data[0] = null;
console.timeEnd("prep"); console.log("Data: ", data);
console.log(data); // End Demo Data
// Helpers
function getGradientR(x) {
if (x < 0.5) return 0
if (x > 0.75) return 255
x = (x - 0.5) * 4.0
return Math.floor(x * 255.0)
}
function getGradientG(x) {
if (x > 0.25 && x < 0.75) return 255
if (x < 0.25) x = x * 4.0
else x = 1.0 - (x - 0.75) * 4.0
return Math.floor(x * 255.0)
}
function getGradientB(x) {
if (x < 0.25) return 255
if (x > 0.5) return 0
x = 1.0 - (x - 0.25) * 4.0
return Math.floor(x * 255.0)
}
function getRGB(c) {
return `rgb(${getGradientR(c)}, ${getGradientG(c)}, ${getGradientB(c)})`
}
// End Helpers
const drawPoints = (u, seriesIdx, idx0, idx1) => { const drawPoints = (u, seriesIdx, idx0, idx1) => {
const size = 5 * devicePixelRatio; const size = 5 * devicePixelRatio;
@ -53,8 +102,6 @@
let deg360 = 2 * Math.PI; let deg360 = 2 * Math.PI;
console.time("points");
let p = new Path2D(); let p = new Path2D();
for (let i = 0; i < d[0].length; i++) { for (let i = 0; i < d[0].length; i++) {
@ -70,20 +117,12 @@
} }
} }
console.timeEnd("points1");
u.ctx.fill(p); u.ctx.fill(p);
}); });
return null; return null;
}; };
let pxRatio;
function setPxRatio() {
pxRatio = devicePixelRatio;
}
function guardedRange(u, min, max) { function guardedRange(u, min, max) {
if (max == min) { if (max == min) {
if (min == null) { if (min == null) {
@ -100,83 +139,99 @@
return [min, max]; return [min, max];
} }
setPxRatio(); function render() {
const opts = {
window.addEventListener('dppxchange', setPxRatio); title: "",
mode: 2,
const opts = { width: width,
title: "Scatter Plot", height: height,
mode: 2, legend: {
width: 1920, live: false,
height: 600, },
legend: { hooks: {
live: false, drawClear: [
}, u => {
hooks: { u.series.forEach((s, i) => {
drawClear: [ if (i > 0)
u => { s._paths = null;
u.series.forEach((s, i) => { });
if (i > 0) },
s._paths = null; ],
}); },
scales: {
x: {
time: false,
// auto: false,
// range: [0, 500],
// remove any scale padding, use raw data limits
range: guardedRange,
}, },
y: {
// auto: false,
// range: [0, 500],
// remove any scale padding, use raw data limits
range: guardedRange,
},
},
series: [
{
/*
stroke: "red",
fill: "rgba(255,0,0,0.1)",
paths: (u, seriesIdx, idx0, idx1) => {
uPlot.orient(u, seriesIdx, (series, dataX, dataY, scaleX, scaleY, valToPosX, valToPosY, xOff, yOff, xDim, yDim) => {
let d = u.data[seriesIdx];
console.log(d);
});
return null;
},
*/
},
{
stroke: (u, seriesIdx) => {
for (let i = 0; i < points; ++i) { return getRGB(time[i]) }
},
fill: (u, seriesIdx) => {
for (let i = 0; i < points; ++i) { return getRGB(time[i]) }
},
paths: drawPoints,
}
], ],
}, };
scales: {
x: {
time: false,
// auto: false,
// range: [0, 500],
// remove any scale padding, use raw data limits
range: guardedRange,
},
y: {
// auto: false,
// range: [0, 500],
// remove any scale padding, use raw data limits
range: guardedRange,
},
},
series: [
{
/*
stroke: "red",
fill: "rgba(255,0,0,0.1)",
paths: (u, seriesIdx, idx0, idx1) => {
uPlot.orient(u, seriesIdx, (series, dataX, dataY, scaleX, scaleY, valToPosX, valToPosY, xOff, yOff, xDim, yDim) => {
let d = u.data[seriesIdx];
console.log(d); uplot = new uPlot(opts, data, plotWrapper);
}); }
return null; // Copied from Histogram
},
*/
},
{
stroke: "red",
fill: "rgba(255,0,0,0.1)",
paths: drawPoints,
},
{
stroke: "green",
fill: "rgba(0,255,0,0.1)",
paths: drawPoints,
},
{
stroke: "blue",
fill: "rgba(0,0,255,0.1)",
paths: drawPoints,
},
{
stroke: "magenta",
fill: "rgba(0,0,255,0.1)",
paths: drawPoints,
},
],
};
let u = new uPlot(opts, data, document.body); onMount(() => {
render()
})
onDestroy(() => {
if (uplot)
uplot.destroy()
if (timeoutId != null)
clearTimeout(timeoutId)
})
function sizeChanged() {
if (timeoutId != null)
clearTimeout(timeoutId)
timeoutId = setTimeout(() => {
timeoutId = null
if (uplot)
uplot.destroy()
render()
}, 200)
}
$: sizeChanged(width, height)
</script> </script>