time_region_manager.ts 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. import 'vendor/flot/jquery.flot';
  2. import _ from 'lodash';
  3. import moment from 'moment';
  4. import config from 'app/core/config';
  5. export const colorModes = {
  6. gray: {
  7. themeDependent: true,
  8. title: 'Gray',
  9. darkColor: { fill: 'rgba(255, 255, 255, 0.09)', line: 'rgba(255, 255, 255, 0.2)' },
  10. lightColor: { fill: 'rgba(0, 0, 0, 0.09)', line: 'rgba(0, 0, 0, 0.2)' },
  11. },
  12. red: {
  13. title: 'Red',
  14. color: { fill: 'rgba(234, 112, 112, 0.12)', line: 'rgba(237, 46, 24, 0.60)' },
  15. },
  16. green: {
  17. title: 'Green',
  18. color: { fill: 'rgba(11, 237, 50, 0.090)', line: 'rgba(6,163,69, 0.60)' },
  19. },
  20. blue: {
  21. title: 'Blue',
  22. color: { fill: 'rgba(11, 125, 238, 0.12)', line: 'rgba(11, 125, 238, 0.60)' },
  23. },
  24. yellow: {
  25. title: 'Yellow',
  26. color: { fill: 'rgba(235, 138, 14, 0.12)', line: 'rgba(247, 149, 32, 0.60)' },
  27. },
  28. custom: { title: 'Custom' },
  29. };
  30. export function getColorModes() {
  31. return _.map(Object.keys(colorModes), key => {
  32. return {
  33. key: key,
  34. value: colorModes[key].title,
  35. };
  36. });
  37. }
  38. function getColor(timeRegion) {
  39. if (Object.keys(colorModes).indexOf(timeRegion.colorMode) === -1) {
  40. timeRegion.colorMode = 'red';
  41. }
  42. if (timeRegion.colorMode === 'custom') {
  43. return {
  44. fill: timeRegion.fillColor,
  45. line: timeRegion.lineColor,
  46. };
  47. }
  48. const colorMode = colorModes[timeRegion.colorMode];
  49. if (colorMode.themeDependent === true) {
  50. return config.bootData.user.lightTheme ? colorMode.lightColor : colorMode.darkColor;
  51. }
  52. return colorMode.color;
  53. }
  54. export class TimeRegionManager {
  55. plot: any;
  56. timeRegions: any;
  57. constructor(private panelCtrl) {}
  58. draw(plot) {
  59. this.timeRegions = this.panelCtrl.panel.timeRegions;
  60. this.plot = plot;
  61. }
  62. addFlotOptions(options, panel) {
  63. if (!panel.timeRegions || panel.timeRegions.length === 0) {
  64. return;
  65. }
  66. const tRange = { from: moment(this.panelCtrl.range.from).utc(), to: moment(this.panelCtrl.range.to).utc() };
  67. let i, hRange, timeRegion, regions, fromStart, fromEnd, timeRegionColor;
  68. const timeRegionsCopy = panel.timeRegions.map(a => ({ ...a }));
  69. for (i = 0; i < timeRegionsCopy.length; i++) {
  70. timeRegion = timeRegionsCopy[i];
  71. if (!(timeRegion.fromDayOfWeek || timeRegion.from) && !(timeRegion.toDayOfWeek || timeRegion.to)) {
  72. continue;
  73. }
  74. if (timeRegion.from && !timeRegion.to) {
  75. timeRegion.to = timeRegion.from;
  76. }
  77. if (!timeRegion.from && timeRegion.to) {
  78. timeRegion.from = timeRegion.to;
  79. }
  80. hRange = {
  81. from: this.parseTimeRange(timeRegion.from),
  82. to: this.parseTimeRange(timeRegion.to),
  83. };
  84. if (!timeRegion.fromDayOfWeek && timeRegion.toDayOfWeek) {
  85. timeRegion.fromDayOfWeek = timeRegion.toDayOfWeek;
  86. }
  87. if (!timeRegion.toDayOfWeek && timeRegion.fromDayOfWeek) {
  88. timeRegion.toDayOfWeek = timeRegion.fromDayOfWeek;
  89. }
  90. if (timeRegion.fromDayOfWeek) {
  91. hRange.from.dayOfWeek = Number(timeRegion.fromDayOfWeek);
  92. }
  93. if (timeRegion.toDayOfWeek) {
  94. hRange.to.dayOfWeek = Number(timeRegion.toDayOfWeek);
  95. }
  96. if (hRange.from.dayOfWeek && hRange.from.h === null && hRange.from.m === null) {
  97. hRange.from.h = 0;
  98. hRange.from.m = 0;
  99. hRange.from.s = 0;
  100. }
  101. if (hRange.to.dayOfWeek && hRange.to.h === null && hRange.to.m === null) {
  102. hRange.to.h = 23;
  103. hRange.to.m = 59;
  104. hRange.to.s = 59;
  105. }
  106. if (!hRange.from || !hRange.to) {
  107. continue;
  108. }
  109. regions = [];
  110. if (
  111. hRange.from.h >= tRange.from.hour() &&
  112. hRange.from.h <= tRange.from.hour() &&
  113. hRange.from.m >= tRange.from.minute() &&
  114. hRange.from.m <= tRange.from.minute() &&
  115. hRange.to.h >= tRange.to.hour() &&
  116. hRange.to.h <= tRange.to.hour() &&
  117. hRange.to.m >= tRange.to.minute() &&
  118. hRange.to.m <= tRange.to.minute()
  119. ) {
  120. regions.push({ from: tRange.from.valueOf(), to: tRange.to.startOf('hour').valueOf() });
  121. } else {
  122. fromStart = moment(tRange.from);
  123. fromStart.set('hour', 0);
  124. fromStart.set('minute', 0);
  125. fromStart.set('second', 0);
  126. fromStart.add(hRange.from.h, 'hours');
  127. fromStart.add(hRange.from.m, 'minutes');
  128. fromStart.add(hRange.from.s, 'seconds');
  129. while (fromStart.unix() <= tRange.to.unix()) {
  130. while (hRange.from.dayOfWeek && hRange.from.dayOfWeek !== fromStart.isoWeekday()) {
  131. fromStart.add(24, 'hours');
  132. }
  133. if (fromStart.unix() > tRange.to.unix()) {
  134. break;
  135. }
  136. fromEnd = moment(fromStart);
  137. if (hRange.from.h <= hRange.to.h) {
  138. fromEnd.add(hRange.to.h - hRange.from.h, 'hours');
  139. } else if (hRange.from.h + hRange.to.h < 23) {
  140. fromEnd.add(hRange.to.h, 'hours');
  141. while (fromEnd.hour() !== hRange.to.h) {
  142. fromEnd.add(-1, 'hours');
  143. }
  144. } else {
  145. fromEnd.add(24 - hRange.from.h, 'hours');
  146. while (fromEnd.hour() !== hRange.to.h) {
  147. fromEnd.add(1, 'hours');
  148. }
  149. }
  150. fromEnd.set('minute', hRange.to.m);
  151. fromEnd.set('second', hRange.to.s);
  152. while (hRange.to.dayOfWeek && hRange.to.dayOfWeek !== fromEnd.isoWeekday()) {
  153. fromEnd.add(24, 'hours');
  154. }
  155. const outsideRange =
  156. (fromStart.unix() < tRange.from.unix() && fromEnd.unix() < tRange.from.unix()) ||
  157. (fromStart.unix() > tRange.to.unix() && fromEnd.unix() > tRange.to.unix());
  158. if (!outsideRange) {
  159. regions.push({ from: fromStart.valueOf(), to: fromEnd.valueOf() });
  160. }
  161. fromStart.add(24, 'hours');
  162. }
  163. }
  164. timeRegionColor = getColor(timeRegion);
  165. for (let j = 0; j < regions.length; j++) {
  166. const r = regions[j];
  167. if (timeRegion.fill) {
  168. options.grid.markings.push({
  169. xaxis: { from: r.from, to: r.to },
  170. color: timeRegionColor.fill,
  171. });
  172. }
  173. if (timeRegion.line) {
  174. options.grid.markings.push({
  175. xaxis: { from: r.from, to: r.from },
  176. color: timeRegionColor.line,
  177. });
  178. options.grid.markings.push({
  179. xaxis: { from: r.to, to: r.to },
  180. color: timeRegionColor.line,
  181. });
  182. }
  183. }
  184. }
  185. }
  186. parseTimeRange(str) {
  187. const timeRegex = /^([\d]+):?(\d{2})?/;
  188. const result = { h: null, m: null };
  189. const match = timeRegex.exec(str);
  190. if (!match) {
  191. return result;
  192. }
  193. if (match.length > 1) {
  194. result.h = Number(match[1]);
  195. result.m = 0;
  196. if (match.length > 2 && match[2] !== undefined) {
  197. result.m = Number(match[2]);
  198. }
  199. if (result.h > 23) {
  200. result.h = 23;
  201. }
  202. if (result.m > 59) {
  203. result.m = 59;
  204. }
  205. }
  206. return result;
  207. }
  208. }