You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

222 lines
6.3 KiB

  1. "use strict";
  2. var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
  3. exports.__esModule = true;
  4. exports.getStyledEvents = getStyledEvents;
  5. var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
  6. var _sortBy = _interopRequireDefault(require("lodash/sortBy"));
  7. var Event =
  8. /*#__PURE__*/
  9. function () {
  10. function Event(data, _ref) {
  11. var accessors = _ref.accessors,
  12. slotMetrics = _ref.slotMetrics;
  13. var _slotMetrics$getRange = slotMetrics.getRange(accessors.start(data), accessors.end(data)),
  14. start = _slotMetrics$getRange.start,
  15. startDate = _slotMetrics$getRange.startDate,
  16. end = _slotMetrics$getRange.end,
  17. endDate = _slotMetrics$getRange.endDate,
  18. top = _slotMetrics$getRange.top,
  19. height = _slotMetrics$getRange.height;
  20. this.start = start;
  21. this.end = end;
  22. this.startMs = +startDate;
  23. this.endMs = +endDate;
  24. this.top = top;
  25. this.height = height;
  26. this.data = data;
  27. }
  28. /**
  29. * The event's width without any overlap.
  30. */
  31. (0, _createClass2.default)(Event, [{
  32. key: "_width",
  33. get: function get() {
  34. // The container event's width is determined by the maximum number of
  35. // events in any of its rows.
  36. if (this.rows) {
  37. var columns = this.rows.reduce(function (max, row) {
  38. return Math.max(max, row.leaves.length + 1);
  39. }, // add itself
  40. 0) + 1; // add the container
  41. return 100 / columns;
  42. }
  43. var availableWidth = 100 - this.container._width; // The row event's width is the space left by the container, divided
  44. // among itself and its leaves.
  45. if (this.leaves) {
  46. return availableWidth / (this.leaves.length + 1);
  47. } // The leaf event's width is determined by its row's width
  48. return this.row._width;
  49. }
  50. /**
  51. * The event's calculated width, possibly with extra width added for
  52. * overlapping effect.
  53. */
  54. }, {
  55. key: "width",
  56. get: function get() {
  57. var noOverlap = this._width;
  58. var overlap = Math.min(100, this._width * 1.7); // Containers can always grow.
  59. if (this.rows) {
  60. return overlap;
  61. } // Rows can grow if they have leaves.
  62. if (this.leaves) {
  63. return this.leaves.length > 0 ? overlap : noOverlap;
  64. } // Leaves can grow unless they're the last item in a row.
  65. var leaves = this.row.leaves;
  66. var index = leaves.indexOf(this);
  67. return index === leaves.length - 1 ? noOverlap : overlap;
  68. }
  69. }, {
  70. key: "xOffset",
  71. get: function get() {
  72. // Containers have no offset.
  73. if (this.rows) return 0; // Rows always start where their container ends.
  74. if (this.leaves) return this.container._width; // Leaves are spread out evenly on the space left by its row.
  75. var _this$row = this.row,
  76. leaves = _this$row.leaves,
  77. xOffset = _this$row.xOffset,
  78. _width = _this$row._width;
  79. var index = leaves.indexOf(this) + 1;
  80. return xOffset + index * _width;
  81. }
  82. }]);
  83. return Event;
  84. }();
  85. /**
  86. * Return true if event a and b is considered to be on the same row.
  87. */
  88. function onSameRow(a, b, minimumStartDifference) {
  89. return (// Occupies the same start slot.
  90. Math.abs(b.start - a.start) < minimumStartDifference || // A's start slot overlaps with b's end slot.
  91. b.start > a.start && b.start < a.end
  92. );
  93. }
  94. function sortByRender(events) {
  95. var sortedByTime = (0, _sortBy.default)(events, ['startMs', function (e) {
  96. return -e.endMs;
  97. }]);
  98. var sorted = [];
  99. while (sortedByTime.length > 0) {
  100. var event = sortedByTime.shift();
  101. sorted.push(event);
  102. for (var i = 0; i < sortedByTime.length; i++) {
  103. var test = sortedByTime[i]; // Still inside this event, look for next.
  104. if (event.endMs > test.startMs) continue; // We've found the first event of the next event group.
  105. // If that event is not right next to our current event, we have to
  106. // move it here.
  107. if (i > 0) {
  108. var _event = sortedByTime.splice(i, 1)[0];
  109. sorted.push(_event);
  110. } // We've already found the next event group, so stop looking.
  111. break;
  112. }
  113. }
  114. return sorted;
  115. }
  116. function getStyledEvents(_ref2) {
  117. var events = _ref2.events,
  118. minimumStartDifference = _ref2.minimumStartDifference,
  119. slotMetrics = _ref2.slotMetrics,
  120. accessors = _ref2.accessors;
  121. // Create proxy events and order them so that we don't have
  122. // to fiddle with z-indexes.
  123. var proxies = events.map(function (event) {
  124. return new Event(event, {
  125. slotMetrics: slotMetrics,
  126. accessors: accessors
  127. });
  128. });
  129. var eventsInRenderOrder = sortByRender(proxies); // Group overlapping events, while keeping order.
  130. // Every event is always one of: container, row or leaf.
  131. // Containers can contain rows, and rows can contain leaves.
  132. var containerEvents = [];
  133. var _loop = function _loop(i) {
  134. var event = eventsInRenderOrder[i]; // Check if this event can go into a container event.
  135. var container = containerEvents.find(function (c) {
  136. return c.end > event.start || Math.abs(event.start - c.start) < minimumStartDifference;
  137. }); // Couldn't find a container — that means this event is a container.
  138. if (!container) {
  139. event.rows = [];
  140. containerEvents.push(event);
  141. return "continue";
  142. } // Found a container for the event.
  143. event.container = container; // Check if the event can be placed in an existing row.
  144. // Start looking from behind.
  145. var row = null;
  146. for (var j = container.rows.length - 1; !row && j >= 0; j--) {
  147. if (onSameRow(container.rows[j], event, minimumStartDifference)) {
  148. row = container.rows[j];
  149. }
  150. }
  151. if (row) {
  152. // Found a row, so add it.
  153. row.leaves.push(event);
  154. event.row = row;
  155. } else {
  156. // Couldn't find a row – that means this event is a row.
  157. event.leaves = [];
  158. container.rows.push(event);
  159. }
  160. };
  161. for (var i = 0; i < eventsInRenderOrder.length; i++) {
  162. var _ret = _loop(i);
  163. if (_ret === "continue") continue;
  164. } // Return the original events, along with their styles.
  165. return eventsInRenderOrder.map(function (event) {
  166. return {
  167. event: event.data,
  168. style: {
  169. top: event.top,
  170. height: event.height,
  171. width: event.width,
  172. xOffset: event.xOffset
  173. }
  174. };
  175. });
  176. }