mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
fix(dashboard): time regions spanning across midnight (#16201)
Fixes #14590
This commit is contained in:
committed by
GitHub
parent
d791a6211d
commit
6c9b9b360a
@@ -463,15 +463,105 @@
|
|||||||
"align": false,
|
"align": false,
|
||||||
"alignLevel": null
|
"alignLevel": null
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"aliasColors": {},
|
||||||
|
"bars": false,
|
||||||
|
"dashLength": 10,
|
||||||
|
"dashes": false,
|
||||||
|
"datasource": "gdev-testdata",
|
||||||
|
"fill": 1,
|
||||||
|
"gridPos": {
|
||||||
|
"h": 8,
|
||||||
|
"w": 24,
|
||||||
|
"x": 0,
|
||||||
|
"y": 32
|
||||||
|
},
|
||||||
|
"id": 7,
|
||||||
|
"legend": {
|
||||||
|
"avg": false,
|
||||||
|
"current": false,
|
||||||
|
"max": false,
|
||||||
|
"min": false,
|
||||||
|
"show": true,
|
||||||
|
"total": false,
|
||||||
|
"values": false
|
||||||
|
},
|
||||||
|
"lines": true,
|
||||||
|
"linewidth": 1,
|
||||||
|
"links": [],
|
||||||
|
"nullPointMode": "null",
|
||||||
|
"percentage": false,
|
||||||
|
"pointradius": 2,
|
||||||
|
"points": false,
|
||||||
|
"renderer": "flot",
|
||||||
|
"seriesOverrides": [],
|
||||||
|
"spaceLength": 10,
|
||||||
|
"stack": false,
|
||||||
|
"steppedLine": false,
|
||||||
|
"targets": [
|
||||||
|
{
|
||||||
|
"refId": "A",
|
||||||
|
"scenarioId": "random_walk"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"thresholds": [],
|
||||||
|
"timeFrom": null,
|
||||||
|
"timeRegions": [
|
||||||
|
{
|
||||||
|
"colorMode": "gray",
|
||||||
|
"fill": true,
|
||||||
|
"fillColor": "rgba(234, 112, 112, 0.12)",
|
||||||
|
"from": "22:00",
|
||||||
|
"line": false,
|
||||||
|
"lineColor": "rgba(237, 46, 24, 0.60)",
|
||||||
|
"op": "time",
|
||||||
|
"to": "00:30"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timeShift": null,
|
||||||
|
"title": "From 22:00 to 00:30 (crossing midnight)",
|
||||||
|
"tooltip": {
|
||||||
|
"shared": true,
|
||||||
|
"sort": 0,
|
||||||
|
"value_type": "individual"
|
||||||
|
},
|
||||||
|
"type": "graph",
|
||||||
|
"xaxis": {
|
||||||
|
"buckets": null,
|
||||||
|
"mode": "time",
|
||||||
|
"name": null,
|
||||||
|
"show": true,
|
||||||
|
"values": []
|
||||||
|
},
|
||||||
|
"yaxes": [
|
||||||
|
{
|
||||||
|
"format": "short",
|
||||||
|
"label": null,
|
||||||
|
"logBase": 1,
|
||||||
|
"max": null,
|
||||||
|
"min": null,
|
||||||
|
"show": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"format": "short",
|
||||||
|
"label": null,
|
||||||
|
"logBase": 1,
|
||||||
|
"max": null,
|
||||||
|
"min": null,
|
||||||
|
"show": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"yaxis": {
|
||||||
|
"align": false,
|
||||||
|
"alignLevel": null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"refresh": false,
|
"refresh": false,
|
||||||
"schemaVersion": 16,
|
"schemaVersion": 18,
|
||||||
"style": "dark",
|
"style": "dark",
|
||||||
"tags": [
|
"tags": ["gdev", "panel-tests"],
|
||||||
"gdev",
|
|
||||||
"panel-tests"
|
|
||||||
],
|
|
||||||
"templating": {
|
"templating": {
|
||||||
"list": []
|
"list": []
|
||||||
},
|
},
|
||||||
@@ -480,32 +570,11 @@
|
|||||||
"to": "now"
|
"to": "now"
|
||||||
},
|
},
|
||||||
"timepicker": {
|
"timepicker": {
|
||||||
"refresh_intervals": [
|
"refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"],
|
||||||
"5s",
|
"time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"]
|
||||||
"10s",
|
|
||||||
"30s",
|
|
||||||
"1m",
|
|
||||||
"5m",
|
|
||||||
"15m",
|
|
||||||
"30m",
|
|
||||||
"1h",
|
|
||||||
"2h",
|
|
||||||
"1d"
|
|
||||||
],
|
|
||||||
"time_options": [
|
|
||||||
"5m",
|
|
||||||
"15m",
|
|
||||||
"1h",
|
|
||||||
"6h",
|
|
||||||
"12h",
|
|
||||||
"24h",
|
|
||||||
"2d",
|
|
||||||
"7d",
|
|
||||||
"30d"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"timezone": "browser",
|
"timezone": "browser",
|
||||||
"title": "Panel Tests - Graph (Time Regions)",
|
"title": "Panel Tests - Graph (Time Regions)",
|
||||||
"uid": "XMjIZPmik",
|
"uid": "XMjIZPmik",
|
||||||
"version": 1
|
"version": 9
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -176,6 +176,33 @@ describe('TimeRegionManager', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
plotOptionsScenario('for time from/to region crossing midnight', ctx => {
|
||||||
|
const regions = [{ from: '22:00', to: '00:30', fill: true, colorMode: 'red' }];
|
||||||
|
const from = moment('2018-12-01T12:00+01:00');
|
||||||
|
const to = moment('2018-12-04T08:00+01:00');
|
||||||
|
ctx.setup(regions, from, to);
|
||||||
|
|
||||||
|
it('should add 3 markings', () => {
|
||||||
|
expect(ctx.options.grid.markings.length).toBe(3);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should add one fill between 22:00 and 00:30 each day', () => {
|
||||||
|
const markings = ctx.options.grid.markings;
|
||||||
|
|
||||||
|
expect(moment(markings[0].xaxis.from).format()).toBe(moment('2018-12-01T23:00:00+01:00').format());
|
||||||
|
expect(moment(markings[0].xaxis.to).format()).toBe(moment('2018-12-02T01:30:00+01:00').format());
|
||||||
|
expect(markings[0].color).toBe(colorModes.red.color.fill);
|
||||||
|
|
||||||
|
expect(moment(markings[1].xaxis.from).format()).toBe(moment('2018-12-02T23:00:00+01:00').format());
|
||||||
|
expect(moment(markings[1].xaxis.to).format()).toBe(moment('2018-12-03T01:30:00+01:00').format());
|
||||||
|
expect(markings[1].color).toBe(colorModes.red.color.fill);
|
||||||
|
|
||||||
|
expect(moment(markings[2].xaxis.from).format()).toBe(moment('2018-12-03T23:00:00+01:00').format());
|
||||||
|
expect(moment(markings[2].xaxis.to).format()).toBe(moment('2018-12-04T01:30:00+01:00').format());
|
||||||
|
expect(markings[2].color).toBe(colorModes.red.color.fill);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
plotOptionsScenario('for day of week from/to region', ctx => {
|
plotOptionsScenario('for day of week from/to region', ctx => {
|
||||||
const regions = [{ fromDayOfWeek: 7, toDayOfWeek: 7, fill: true, colorMode: 'red' }];
|
const regions = [{ fromDayOfWeek: 7, toDayOfWeek: 7, fill: true, colorMode: 'red' }];
|
||||||
const from = moment('2018-01-01T18:45:05+01:00');
|
const from = moment('2018-01-01T18:45:05+01:00');
|
||||||
|
|||||||
@@ -143,70 +143,55 @@ export class TimeRegionManager {
|
|||||||
|
|
||||||
regions = [];
|
regions = [];
|
||||||
|
|
||||||
if (
|
fromStart = moment(tRange.from);
|
||||||
hRange.from.h >= tRange.from.hour() &&
|
fromStart.set('hour', 0);
|
||||||
hRange.from.h <= tRange.from.hour() &&
|
fromStart.set('minute', 0);
|
||||||
hRange.from.m >= tRange.from.minute() &&
|
fromStart.set('second', 0);
|
||||||
hRange.from.m <= tRange.from.minute() &&
|
fromStart.add(hRange.from.h, 'hours');
|
||||||
hRange.to.h >= tRange.to.hour() &&
|
fromStart.add(hRange.from.m, 'minutes');
|
||||||
hRange.to.h <= tRange.to.hour() &&
|
fromStart.add(hRange.from.s, 'seconds');
|
||||||
hRange.to.m >= tRange.to.minute() &&
|
|
||||||
hRange.to.m <= tRange.to.minute()
|
|
||||||
) {
|
|
||||||
regions.push({ from: tRange.from.valueOf(), to: tRange.to.startOf('hour').valueOf() });
|
|
||||||
} else {
|
|
||||||
fromStart = moment(tRange.from);
|
|
||||||
fromStart.set('hour', 0);
|
|
||||||
fromStart.set('minute', 0);
|
|
||||||
fromStart.set('second', 0);
|
|
||||||
fromStart.add(hRange.from.h, 'hours');
|
|
||||||
fromStart.add(hRange.from.m, 'minutes');
|
|
||||||
fromStart.add(hRange.from.s, 'seconds');
|
|
||||||
|
|
||||||
while (fromStart.unix() <= tRange.to.unix()) {
|
|
||||||
while (hRange.from.dayOfWeek && hRange.from.dayOfWeek !== fromStart.isoWeekday()) {
|
|
||||||
fromStart.add(24, 'hours');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fromStart.unix() > tRange.to.unix()) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
fromEnd = moment(fromStart);
|
|
||||||
|
|
||||||
if (hRange.from.h <= hRange.to.h) {
|
|
||||||
fromEnd.add(hRange.to.h - hRange.from.h, 'hours');
|
|
||||||
} else if (hRange.from.h + hRange.to.h < 23) {
|
|
||||||
fromEnd.add(hRange.to.h, 'hours');
|
|
||||||
|
|
||||||
while (fromEnd.hour() !== hRange.to.h) {
|
|
||||||
fromEnd.add(-1, 'hours');
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fromEnd.add(24 - hRange.from.h, 'hours');
|
|
||||||
|
|
||||||
while (fromEnd.hour() !== hRange.to.h) {
|
|
||||||
fromEnd.add(1, 'hours');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fromEnd.set('minute', hRange.to.m);
|
|
||||||
fromEnd.set('second', hRange.to.s);
|
|
||||||
|
|
||||||
while (hRange.to.dayOfWeek && hRange.to.dayOfWeek !== fromEnd.isoWeekday()) {
|
|
||||||
fromEnd.add(24, 'hours');
|
|
||||||
}
|
|
||||||
|
|
||||||
const outsideRange =
|
|
||||||
(fromStart.unix() < tRange.from.unix() && fromEnd.unix() < tRange.from.unix()) ||
|
|
||||||
(fromStart.unix() > tRange.to.unix() && fromEnd.unix() > tRange.to.unix());
|
|
||||||
|
|
||||||
if (!outsideRange) {
|
|
||||||
regions.push({ from: fromStart.valueOf(), to: fromEnd.valueOf() });
|
|
||||||
}
|
|
||||||
|
|
||||||
|
while (fromStart.unix() <= tRange.to.unix()) {
|
||||||
|
while (hRange.from.dayOfWeek && hRange.from.dayOfWeek !== fromStart.isoWeekday()) {
|
||||||
fromStart.add(24, 'hours');
|
fromStart.add(24, 'hours');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (fromStart.unix() > tRange.to.unix()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
fromEnd = moment(fromStart);
|
||||||
|
|
||||||
|
if (hRange.from.h <= hRange.to.h) {
|
||||||
|
fromEnd.add(hRange.to.h - hRange.from.h, 'hours');
|
||||||
|
} else if (hRange.from.h > hRange.to.h) {
|
||||||
|
while (fromEnd.hour() !== hRange.to.h) {
|
||||||
|
fromEnd.add(1, 'hours');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fromEnd.add(24 - hRange.from.h, 'hours');
|
||||||
|
|
||||||
|
while (fromEnd.hour() !== hRange.to.h) {
|
||||||
|
fromEnd.add(1, 'hours');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fromEnd.set('minute', hRange.to.m);
|
||||||
|
fromEnd.set('second', hRange.to.s);
|
||||||
|
|
||||||
|
while (hRange.to.dayOfWeek && hRange.to.dayOfWeek !== fromEnd.isoWeekday()) {
|
||||||
|
fromEnd.add(24, 'hours');
|
||||||
|
}
|
||||||
|
|
||||||
|
const outsideRange =
|
||||||
|
(fromStart.unix() < tRange.from.unix() && fromEnd.unix() < tRange.from.unix()) ||
|
||||||
|
(fromStart.unix() > tRange.to.unix() && fromEnd.unix() > tRange.to.unix());
|
||||||
|
|
||||||
|
if (!outsideRange) {
|
||||||
|
regions.push({ from: fromStart.valueOf(), to: fromEnd.valueOf() });
|
||||||
|
}
|
||||||
|
|
||||||
|
fromStart.add(24, 'hours');
|
||||||
}
|
}
|
||||||
|
|
||||||
timeRegionColor = getColor(timeRegion, this.theme);
|
timeRegionColor = getColor(timeRegion, this.theme);
|
||||||
|
|||||||
Reference in New Issue
Block a user