UNPKG

react-big-calendar

Version:
215 lines (195 loc) 6.64 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = getStyledEvents; var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _sortBy = _interopRequireDefault(require("lodash/sortBy")); var Event = /*#__PURE__*/function () { function Event(data, _ref) { var accessors = _ref.accessors, slotMetrics = _ref.slotMetrics; (0, _classCallCheck2.default)(this, Event); var _slotMetrics$getRange = slotMetrics.getRange(accessors.start(data), accessors.end(data)), start = _slotMetrics$getRange.start, startDate = _slotMetrics$getRange.startDate, end = _slotMetrics$getRange.end, endDate = _slotMetrics$getRange.endDate, top = _slotMetrics$getRange.top, height = _slotMetrics$getRange.height; this.start = start; this.end = end; this.startMs = +startDate; this.endMs = +endDate; this.top = top; this.height = height; this.data = data; } /** * The event's width without any overlap. */ return (0, _createClass2.default)(Event, [{ key: "_width", get: function get() { // The container event's width is determined by the maximum number of // events in any of its rows. if (this.rows) { var columns = this.rows.reduce(function (max, row) { return Math.max(max, row.leaves.length + 1); }, // add itself 0) + 1; // add the container return 100 / columns; } // The row event's width is the space left by the container, divided // among itself and its leaves. if (this.leaves) { var availableWidth = 100 - this.container._width; return availableWidth / (this.leaves.length + 1); } // The leaf event's width is determined by its row's width return this.row._width; } /** * The event's calculated width, possibly with extra width added for * overlapping effect. */ }, { key: "width", get: function get() { var noOverlap = this._width; var overlap = Math.min(100, this._width * 1.7); // Containers can always grow. if (this.rows) { return overlap; } // Rows can grow if they have leaves. if (this.leaves) { return this.leaves.length > 0 ? overlap : noOverlap; } // Leaves can grow unless they're the last item in a row. var leaves = this.row.leaves; var index = leaves.indexOf(this); return index === leaves.length - 1 ? noOverlap : overlap; } }, { key: "xOffset", get: function get() { // Containers have no offset. if (this.rows) return 0; // Rows always start where their container ends. if (this.leaves) return this.container._width; // Leaves are spread out evenly on the space left by its row. var _this$row = this.row, leaves = _this$row.leaves, xOffset = _this$row.xOffset, _width = _this$row._width; var index = leaves.indexOf(this) + 1; return xOffset + index * _width; } }]); }(); /** * Return true if event a and b is considered to be on the same row. */ function onSameRow(a, b, minimumStartDifference) { return ( // Occupies the same start slot. Math.abs(b.start - a.start) < minimumStartDifference || // A's start slot overlaps with b's end slot. b.start > a.start && b.start < a.end ); } function sortByRender(events) { var sortedByTime = (0, _sortBy.default)(events, ['startMs', function (e) { return -e.endMs; }]); var sorted = []; while (sortedByTime.length > 0) { var event = sortedByTime.shift(); sorted.push(event); for (var i = 0; i < sortedByTime.length; i++) { var test = sortedByTime[i]; // Still inside this event, look for next. if (event.endMs > test.startMs) continue; // We've found the first event of the next event group. // If that event is not right next to our current event, we have to // move it here. if (i > 0) { var _event = sortedByTime.splice(i, 1)[0]; sorted.push(_event); } // We've already found the next event group, so stop looking. break; } } return sorted; } function getStyledEvents(_ref2) { var events = _ref2.events, minimumStartDifference = _ref2.minimumStartDifference, slotMetrics = _ref2.slotMetrics, accessors = _ref2.accessors; // Create proxy events and order them so that we don't have // to fiddle with z-indexes. var proxies = events.map(function (event) { return new Event(event, { slotMetrics: slotMetrics, accessors: accessors }); }); var eventsInRenderOrder = sortByRender(proxies); // Group overlapping events, while keeping order. // Every event is always one of: container, row or leaf. // Containers can contain rows, and rows can contain leaves. var containerEvents = []; var _loop = function _loop() { var event = eventsInRenderOrder[i]; // Check if this event can go into a container event. var container = containerEvents.find(function (c) { return c.end > event.start || Math.abs(event.start - c.start) < minimumStartDifference; }); // Couldn't find a container — that means this event is a container. if (!container) { event.rows = []; containerEvents.push(event); return 1; // continue } // Found a container for the event. event.container = container; // Check if the event can be placed in an existing row. // Start looking from behind. var row = null; for (var j = container.rows.length - 1; !row && j >= 0; j--) { if (onSameRow(container.rows[j], event, minimumStartDifference)) { row = container.rows[j]; } } if (row) { // Found a row, so add it. row.leaves.push(event); event.row = row; } else { // Couldn't find a row – that means this event is a row. event.leaves = []; container.rows.push(event); } }; for (var i = 0; i < eventsInRenderOrder.length; i++) { if (_loop()) continue; } // Return the original events, along with their styles. return eventsInRenderOrder.map(function (event) { return { event: event.data, style: { top: event.top, height: event.height, width: event.width, xOffset: Math.max(0, event.xOffset) } }; }); }