mirror of https://github.com/prometheus/prometheus
Show single samples without neighbors as dots
Signed-off-by: Julius Volz <julius.volz@gmail.com>pull/14872/head
parent
7ea75c75c0
commit
3ecc13b330
|
@ -234,6 +234,67 @@ const autoPadLeft = (
|
||||||
return Math.ceil(axisSize);
|
return Math.ceil(axisSize);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// This filter functions ensures that only points that are disconnected
|
||||||
|
// from their neighbors are drawn. Otherwise, we just draw line segments
|
||||||
|
// without dots on them.
|
||||||
|
//
|
||||||
|
// Adapted from https://github.com/leeoniya/uPlot/blob/91de800538ee5d6f45f448d98b660a4a658e587b/demos/points.html#L15-L64
|
||||||
|
const onlyDrawPointsForDisconnectedSamplesFilter = (
|
||||||
|
u: uPlot,
|
||||||
|
seriesIdx: number,
|
||||||
|
show: boolean,
|
||||||
|
gaps?: null | number[][]
|
||||||
|
) => {
|
||||||
|
const filtered = [];
|
||||||
|
|
||||||
|
const series = u.series[seriesIdx];
|
||||||
|
|
||||||
|
if (!show && gaps && gaps.length) {
|
||||||
|
const [firstIdx, lastIdx] = series.idxs!;
|
||||||
|
const xData = u.data[0];
|
||||||
|
const yData = u.data[seriesIdx];
|
||||||
|
const firstPos = Math.round(u.valToPos(xData[firstIdx], "x", true));
|
||||||
|
const lastPos = Math.round(u.valToPos(xData[lastIdx], "x", true));
|
||||||
|
|
||||||
|
if (gaps[0][0] === firstPos) {
|
||||||
|
filtered.push(firstIdx);
|
||||||
|
}
|
||||||
|
|
||||||
|
// show single points between consecutive gaps that share end/start
|
||||||
|
for (let i = 0; i < gaps.length; i++) {
|
||||||
|
const thisGap = gaps[i];
|
||||||
|
const nextGap = gaps[i + 1];
|
||||||
|
|
||||||
|
if (nextGap && thisGap[1] === nextGap[0]) {
|
||||||
|
// approx when data density is > 1pt/px, since gap start/end pixels are rounded
|
||||||
|
let approxIdx = u.posToIdx(thisGap[1], true);
|
||||||
|
|
||||||
|
if (yData[approxIdx] == null) {
|
||||||
|
// scan left/right alternating to find closest index with non-null value
|
||||||
|
for (let j = 1; j < 100; j++) {
|
||||||
|
if (yData[approxIdx + j] != null) {
|
||||||
|
approxIdx += j;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (yData[approxIdx - j] != null) {
|
||||||
|
approxIdx -= j;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
filtered.push(approxIdx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gaps[gaps.length - 1][1] === lastPos) {
|
||||||
|
filtered.push(lastIdx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return filtered.length ? filtered : null;
|
||||||
|
};
|
||||||
|
|
||||||
const getOptions = (
|
const getOptions = (
|
||||||
width: number,
|
width: number,
|
||||||
result: RangeSamples[],
|
result: RangeSamples[],
|
||||||
|
@ -320,6 +381,9 @@ const getOptions = (
|
||||||
{},
|
{},
|
||||||
...result.map(
|
...result.map(
|
||||||
(r, idx): uPlot.Series => ({
|
(r, idx): uPlot.Series => ({
|
||||||
|
points: {
|
||||||
|
filter: onlyDrawPointsForDisconnectedSamplesFilter,
|
||||||
|
},
|
||||||
label: formatSeries(r.metric),
|
label: formatSeries(r.metric),
|
||||||
width: 1.5,
|
width: 1.5,
|
||||||
// @ts-expect-error - uPlot doesn't have a field for labels, but we just attach some anyway.
|
// @ts-expect-error - uPlot doesn't have a field for labels, but we just attach some anyway.
|
||||||
|
|
Loading…
Reference in New Issue