datetime_breaks.js 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. /**
  2. * DevExtreme (viz/axes/datetime_breaks.js)
  3. * Version: 19.1.16
  4. * Build date: Tue Oct 18 2022
  5. *
  6. * Copyright (c) 2012 - 2022 Developer Express Inc. ALL RIGHTS RESERVED
  7. * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/
  8. */
  9. "use strict";
  10. var dateUtils = require("../../core/utils/date");
  11. var days = [0, 1, 2, 3, 4, 5, 6];
  12. function getWeekendDays(workdays) {
  13. return days.filter(function(day) {
  14. return !workdays.some(function(workDay) {
  15. return workDay === day
  16. })
  17. })
  18. }
  19. function getNextDayIndex(dayIndex) {
  20. return (dayIndex + 1) % 7
  21. }
  22. function dayBetweenWeekend(weekend, day) {
  23. var start = weekend.start;
  24. var end = weekend.end;
  25. while (start !== end) {
  26. if (start === day) {
  27. return true
  28. }
  29. start = getNextDayIndex(start)
  30. }
  31. return false
  32. }
  33. function getDaysDistance(day, end) {
  34. var length = 0;
  35. while (day !== end) {
  36. day = getNextDayIndex(day);
  37. length++
  38. }
  39. return length
  40. }
  41. function separateBreak(scaleBreak, day) {
  42. var result = [];
  43. var dayEnd = new Date(day);
  44. dayEnd.setDate(day.getDate() + 1);
  45. if (day > scaleBreak.from) {
  46. result.push({
  47. from: scaleBreak.from,
  48. to: day
  49. })
  50. }
  51. if (dayEnd < scaleBreak.to) {
  52. result.push({
  53. from: dayEnd,
  54. to: scaleBreak.to
  55. })
  56. }
  57. return result
  58. }
  59. function getWeekEndDayIndices(workDays) {
  60. var indices = getWeekendDays(workDays);
  61. if (indices.length < 7) {
  62. while (getNextDayIndex(indices[indices.length - 1]) === indices[0]) {
  63. indices.unshift(indices.pop())
  64. }
  65. }
  66. return indices
  67. }
  68. function generateDateBreaksForWeekend(min, max, weekendDayIndices) {
  69. var day = min.getDate();
  70. var breaks = [];
  71. var weekends = weekendDayIndices.reduce(function(obj, day) {
  72. var currentWeekEnd = obj[1];
  73. if (void 0 === currentWeekEnd.start) {
  74. currentWeekEnd = {
  75. start: day,
  76. end: getNextDayIndex(day)
  77. };
  78. obj[0].push(currentWeekEnd);
  79. return [obj[0], currentWeekEnd]
  80. } else {
  81. if (currentWeekEnd.end === day) {
  82. currentWeekEnd.end = getNextDayIndex(day);
  83. return obj
  84. }
  85. }
  86. currentWeekEnd = {
  87. start: day,
  88. end: getNextDayIndex(day)
  89. };
  90. obj[0].push(currentWeekEnd);
  91. return [obj[0], currentWeekEnd]
  92. }, [
  93. [], {}
  94. ]);
  95. weekends[0].forEach(function(weekend) {
  96. var currentDate = new Date(min);
  97. currentDate = dateUtils.trimTime(currentDate);
  98. while (currentDate < max) {
  99. day = currentDate.getDay();
  100. var date = currentDate.getDate();
  101. if (dayBetweenWeekend(weekend, day)) {
  102. var from = new Date(currentDate);
  103. var to;
  104. currentDate.setDate(date + getDaysDistance(day, weekend.end));
  105. to = new Date(currentDate);
  106. breaks.push({
  107. from: from,
  108. to: to
  109. })
  110. }
  111. currentDate.setDate(currentDate.getDate() + 1)
  112. }
  113. });
  114. return breaks
  115. }
  116. function excludeWorkDaysFromWeekEndBreaks(breaks, exactWorkDays) {
  117. var result = breaks.slice();
  118. var i;
  119. var processWorkDay = function(workday) {
  120. workday = dateUtils.trimTime(new Date(workday));
  121. if (result[i].from <= workday && result[i].to > workday) {
  122. var separatedBreak = separateBreak(result[i], workday);
  123. if (2 === separatedBreak.length) {
  124. result.splice(i, 1, separatedBreak[0], separatedBreak[1])
  125. } else {
  126. if (1 === separatedBreak.length) {
  127. result.splice(i, 1, separatedBreak[0])
  128. } else {
  129. result.splice(i, 1)
  130. }
  131. }
  132. }
  133. };
  134. for (i = 0; i < result.length; i++) {
  135. exactWorkDays.forEach(processWorkDay)
  136. }
  137. return result
  138. }
  139. function generateBreaksForHolidays(min, max, holidays, weekendDayIndices) {
  140. var day;
  141. var dayInWeekend = function(dayIndex) {
  142. return dayIndex === day
  143. };
  144. var adjustedMin = dateUtils.trimTime(min);
  145. var adjustedMax = dateUtils.trimTime(max);
  146. adjustedMax.setDate(max.getDate() + 1);
  147. return holidays.reduce(function(breaks, holiday) {
  148. var holidayStart;
  149. var holidayEnd;
  150. holiday = new Date(holiday);
  151. day = holiday.getDay();
  152. if (!weekendDayIndices.some(dayInWeekend) && holiday >= adjustedMin && holiday <= adjustedMax) {
  153. holidayStart = dateUtils.trimTime(holiday);
  154. holidayEnd = new Date(holidayStart);
  155. holidayEnd.setDate(holidayStart.getDate() + 1);
  156. breaks.push({
  157. from: holidayStart,
  158. to: holidayEnd
  159. })
  160. }
  161. return breaks
  162. }, [])
  163. }
  164. function calculateGaps(breaks) {
  165. return breaks.map(function(b) {
  166. return {
  167. from: b.from,
  168. to: b.to,
  169. gapSize: dateUtils.convertMillisecondsToDateUnits(b.to - b.from)
  170. }
  171. })
  172. }
  173. exports.generateDateBreaks = function(min, max, workWeek, singleWorkdays, holidays) {
  174. var weekendDayIndices = getWeekEndDayIndices(workWeek);
  175. var breaks = generateDateBreaksForWeekend(min, max, weekendDayIndices);
  176. breaks.push.apply(breaks, generateBreaksForHolidays(min, max, holidays || [], weekendDayIndices));
  177. return calculateGaps(excludeWorkDaysFromWeekEndBreaks(breaks, singleWorkdays || []))
  178. };