From 63be43e3b2c1ce5cfa0c8db3fca20b6f591bdb11 Mon Sep 17 00:00:00 2001 From: Marcus Efraimsson Date: Thu, 21 Jun 2018 14:41:47 +0200 Subject: [PATCH] graph: Time region support --- public/app/plugins/panel/graph/graph.ts | 6 + public/app/plugins/panel/graph/module.ts | 2 + .../graph/specs/time_region_manager.test.ts | 217 +++++++++++++++ .../app/plugins/panel/graph/tab_display.html | 9 + .../plugins/panel/graph/thresholds_form.html | 77 ++++++ .../plugins/panel/graph/thresholds_form.ts | 82 +----- .../panel/graph/time_region_manager.ts | 249 ++++++++++++++++++ .../panel/graph/time_regions_form.html | 64 +++++ .../plugins/panel/graph/time_regions_form.ts | 73 +++++ 9 files changed, 698 insertions(+), 81 deletions(-) create mode 100644 public/app/plugins/panel/graph/specs/time_region_manager.test.ts create mode 100644 public/app/plugins/panel/graph/thresholds_form.html create mode 100644 public/app/plugins/panel/graph/time_region_manager.ts create mode 100644 public/app/plugins/panel/graph/time_regions_form.html create mode 100644 public/app/plugins/panel/graph/time_regions_form.ts diff --git a/public/app/plugins/panel/graph/graph.ts b/public/app/plugins/panel/graph/graph.ts index 01afd0716e6..c5f98792568 100755 --- a/public/app/plugins/panel/graph/graph.ts +++ b/public/app/plugins/panel/graph/graph.ts @@ -16,6 +16,7 @@ import { tickStep } from 'app/core/utils/ticks'; import { appEvents, coreModule, updateLegendValues } from 'app/core/core'; import GraphTooltip from './graph_tooltip'; import { ThresholdManager } from './threshold_manager'; +import { TimeRegionManager } from './time_region_manager'; import { EventManager } from 'app/features/annotations/all'; import { convertToHistogramData } from './histogram'; import { alignYLevel } from './align_yaxes'; @@ -38,6 +39,7 @@ class GraphElement { panelWidth: number; eventManager: EventManager; thresholdManager: ThresholdManager; + timeRegionManager: TimeRegionManager; legendElem: HTMLElement; constructor(private scope, private elem, private timeSrv) { @@ -49,6 +51,7 @@ class GraphElement { this.panelWidth = 0; this.eventManager = new EventManager(this.ctrl); this.thresholdManager = new ThresholdManager(this.ctrl); + this.timeRegionManager = new TimeRegionManager(this.ctrl); this.tooltip = new GraphTooltip(this.elem, this.ctrl.dashboard, this.scope, () => { return this.sortedSeries; }); @@ -125,6 +128,7 @@ class GraphElement { onPanelTeardown() { this.thresholdManager = null; + this.timeRegionManager = null; if (this.plot) { this.plot.destroy(); @@ -215,6 +219,7 @@ class GraphElement { } this.thresholdManager.draw(plot); + this.timeRegionManager.draw(plot); } processOffsetHook(plot, gridMargin) { @@ -293,6 +298,7 @@ class GraphElement { this.prepareXAxis(options, this.panel); this.configureYAxisOptions(this.data, options); this.thresholdManager.addFlotOptions(options, this.panel); + this.timeRegionManager.addFlotOptions(options, this.panel); this.eventManager.addFlotEvents(this.annotations, options); this.sortedSeries = this.sortSeries(this.data, this.panel); diff --git a/public/app/plugins/panel/graph/module.ts b/public/app/plugins/panel/graph/module.ts index a6c5190d937..5b48636de5f 100644 --- a/public/app/plugins/panel/graph/module.ts +++ b/public/app/plugins/panel/graph/module.ts @@ -1,6 +1,7 @@ import './graph'; import './series_overrides_ctrl'; import './thresholds_form'; +import './time_regions_form'; import template from './template'; import _ from 'lodash'; @@ -111,6 +112,7 @@ class GraphCtrl extends MetricsPanelCtrl { // other style overrides seriesOverrides: [], thresholds: [], + timeRegions: [], }; /** @ngInject */ diff --git a/public/app/plugins/panel/graph/specs/time_region_manager.test.ts b/public/app/plugins/panel/graph/specs/time_region_manager.test.ts new file mode 100644 index 00000000000..d1b2290cb61 --- /dev/null +++ b/public/app/plugins/panel/graph/specs/time_region_manager.test.ts @@ -0,0 +1,217 @@ +import { TimeRegionManager, colorModes } from '../time_region_manager'; +import moment from 'moment'; + +describe('TimeRegionManager', () => { + function plotOptionsScenario(desc, func) { + describe(desc, () => { + const ctx: any = { + panel: { + timeRegions: [], + }, + options: { + grid: { markings: [] }, + }, + panelCtrl: { + range: {}, + dashboard: { + isTimezoneUtc: () => false, + }, + }, + }; + + ctx.setup = (regions, from, to) => { + ctx.panel.timeRegions = regions; + ctx.panelCtrl.range.from = from; + ctx.panelCtrl.range.to = to; + const manager = new TimeRegionManager(ctx.panelCtrl); + manager.addFlotOptions(ctx.options, ctx.panel); + }; + + ctx.printScenario = () => { + console.log(`Time range: from=${ctx.panelCtrl.range.from.format()}, to=${ctx.panelCtrl.range.to.format()}`); + ctx.options.grid.markings.forEach((m, i) => { + console.log( + `Marking (${i}): from=${moment(m.xaxis.from).format()}, to=${moment(m.xaxis.to).format()}, color=${m.color}` + ); + }); + }; + + func(ctx); + }); + } + + describe('When creating plot markings', () => { + plotOptionsScenario('for day of week region', ctx => { + const regions = [{ fromDayOfWeek: 1, toDayOfWeek: 1, fill: true, line: true, colorMode: 'red' }]; + const from = moment('2018-01-01 00:00'); + const to = moment('2018-01-01 23:59'); + ctx.setup(regions, from, to); + + it('should add 3 markings', () => { + expect(ctx.options.grid.markings.length).toBe(3); + }); + + it('should add fill', () => { + const markings = ctx.options.grid.markings; + expect(moment(markings[0].xaxis.from).format()).toBe(from.format()); + expect(moment(markings[0].xaxis.to).format()).toBe(to.format()); + expect(markings[0].color).toBe(colorModes.red.color.fill); + }); + + it('should add line before', () => { + const markings = ctx.options.grid.markings; + expect(moment(markings[1].xaxis.from).format()).toBe(from.format()); + expect(moment(markings[1].xaxis.to).format()).toBe(from.format()); + expect(markings[1].color).toBe(colorModes.red.color.line); + }); + + it('should add line after', () => { + const markings = ctx.options.grid.markings; + expect(moment(markings[2].xaxis.from).format()).toBe(to.format()); + expect(moment(markings[2].xaxis.to).format()).toBe(to.format()); + expect(markings[2].color).toBe(colorModes.red.color.line); + }); + }); + + plotOptionsScenario('for time from region', ctx => { + const regions = [{ from: '05:00', fill: true, colorMode: 'red' }]; + const from = moment('2018-01-01 00:00'); + const to = moment('2018-01-03 23:59'); + ctx.setup(regions, from, to); + + it('should add 3 markings', () => { + expect(ctx.options.grid.markings.length).toBe(3); + }); + + it('should add one fill at 05:00 each day', () => { + const markings = ctx.options.grid.markings; + + const firstFill = moment(from.add(5, 'hours')); + expect(moment(markings[0].xaxis.from).format()).toBe(firstFill.format()); + expect(moment(markings[0].xaxis.to).format()).toBe(firstFill.format()); + expect(markings[0].color).toBe(colorModes.red.color.fill); + + const secondFill = moment(firstFill).add(1, 'days'); + expect(moment(markings[1].xaxis.from).format()).toBe(secondFill.format()); + expect(moment(markings[1].xaxis.to).format()).toBe(secondFill.format()); + expect(markings[1].color).toBe(colorModes.red.color.fill); + + const thirdFill = moment(secondFill).add(1, 'days'); + expect(moment(markings[2].xaxis.from).format()).toBe(thirdFill.format()); + expect(moment(markings[2].xaxis.to).format()).toBe(thirdFill.format()); + expect(markings[2].color).toBe(colorModes.red.color.fill); + }); + }); + + plotOptionsScenario('for time to region', ctx => { + const regions = [{ to: '05:00', fill: true, colorMode: 'red' }]; + const from = moment('2018-02-01 00:00'); + const to = moment('2018-02-03 23:59'); + ctx.setup(regions, from, to); + + it('should add 3 markings', () => { + expect(ctx.options.grid.markings.length).toBe(3); + }); + + it('should add one fill at 05:00 each day', () => { + const markings = ctx.options.grid.markings; + + const firstFill = moment(from.add(5, 'hours')); + expect(moment(markings[0].xaxis.from).format()).toBe(firstFill.format()); + expect(moment(markings[0].xaxis.to).format()).toBe(firstFill.format()); + expect(markings[0].color).toBe(colorModes.red.color.fill); + + const secondFill = moment(firstFill).add(1, 'days'); + expect(moment(markings[1].xaxis.from).format()).toBe(secondFill.format()); + expect(moment(markings[1].xaxis.to).format()).toBe(secondFill.format()); + expect(markings[1].color).toBe(colorModes.red.color.fill); + + const thirdFill = moment(secondFill).add(1, 'days'); + expect(moment(markings[2].xaxis.from).format()).toBe(thirdFill.format()); + expect(moment(markings[2].xaxis.to).format()).toBe(thirdFill.format()); + expect(markings[2].color).toBe(colorModes.red.color.fill); + }); + }); + + plotOptionsScenario('for day of week from/to region', ctx => { + const regions = [{ fromDayOfWeek: 7, toDayOfWeek: 7, fill: true, colorMode: 'red' }]; + const from = moment('2018-01-01 18:45:05'); + const to = moment('2018-01-22 08:27:00'); + ctx.setup(regions, from, to); + + it('should add 3 markings', () => { + expect(ctx.options.grid.markings.length).toBe(3); + }); + + it('should add one fill at each sunday', () => { + const markings = ctx.options.grid.markings; + + expect(moment(markings[0].xaxis.from).format()).toBe(moment('2018-01-07 00:00:00').format()); + expect(moment(markings[0].xaxis.to).format()).toBe(moment('2018-01-07 23:59:59').format()); + expect(markings[0].color).toBe(colorModes.red.color.fill); + + expect(moment(markings[1].xaxis.from).format()).toBe(moment('2018-01-14 00:00:00').format()); + expect(moment(markings[1].xaxis.to).format()).toBe(moment('2018-01-14 23:59:59').format()); + expect(markings[1].color).toBe(colorModes.red.color.fill); + + expect(moment(markings[2].xaxis.from).format()).toBe(moment('2018-01-21 00:00:00').format()); + expect(moment(markings[2].xaxis.to).format()).toBe(moment('2018-01-21 23:59:59').format()); + expect(markings[2].color).toBe(colorModes.red.color.fill); + }); + }); + + plotOptionsScenario('for day of week from region', ctx => { + const regions = [{ fromDayOfWeek: 7, fill: true, colorMode: 'red' }]; + const from = moment('2018-01-01 18:45:05'); + const to = moment('2018-01-22 08:27:00'); + ctx.setup(regions, from, to); + + it('should add 3 markings', () => { + expect(ctx.options.grid.markings.length).toBe(3); + }); + + it('should add one fill at each sunday', () => { + const markings = ctx.options.grid.markings; + + expect(moment(markings[0].xaxis.from).format()).toBe(moment('2018-01-07 00:00:00').format()); + expect(moment(markings[0].xaxis.to).format()).toBe(moment('2018-01-07 23:59:59').format()); + expect(markings[0].color).toBe(colorModes.red.color.fill); + + expect(moment(markings[1].xaxis.from).format()).toBe(moment('2018-01-14 00:00:00').format()); + expect(moment(markings[1].xaxis.to).format()).toBe(moment('2018-01-14 23:59:59').format()); + expect(markings[1].color).toBe(colorModes.red.color.fill); + + expect(moment(markings[2].xaxis.from).format()).toBe(moment('2018-01-21 00:00:00').format()); + expect(moment(markings[2].xaxis.to).format()).toBe(moment('2018-01-21 23:59:59').format()); + expect(markings[2].color).toBe(colorModes.red.color.fill); + }); + }); + + plotOptionsScenario('for day of week to region', ctx => { + const regions = [{ toDayOfWeek: 7, fill: true, colorMode: 'red' }]; + const from = moment('2018-01-01 18:45:05'); + const to = moment('2018-01-22 08:27:00'); + ctx.setup(regions, from, to); + + it('should add 3 markings', () => { + expect(ctx.options.grid.markings.length).toBe(3); + }); + + it('should add one fill at each sunday', () => { + const markings = ctx.options.grid.markings; + + expect(moment(markings[0].xaxis.from).format()).toBe(moment('2018-01-07 00:00:00').format()); + expect(moment(markings[0].xaxis.to).format()).toBe(moment('2018-01-07 23:59:59').format()); + expect(markings[0].color).toBe(colorModes.red.color.fill); + + expect(moment(markings[1].xaxis.from).format()).toBe(moment('2018-01-14 00:00:00').format()); + expect(moment(markings[1].xaxis.to).format()).toBe(moment('2018-01-14 23:59:59').format()); + expect(markings[1].color).toBe(colorModes.red.color.fill); + + expect(moment(markings[2].xaxis.from).format()).toBe(moment('2018-01-21 00:00:00').format()); + expect(moment(markings[2].xaxis.to).format()).toBe(moment('2018-01-21 23:59:59').format()); + expect(markings[2].color).toBe(colorModes.red.color.fill); + }); + }); + }); +}); diff --git a/public/app/plugins/panel/graph/tab_display.html b/public/app/plugins/panel/graph/tab_display.html index ebc6cf9b18e..d407f30ffc8 100644 --- a/public/app/plugins/panel/graph/tab_display.html +++ b/public/app/plugins/panel/graph/tab_display.html @@ -14,6 +14,11 @@ Thresholds ({{ctrl.panel.thresholds.length}}) +
  • + + Time regions ({{ctrl.panel.timeRegions.length}}) + +
  • @@ -132,4 +137,8 @@ +
    + +
    + diff --git a/public/app/plugins/panel/graph/thresholds_form.html b/public/app/plugins/panel/graph/thresholds_form.html new file mode 100644 index 00000000000..81877150a47 --- /dev/null +++ b/public/app/plugins/panel/graph/thresholds_form.html @@ -0,0 +1,77 @@ +
    +
    Thresholds
    +

    + Visual thresholds options disabled. + Visit the Alert tab update your thresholds.
    + To re-enable thresholds, the alert rule must be deleted from this panel. +

    +
    +
    +
    + +
    + +
    +
    + +
    + +
    + +
    + +
    + +
    +
    + + + +
    + + + + +
    + + + +
    + + + + +
    + +
    + +
    + +
    +
    + +
    + +
    +
    + +
    + +
    +
    +
    \ No newline at end of file diff --git a/public/app/plugins/panel/graph/thresholds_form.ts b/public/app/plugins/panel/graph/thresholds_form.ts index 5f1edb8aa9a..4f480873d5b 100644 --- a/public/app/plugins/panel/graph/thresholds_form.ts +++ b/public/app/plugins/panel/graph/thresholds_form.ts @@ -58,90 +58,10 @@ export class ThresholdFormCtrl { } } -const template = ` -
    -
    Thresholds
    -

    - Visual thresholds options disabled. - Visit the Alert tab update your thresholds.
    - To re-enable thresholds, the alert rule must be deleted from this panel. -

    -
    -
    -
    - -
    - -
    -
    - -
    - -
    - -
    - -
    - -
    -
    - - - -
    - - - - -
    - - - -
    - - - - -
    - -
    - -
    - -
    -
    - -
    - -
    -
    - -
    - -
    -
    -
    -`; - coreModule.directive('graphThresholdForm', () => { return { restrict: 'E', - template: template, + templateUrl: 'public/app/plugins/panel/graph/thresholds_form.html', controller: ThresholdFormCtrl, bindToController: true, controllerAs: 'ctrl', diff --git a/public/app/plugins/panel/graph/time_region_manager.ts b/public/app/plugins/panel/graph/time_region_manager.ts new file mode 100644 index 00000000000..c3c6aadaa31 --- /dev/null +++ b/public/app/plugins/panel/graph/time_region_manager.ts @@ -0,0 +1,249 @@ +import 'vendor/flot/jquery.flot'; +import _ from 'lodash'; +import moment from 'moment'; +import config from 'app/core/config'; + +export const colorModes = { + custom: { title: 'Custom' }, + red: { + title: 'Red', + color: { fill: 'rgba(234, 112, 112, 0.12)', line: 'rgba(237, 46, 24, 0.60)' }, + }, + yellow: { + title: 'Yellow', + color: { fill: 'rgba(235, 138, 14, 0.12)', line: 'rgba(247, 149, 32, 0.60)' }, + }, + green: { + title: 'Green', + color: { fill: 'rgba(11, 237, 50, 0.090)', line: 'rgba(6,163,69, 0.60)' }, + }, + background3: { + themeDependent: true, + title: 'Background (3%)', + darkColor: { fill: 'rgba(255, 255, 255, 0.03)', line: 'rgba(255, 255, 255, 0.1)' }, + lightColor: { fill: 'rgba(0, 0, 0, 0.03)', line: 'rgba(0, 0, 0, 0.1)' }, + }, + background6: { + themeDependent: true, + title: 'Background (6%)', + darkColor: { fill: 'rgba(255, 255, 255, 0.06)', line: 'rgba(255, 255, 255, 0.15)' }, + lightColor: { fill: 'rgba(0, 0, 0, 0.06)', line: 'rgba(0, 0, 0, 0.15)' }, + }, + background9: { + themeDependent: true, + title: 'Background (9%)', + darkColor: { fill: 'rgba(255, 255, 255, 0.09)', line: 'rgba(255, 255, 255, 0.2)' }, + lightColor: { fill: 'rgba(0, 0, 0, 0.09)', line: 'rgba(0, 0, 0, 0.2)' }, + }, +}; + +export function getColorModes() { + return _.map(Object.keys(colorModes), key => { + return { + key: key, + value: colorModes[key].title, + }; + }); +} + +function getColor(timeRegion) { + if (Object.keys(colorModes).indexOf(timeRegion.colorMode) === -1) { + timeRegion.colorMode = 'red'; + } + + if (timeRegion.colorMode === 'custom') { + return { + fill: timeRegion.fillColor, + line: timeRegion.lineColor, + }; + } + + const colorMode = colorModes[timeRegion.colorMode]; + if (colorMode.themeDependent === true) { + return config.bootData.user.lightTheme ? colorMode.lightColor : colorMode.darkColor; + } + + return colorMode.color; +} + +export class TimeRegionManager { + plot: any; + timeRegions: any; + + constructor(private panelCtrl) {} + + draw(plot) { + this.timeRegions = this.panelCtrl.panel.timeRegions; + this.plot = plot; + } + + addFlotOptions(options, panel) { + if (!panel.timeRegions || panel.timeRegions.length === 0) { + return; + } + + const tRange = this.panelCtrl.dashboard.isTimezoneUtc() + ? { from: this.panelCtrl.range.from, to: this.panelCtrl.range.to } + : { from: this.panelCtrl.range.from.local(), to: this.panelCtrl.range.to.local() }; + + let i, hRange, timeRegion, regions, fromStart, fromEnd, timeRegionColor; + + for (i = 0; i < panel.timeRegions.length; i++) { + timeRegion = panel.timeRegions[i]; + + if (!(timeRegion.fromDayOfWeek || timeRegion.from) && !(timeRegion.toDayOfWeek || timeRegion.to)) { + continue; + } + + hRange = { + from: this.parseTimeRange(timeRegion.from), + to: this.parseTimeRange(timeRegion.to), + }; + + if (!timeRegion.fromDayOfWeek && timeRegion.toDayOfWeek) { + timeRegion.fromDayOfWeek = timeRegion.toDayOfWeek; + } + + if (!timeRegion.toDayOfWeek && timeRegion.fromDayOfWeek) { + timeRegion.toDayOfWeek = timeRegion.fromDayOfWeek; + } + + if (timeRegion.fromDayOfWeek) { + hRange.from.dayOfWeek = Number(timeRegion.fromDayOfWeek); + } + + if (timeRegion.toDayOfWeek) { + hRange.to.dayOfWeek = Number(timeRegion.toDayOfWeek); + } + + if (!hRange.from.h && hRange.to.h) { + hRange.from = hRange.to; + } + + if (hRange.from.h && !hRange.to.h) { + hRange.to = hRange.from; + } + + if (hRange.from.dayOfWeek && !hRange.from.h && !hRange.from.m) { + hRange.from.h = 0; + hRange.from.m = 0; + hRange.from.s = 0; + } + + if (hRange.to.dayOfWeek && !hRange.to.h && !hRange.to.m) { + hRange.to.h = 23; + hRange.to.m = 59; + hRange.to.s = 59; + } + + if (!hRange.from || !hRange.to) { + continue; + } + + regions = []; + + if ( + hRange.from.h >= tRange.from.hour() && + hRange.from.h <= tRange.from.hour() && + hRange.from.m >= tRange.from.minute() && + hRange.from.m <= tRange.from.minute() && + hRange.to.h >= tRange.to.hour() && + hRange.to.h <= tRange.to.hour() && + 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'); + } else { + fromEnd.add(24 - hRange.from.h, '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'); + } + + regions.push({ from: fromStart.valueOf(), to: fromEnd.valueOf() }); + fromStart.add(24, 'hours'); + } + } + + timeRegionColor = getColor(timeRegion); + + for (let j = 0; j < regions.length; j++) { + const r = regions[j]; + if (timeRegion.fill) { + options.grid.markings.push({ + xaxis: { from: r.from, to: r.to }, + color: timeRegionColor.fill, + }); + } + + if (timeRegion.line) { + options.grid.markings.push({ + xaxis: { from: r.from, to: r.from }, + color: timeRegionColor.line, + }); + options.grid.markings.push({ + xaxis: { from: r.to, to: r.to }, + color: timeRegionColor.line, + }); + } + } + } + } + + parseTimeRange(str) { + const timeRegex = /^([\d]+):?(\d{2})?/; + const result = { h: null, m: null }; + const match = timeRegex.exec(str); + + if (!match) { + return result; + } + + if (match.length > 1) { + result.h = Number(match[1]); + result.m = 0; + + if (match.length > 2 && match[2] !== undefined) { + result.m = Number(match[2]); + } + + if (result.h > 23) { + result.h = 23; + } + + if (result.m > 59) { + result.m = 59; + } + } + + return result; + } +} diff --git a/public/app/plugins/panel/graph/time_regions_form.html b/public/app/plugins/panel/graph/time_regions_form.html new file mode 100644 index 00000000000..66bf4352aa5 --- /dev/null +++ b/public/app/plugins/panel/graph/time_regions_form.html @@ -0,0 +1,64 @@ +
    +
    Time regions
    +
    +
    + +
    + +
    + +
    + +
    + + +
    + +
    + +
    + +
    + +
    + +
    +
    + + + +
    + + + + +
    + + + +
    + + + + +
    + +
    + +
    +
    + +
    + +
    +
    \ No newline at end of file diff --git a/public/app/plugins/panel/graph/time_regions_form.ts b/public/app/plugins/panel/graph/time_regions_form.ts new file mode 100644 index 00000000000..e01ec4acd0e --- /dev/null +++ b/public/app/plugins/panel/graph/time_regions_form.ts @@ -0,0 +1,73 @@ +import coreModule from 'app/core/core_module'; +import { getColorModes } from './time_region_manager'; + +export class TimeRegionFormCtrl { + panelCtrl: any; + panel: any; + disabled: boolean; + colorModes: any; + + /** @ngInject */ + constructor($scope) { + this.panel = this.panelCtrl.panel; + + const unbindDestroy = $scope.$on('$destroy', () => { + this.panelCtrl.editingTimeRegions = false; + this.panelCtrl.render(); + unbindDestroy(); + }); + + this.colorModes = getColorModes(); + this.panelCtrl.editingTimeRegions = true; + } + + render() { + this.panelCtrl.render(); + } + + addTimeRegion() { + this.panel.timeRegions.push({ + op: 'time', + fromDayOfWeek: undefined, + from: undefined, + toDayOfWeek: undefined, + to: undefined, + colorMode: 'critical', + fill: true, + line: false, + }); + this.panelCtrl.render(); + } + + removeTimeRegion(index) { + this.panel.timeRegions.splice(index, 1); + this.panelCtrl.render(); + } + + onFillColorChange(index) { + return newColor => { + this.panel.timeRegions[index].fillColor = newColor; + this.render(); + }; + } + + onLineColorChange(index) { + return newColor => { + this.panel.timeRegions[index].lineColor = newColor; + this.render(); + }; + } +} + +coreModule.directive('graphTimeRegionForm', () => { + return { + restrict: 'E', + templateUrl: 'public/app/plugins/panel/graph/time_regions_form.html', + controller: TimeRegionFormCtrl, + bindToController: true, + controllerAs: 'ctrl', + scope: { + panelCtrl: '=', + }, + }; +});