mirror of
https://github.com/grafana/grafana.git
synced 2024-11-22 17:06:57 -06:00
TimeSeries: Render null-bounded points at data edges (#57798)
This commit is contained in:
parent
fbfd0fd51b
commit
45234e76eb
@ -129,6 +129,7 @@ Object {
|
||||
],
|
||||
"facets": undefined,
|
||||
"fill": [Function],
|
||||
"gaps": [Function],
|
||||
"paths": [Function],
|
||||
"points": Object {
|
||||
"fill": "#ff0000",
|
||||
@ -152,6 +153,7 @@ Object {
|
||||
],
|
||||
"facets": undefined,
|
||||
"fill": [Function],
|
||||
"gaps": [Function],
|
||||
"paths": [Function],
|
||||
"points": Object {
|
||||
"fill": "#ff0000",
|
||||
@ -175,6 +177,7 @@ Object {
|
||||
],
|
||||
"facets": undefined,
|
||||
"fill": [Function],
|
||||
"gaps": [Function],
|
||||
"paths": [Function],
|
||||
"points": Object {
|
||||
"fill": "#ff0000",
|
||||
@ -198,6 +201,7 @@ Object {
|
||||
],
|
||||
"facets": undefined,
|
||||
"fill": [Function],
|
||||
"gaps": [Function],
|
||||
"paths": [Function],
|
||||
"points": Object {
|
||||
"fill": "#ff0000",
|
||||
@ -221,6 +225,7 @@ Object {
|
||||
],
|
||||
"facets": undefined,
|
||||
"fill": [Function],
|
||||
"gaps": [Function],
|
||||
"paths": [Function],
|
||||
"points": Object {
|
||||
"fill": "#ff0000",
|
||||
|
@ -296,7 +296,7 @@ export const preparePlotConfigBuilder: UPlotConfigPrepFn<{
|
||||
|
||||
let pointsFilter: uPlot.Series.Points.Filter = () => null;
|
||||
|
||||
if (customConfig.spanNulls !== true) {
|
||||
if (customConfig.spanNulls !== true && showPoints !== VisibilityMode.Always) {
|
||||
pointsFilter = (u, seriesIdx, show, gaps) => {
|
||||
let filtered = [];
|
||||
|
||||
@ -426,7 +426,40 @@ export const preparePlotConfigBuilder: UPlotConfigPrepFn<{
|
||||
dynamicSeriesColor = (seriesIdx) => getFieldSeriesColor(alignedFrame.fields[seriesIdx], theme).color;
|
||||
}
|
||||
|
||||
// this adds leading and trailing gaps when datasets have leading and trailing nulls
|
||||
// it will cause additional unnecessary clips, but we also use adjacent gaps to show single points
|
||||
// when not connecting across gaps, e.g. null,100,null,null,50,50,50,null,50,null,null
|
||||
const gapsRefiner: uPlot.Series.GapsRefiner = (u, seriesIdx, idx0, idx1, gaps) => {
|
||||
let yData = u.data[seriesIdx];
|
||||
|
||||
// @ts-ignore
|
||||
let xData = u._data[0];
|
||||
|
||||
// scan to first and last non-null vals
|
||||
let first = idx0,
|
||||
last = idx1;
|
||||
|
||||
while (first <= last && yData[first] == null) {
|
||||
first++;
|
||||
}
|
||||
|
||||
while (last > first && yData[last] == null) {
|
||||
last--;
|
||||
}
|
||||
|
||||
if (first !== idx0) {
|
||||
gaps.unshift([u.bbox.left, Math.round(u.valToPos(xData[first]!, 'x', true))]);
|
||||
}
|
||||
|
||||
if (last !== idx1) {
|
||||
gaps.push([Math.round(u.valToPos(xData[last]!, 'x', true)), u.bbox.left + u.bbox.width]);
|
||||
}
|
||||
|
||||
return gaps;
|
||||
};
|
||||
|
||||
builder.addSeries({
|
||||
gapsRefiner,
|
||||
pathBuilder,
|
||||
pointsBuilder,
|
||||
scaleKey,
|
||||
|
@ -613,6 +613,7 @@ describe('UPlotConfigBuilder', () => {
|
||||
Object {
|
||||
"facets": undefined,
|
||||
"fill": [Function],
|
||||
"gaps": [Function],
|
||||
"paths": [Function],
|
||||
"points": Object {
|
||||
"fill": "#0000ff",
|
||||
@ -740,6 +741,7 @@ describe('UPlotConfigBuilder', () => {
|
||||
Object {
|
||||
"facets": undefined,
|
||||
"fill": [Function],
|
||||
"gaps": [Function],
|
||||
"paths": [Function],
|
||||
"points": Object {
|
||||
"fill": "#0000ff",
|
||||
@ -758,6 +760,7 @@ describe('UPlotConfigBuilder', () => {
|
||||
Object {
|
||||
"facets": undefined,
|
||||
"fill": [Function],
|
||||
"gaps": [Function],
|
||||
"paths": [Function],
|
||||
"points": Object {
|
||||
"fill": "#00ff00",
|
||||
@ -776,6 +779,7 @@ describe('UPlotConfigBuilder', () => {
|
||||
Object {
|
||||
"facets": undefined,
|
||||
"fill": [Function],
|
||||
"gaps": [Function],
|
||||
"paths": [Function],
|
||||
"points": Object {
|
||||
"fill": "#ff0000",
|
||||
|
@ -49,6 +49,8 @@ export interface SeriesProps extends LineConfig, BarConfig, FillConfig, PointsCo
|
||||
dataFrameFieldIndex?: DataFrameFieldIndex;
|
||||
theme: GrafanaTheme2;
|
||||
value?: uPlot.Series.Value;
|
||||
|
||||
gapsRefiner?: uPlot.Series.GapsRefiner;
|
||||
}
|
||||
|
||||
export class UPlotSeriesBuilder extends PlotConfigBuilder<SeriesProps, Series> {
|
||||
@ -71,6 +73,7 @@ export class UPlotSeriesBuilder extends PlotConfigBuilder<SeriesProps, Series> {
|
||||
pxAlign,
|
||||
spanNulls,
|
||||
show = true,
|
||||
gapsRefiner,
|
||||
} = this.props;
|
||||
|
||||
let lineConfig: Partial<Series> = {};
|
||||
@ -145,6 +148,7 @@ export class UPlotSeriesBuilder extends PlotConfigBuilder<SeriesProps, Series> {
|
||||
pxAlign,
|
||||
show,
|
||||
fill: this.getFill(),
|
||||
gaps: gapsRefiner ?? ((u, seriesIdx, idx0, idx1, gaps) => gaps),
|
||||
...lineConfig,
|
||||
...pointsConfig,
|
||||
};
|
||||
|
@ -133,6 +133,7 @@ Object {
|
||||
Object {
|
||||
"facets": undefined,
|
||||
"fill": [Function],
|
||||
"gaps": [Function],
|
||||
"paths": [Function],
|
||||
"points": Object {
|
||||
"fill": "#808080",
|
||||
@ -286,6 +287,7 @@ Object {
|
||||
Object {
|
||||
"facets": undefined,
|
||||
"fill": [Function],
|
||||
"gaps": [Function],
|
||||
"paths": [Function],
|
||||
"points": Object {
|
||||
"fill": "#808080",
|
||||
@ -439,6 +441,7 @@ Object {
|
||||
Object {
|
||||
"facets": undefined,
|
||||
"fill": [Function],
|
||||
"gaps": [Function],
|
||||
"paths": [Function],
|
||||
"points": Object {
|
||||
"fill": "#808080",
|
||||
@ -592,6 +595,7 @@ Object {
|
||||
Object {
|
||||
"facets": undefined,
|
||||
"fill": [Function],
|
||||
"gaps": [Function],
|
||||
"paths": [Function],
|
||||
"points": Object {
|
||||
"fill": "#808080",
|
||||
@ -745,6 +749,7 @@ Object {
|
||||
Object {
|
||||
"facets": undefined,
|
||||
"fill": [Function],
|
||||
"gaps": [Function],
|
||||
"paths": [Function],
|
||||
"points": Object {
|
||||
"fill": "#808080",
|
||||
@ -898,6 +903,7 @@ Object {
|
||||
Object {
|
||||
"facets": undefined,
|
||||
"fill": [Function],
|
||||
"gaps": [Function],
|
||||
"paths": [Function],
|
||||
"points": Object {
|
||||
"fill": "#808080",
|
||||
@ -1051,6 +1057,7 @@ Object {
|
||||
Object {
|
||||
"facets": undefined,
|
||||
"fill": [Function],
|
||||
"gaps": [Function],
|
||||
"paths": [Function],
|
||||
"points": Object {
|
||||
"fill": "#808080",
|
||||
@ -1204,6 +1211,7 @@ Object {
|
||||
Object {
|
||||
"facets": undefined,
|
||||
"fill": [Function],
|
||||
"gaps": [Function],
|
||||
"paths": [Function],
|
||||
"points": Object {
|
||||
"fill": "#808080",
|
||||
|
Loading…
Reference in New Issue
Block a user