TimeSeries/Trend: Fix sparse points rendering heuristic (#107279)

This commit is contained in:
Leon Sorokin
2025-07-01 15:03:53 -05:00
committed by GitHub
parent fe7ca61a51
commit 79c39e7907
2 changed files with 309 additions and 85 deletions
@@ -21,10 +21,10 @@
}
]
},
"description": "",
"editable": true,
"fiscalYearStartMonth": 0,
"graphTooltip": 0,
"id": 21273,
"links": [
{
"asDropdown": true,
@@ -37,9 +37,9 @@
"type": "dashboards"
}
],
"liveNow": false,
"panels": [
{
"collapsed": false,
"gridPos": {
"h": 1,
"w": 24,
@@ -47,6 +47,7 @@
"y": 0
},
"id": 44,
"panels": [],
"title": "Enums",
"type": "row"
},
@@ -99,7 +100,7 @@
"steps": [
{
"color": "green",
"value": null
"value": 0
},
{
"color": "red",
@@ -162,6 +163,7 @@
"sort": "none"
}
},
"pluginVersion": "12.1.0-pre",
"targets": [
{
"datasource": {
@@ -209,6 +211,7 @@
"mode": "thresholds"
},
"custom": {
"axisPlacement": "auto",
"fillOpacity": 70,
"hideFrom": {
"legend": false,
@@ -225,7 +228,7 @@
"steps": [
{
"color": "green",
"value": null
"value": 0
},
{
"color": "red",
@@ -282,6 +285,7 @@
"sort": "none"
}
},
"pluginVersion": "12.1.0-pre",
"targets": [
{
"datasource": {
@@ -318,6 +322,7 @@
"type": "state-timeline"
},
{
"collapsed": false,
"gridPos": {
"h": 1,
"w": 24,
@@ -325,6 +330,7 @@
"y": 17
},
"id": 43,
"panels": [],
"title": "Gaps and connected",
"type": "row"
},
@@ -375,7 +381,7 @@
"steps": [
{
"color": "green",
"value": null
"value": 0
},
{
"color": "red",
@@ -394,7 +400,6 @@
"y": 18
},
"id": 3,
"links": [],
"options": {
"legend": {
"calcs": [],
@@ -407,7 +412,7 @@
"sort": "none"
}
},
"pluginVersion": "7.4.0-pre",
"pluginVersion": "12.1.0-pre",
"targets": [
{
"alias": "",
@@ -490,7 +495,7 @@
"steps": [
{
"color": "green",
"value": null
"value": 0
},
{
"color": "red",
@@ -509,7 +514,6 @@
"y": 18
},
"id": 2,
"links": [],
"options": {
"legend": {
"calcs": [],
@@ -522,7 +526,7 @@
"sort": "none"
}
},
"pluginVersion": "7.4.0-pre",
"pluginVersion": "12.1.0-pre",
"targets": [
{
"alias": "",
@@ -613,7 +617,7 @@
"steps": [
{
"color": "green",
"value": null
"value": 0
},
{
"color": "red",
@@ -632,7 +636,6 @@
"y": 18
},
"id": 6,
"links": [],
"options": {
"legend": {
"calcs": [],
@@ -645,7 +648,7 @@
"sort": "none"
}
},
"pluginVersion": "7.4.0-pre",
"pluginVersion": "12.1.0-pre",
"targets": [
{
"alias": "",
@@ -754,7 +757,7 @@
"steps": [
{
"color": "green",
"value": null
"value": 0
},
{
"color": "red",
@@ -773,7 +776,6 @@
"y": 25
},
"id": 4,
"links": [],
"options": {
"legend": {
"calcs": [],
@@ -786,7 +788,7 @@
"sort": "none"
}
},
"pluginVersion": "7.4.0-pre",
"pluginVersion": "12.1.0-pre",
"targets": [
{
"alias": "",
@@ -869,7 +871,7 @@
"steps": [
{
"color": "green",
"value": null
"value": 0
},
{
"color": "red",
@@ -888,7 +890,6 @@
"y": 25
},
"id": 5,
"links": [],
"options": {
"legend": {
"calcs": [],
@@ -901,7 +902,7 @@
"sort": "none"
}
},
"pluginVersion": "7.4.0-pre",
"pluginVersion": "12.1.0-pre",
"targets": [
{
"alias": "",
@@ -992,7 +993,7 @@
"steps": [
{
"color": "green",
"value": null
"value": 0
},
{
"color": "red",
@@ -1011,7 +1012,6 @@
"y": 25
},
"id": 7,
"links": [],
"options": {
"legend": {
"calcs": [],
@@ -1024,7 +1024,7 @@
"sort": "none"
}
},
"pluginVersion": "7.4.0-pre",
"pluginVersion": "12.1.0-pre",
"targets": [
{
"alias": "",
@@ -1133,7 +1133,7 @@
"steps": [
{
"color": "green",
"value": null
"value": 0
},
{
"color": "red",
@@ -1197,7 +1197,7 @@
"sort": "none"
}
},
"pluginVersion": "7.2.0-pre",
"pluginVersion": "12.1.0-pre",
"targets": [
{
"refId": "A",
@@ -1232,7 +1232,6 @@
}
],
"title": "Null values in first series & show gaps ",
"transformations": [],
"type": "timeseries"
},
{
@@ -1282,7 +1281,7 @@
"steps": [
{
"color": "green",
"value": null
"value": 0
},
{
"color": "red",
@@ -1346,7 +1345,7 @@
"sort": "none"
}
},
"pluginVersion": "7.2.0-pre",
"pluginVersion": "12.1.0-pre",
"targets": [
{
"alias": "",
@@ -1381,11 +1380,12 @@
}
],
"title": "Null values in second series show gaps (bugged)",
"transformations": [],
"type": "timeseries"
},
{
"datasource": { "type": "testdata" },
"datasource": {
"type": "testdata"
},
"fieldConfig": {
"defaults": {
"color": {
@@ -1432,7 +1432,7 @@
"steps": [
{
"color": "green",
"value": null
"value": 0
},
{
"color": "red",
@@ -1462,6 +1462,7 @@
"sort": "none"
}
},
"pluginVersion": "12.1.0-pre",
"targets": [
{
"refId": "A",
@@ -1473,7 +1474,9 @@
"type": "timeseries"
},
{
"datasource": { "type": "testdata" },
"datasource": {
"type": "testdata"
},
"fieldConfig": {
"defaults": {
"color": {
@@ -1520,7 +1523,7 @@
"steps": [
{
"color": "green",
"value": null
"value": 0
},
{
"color": "red",
@@ -1550,6 +1553,7 @@
"sort": "none"
}
},
"pluginVersion": "12.1.0-pre",
"targets": [
{
"datasource": {
@@ -1565,7 +1569,9 @@
"type": "timeseries"
},
{
"datasource": { "type": "testdata" },
"datasource": {
"type": "testdata"
},
"fieldConfig": {
"defaults": {
"color": {
@@ -1609,7 +1615,7 @@
"steps": [
{
"color": "green",
"value": null
"value": 0
},
{
"color": "red",
@@ -1640,6 +1646,7 @@
"sort": "none"
}
},
"pluginVersion": "12.1.0-pre",
"targets": [
{
"datasource": {
@@ -1655,7 +1662,9 @@
"type": "timeseries"
},
{
"datasource": { "type": "testdata" },
"datasource": {
"type": "testdata"
},
"fieldConfig": {
"defaults": {
"color": {
@@ -1699,7 +1708,7 @@
"steps": [
{
"color": "green",
"value": null
"value": 0
},
{
"color": "red",
@@ -1730,6 +1739,7 @@
"sort": "none"
}
},
"pluginVersion": "12.1.0-pre",
"targets": [
{
"datasource": {
@@ -1745,7 +1755,9 @@
"type": "timeseries"
},
{
"datasource": { "type": "testdata" },
"datasource": {
"type": "testdata"
},
"fieldConfig": {
"defaults": {
"color": {
@@ -1789,7 +1801,7 @@
"steps": [
{
"color": "green",
"value": null
"value": 0
},
{
"color": "red",
@@ -1820,6 +1832,7 @@
"sort": "none"
}
},
"pluginVersion": "12.1.0-pre",
"targets": [
{
"datasource": {
@@ -1835,7 +1848,9 @@
"type": "timeseries"
},
{
"datasource": { "type": "testdata" },
"datasource": {
"type": "testdata"
},
"fieldConfig": {
"defaults": {
"color": {
@@ -1879,7 +1894,7 @@
"steps": [
{
"color": "green",
"value": null
"value": 0
},
{
"color": "red",
@@ -1891,7 +1906,7 @@
"overrides": []
},
"gridPos": {
"h": 10,
"h": 5,
"w": 8,
"x": 0,
"y": 61
@@ -1910,6 +1925,7 @@
"sort": "none"
}
},
"pluginVersion": "12.1.0-pre",
"targets": [
{
"datasource": {
@@ -1925,7 +1941,9 @@
"type": "timeseries"
},
{
"datasource": { "type": "testdata" },
"datasource": {
"type": "testdata"
},
"fieldConfig": {
"defaults": {
"color": {
@@ -1969,7 +1987,7 @@
"steps": [
{
"color": "green",
"value": null
"value": 0
},
{
"color": "red",
@@ -1981,7 +1999,7 @@
"overrides": []
},
"gridPos": {
"h": 10,
"h": 5,
"w": 8,
"x": 8,
"y": 61
@@ -2000,6 +2018,7 @@
"sort": "none"
}
},
"pluginVersion": "12.1.0-pre",
"targets": [
{
"datasource": {
@@ -2015,7 +2034,9 @@
"type": "timeseries"
},
{
"datasource": { "type": "testdata" },
"datasource": {
"type": "testdata"
},
"fieldConfig": {
"defaults": {
"color": {
@@ -2059,7 +2080,7 @@
"steps": [
{
"color": "green",
"value": null
"value": 0
},
{
"color": "red",
@@ -2071,7 +2092,7 @@
"overrides": []
},
"gridPos": {
"h": 10,
"h": 5,
"w": 8,
"x": 16,
"y": 61
@@ -2090,6 +2111,7 @@
"sort": "none"
}
},
"pluginVersion": "12.1.0-pre",
"targets": [
{
"datasource": {
@@ -2104,6 +2126,192 @@
"title": "Higher density (mostly nulls, no leading/trailing)",
"type": "timeseries"
},
{
"datasource": {
"type": "testdata"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"insertNulls": false,
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "auto",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": 0
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 5,
"w": 8,
"x": 0,
"y": 66
},
"id": 47,
"maxDataPoints": 150,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"pluginVersion": "12.1.0-pre",
"targets": [
{
"datasource": {
"type": "testdata",
"uid": "PD8C576611E62080A"
},
"refId": "A",
"scenarioId": "csv_metric_values",
"stringInput": "8"
}
],
"title": "Higher density (mostly nulls, one leading point)",
"type": "timeseries"
},
{
"datasource": {
"type": "testdata"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"insertNulls": false,
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "auto",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": 0
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 5,
"w": 8,
"x": 8,
"y": 66
},
"id": 48,
"maxDataPoints": 150,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"pluginVersion": "12.1.0-pre",
"targets": [
{
"datasource": {
"type": "testdata",
"uid": "PD8C576611E62080A"
},
"refId": "A",
"scenarioId": "csv_metric_values",
"stringInput": ",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,8"
}
],
"title": "Higher density (mostly nulls, one trailing point)",
"type": "timeseries"
},
{
"collapsed": false,
"gridPos": {
@@ -2165,7 +2373,7 @@
"steps": [
{
"color": "green",
"value": null
"value": 0
},
{
"color": "red",
@@ -2196,7 +2404,7 @@
"sort": "none"
}
},
"pluginVersion": "7.5.0-pre",
"pluginVersion": "12.1.0-pre",
"targets": [
{
"alias": "",
@@ -2213,7 +2421,9 @@
"type": "timeseries"
},
{
"datasource": { "type": "testdata" },
"datasource": {
"type": "testdata"
},
"fieldConfig": {
"defaults": {
"color": {
@@ -2257,7 +2467,7 @@
"steps": [
{
"color": "green",
"value": null
"value": 0
},
{
"color": "red",
@@ -2288,7 +2498,7 @@
"sort": "none"
}
},
"pluginVersion": "7.5.0-pre",
"pluginVersion": "12.1.0-pre",
"targets": [
{
"alias": "",
@@ -2305,13 +2515,16 @@
"type": "trend"
},
{
"datasource": { "type": "testdata" },
"datasource": {
"type": "testdata"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"custom": {
"axisPlacement": "auto",
"fillOpacity": 70,
"hideFrom": {
"legend": false,
@@ -2328,7 +2541,7 @@
"steps": [
{
"color": "green",
"value": null
"value": 0
},
{
"color": "#EAB839",
@@ -2374,7 +2587,7 @@
"sort": "none"
}
},
"pluginVersion": "7.5.0-pre",
"pluginVersion": "12.1.0-pre",
"targets": [
{
"alias": "",
@@ -2438,7 +2651,7 @@
"steps": [
{
"color": "green",
"value": null
"value": 0
},
{
"color": "red",
@@ -2469,7 +2682,7 @@
"sort": "none"
}
},
"pluginVersion": "7.5.0-pre",
"pluginVersion": "12.1.0-pre",
"targets": [
{
"datasource": {
@@ -2531,7 +2744,7 @@
"steps": [
{
"color": "green",
"value": null
"value": 0
},
{
"color": "red",
@@ -2562,7 +2775,7 @@
"sort": "none"
}
},
"pluginVersion": "7.5.0-pre",
"pluginVersion": "12.1.0-pre",
"targets": [
{
"datasource": {
@@ -2587,6 +2800,7 @@
"mode": "thresholds"
},
"custom": {
"axisPlacement": "auto",
"fillOpacity": 70,
"hideFrom": {
"legend": false,
@@ -2603,7 +2817,7 @@
"steps": [
{
"color": "green",
"value": null
"value": 0
},
{
"color": "#EAB839",
@@ -2649,7 +2863,7 @@
"sort": "none"
}
},
"pluginVersion": "7.5.0-pre",
"pluginVersion": "12.1.0-pre",
"targets": [
{
"datasource": {
@@ -2711,7 +2925,7 @@
"steps": [
{
"color": "green",
"value": null
"value": 0
},
{
"color": "red",
@@ -2742,7 +2956,7 @@
"sort": "none"
}
},
"pluginVersion": "7.5.0-pre",
"pluginVersion": "12.1.0-pre",
"targets": [
{
"datasource": {
@@ -2804,7 +3018,7 @@
"steps": [
{
"color": "green",
"value": null
"value": 0
},
{
"color": "red",
@@ -2835,7 +3049,7 @@
"sort": "none"
}
},
"pluginVersion": "7.5.0-pre",
"pluginVersion": "12.1.0-pre",
"targets": [
{
"datasource": {
@@ -2860,6 +3074,7 @@
"mode": "thresholds"
},
"custom": {
"axisPlacement": "auto",
"fillOpacity": 70,
"hideFrom": {
"legend": false,
@@ -2876,7 +3091,7 @@
"steps": [
{
"color": "green",
"value": null
"value": 0
},
{
"color": "#EAB839",
@@ -2922,7 +3137,7 @@
"sort": "none"
}
},
"pluginVersion": "7.5.0-pre",
"pluginVersion": "12.1.0-pre",
"targets": [
{
"datasource": {
@@ -2984,7 +3199,7 @@
"steps": [
{
"color": "green",
"value": null
"value": 0
},
{
"color": "red",
@@ -3015,7 +3230,7 @@
"sort": "none"
}
},
"pluginVersion": "7.5.0-pre",
"pluginVersion": "12.1.0-pre",
"targets": [
{
"datasource": {
@@ -3077,7 +3292,7 @@
"steps": [
{
"color": "green",
"value": null
"value": 0
},
{
"color": "red",
@@ -3108,7 +3323,7 @@
"sort": "none"
}
},
"pluginVersion": "7.5.0-pre",
"pluginVersion": "12.1.0-pre",
"targets": [
{
"datasource": {
@@ -3133,6 +3348,7 @@
"mode": "thresholds"
},
"custom": {
"axisPlacement": "auto",
"fillOpacity": 70,
"hideFrom": {
"legend": false,
@@ -3149,7 +3365,7 @@
"steps": [
{
"color": "green",
"value": null
"value": 0
},
{
"color": "#EAB839",
@@ -3195,7 +3411,7 @@
"sort": "none"
}
},
"pluginVersion": "7.5.0-pre",
"pluginVersion": "12.1.0-pre",
"targets": [
{
"datasource": {
@@ -3210,8 +3426,9 @@
"type": "state-timeline"
}
],
"preload": false,
"refresh": false,
"schemaVersion": 39,
"schemaVersion": 41,
"tags": [
"gdev",
"panel-tests",
@@ -3232,6 +3449,5 @@
"timezone": "",
"title": "Panel Tests - Graph NG - Discrete panels",
"uid": "8mmCAF1Mz",
"version": 25,
"weekStart": ""
"version": 1
}
+17 -9
View File
@@ -343,7 +343,7 @@ export const preparePlotConfigBuilder: UPlotConfigPrepFn = ({
let pointsFilter: uPlot.Series.Points.Filter = () => null;
if (customConfig.spanNulls !== true) {
if (customConfig.spanNulls !== true && showPoints === VisibilityMode.Auto) {
pointsFilter = (u, seriesIdx, show, gaps) => {
let filtered = [];
@@ -390,15 +390,23 @@ export const preparePlotConfigBuilder: UPlotConfigPrepFn = ({
filtered.push(lastIdx);
}
}
// single point surrounded by nulls
// single point
else {
// meh heuristic
if (yData[0] == null && yData[yData.length - 1] == null) {
for (let i = 0; i < yData.length; i++) {
if (yData[i] != null) {
filtered.push(i);
}
}
// scan right
let leftIdx = 0;
while (yData[leftIdx] == null) {
leftIdx++;
}
// scan left
let rightIdx = yData.length - 1;
while (rightIdx >= leftIdx && yData[rightIdx] == null) {
rightIdx--;
}
// render if same
if (leftIdx === rightIdx) {
filtered.push(leftIdx);
}
}
}