@oddle.me/react-calendar-timeline 0.28.1-0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +8 -0
- package/README.md +1298 -0
- package/lib/Timeline.css +110 -0
- package/lib/index.js +77 -0
- package/lib/lib/Timeline.js +966 -0
- package/lib/lib/columns/Columns.js +137 -0
- package/lib/lib/default-config.js +73 -0
- package/lib/lib/headers/CustomDateHeader.js +48 -0
- package/lib/lib/headers/CustomHeader.js +276 -0
- package/lib/lib/headers/DateHeader.js +206 -0
- package/lib/lib/headers/HeadersContext.js +94 -0
- package/lib/lib/headers/Interval.js +131 -0
- package/lib/lib/headers/SidebarHeader.js +130 -0
- package/lib/lib/headers/TimelineHeaders.js +180 -0
- package/lib/lib/headers/constants.js +10 -0
- package/lib/lib/interaction/PreventClickOnDrag.js +99 -0
- package/lib/lib/items/Item.js +627 -0
- package/lib/lib/items/Items.js +178 -0
- package/lib/lib/items/defaultItemRenderer.js +40 -0
- package/lib/lib/items/styles.js +65 -0
- package/lib/lib/layout/Sidebar.js +138 -0
- package/lib/lib/markers/MarkerCanvas.js +164 -0
- package/lib/lib/markers/MarkerCanvasContext.js +28 -0
- package/lib/lib/markers/TimelineMarkersContext.js +157 -0
- package/lib/lib/markers/TimelineMarkersRenderer.js +69 -0
- package/lib/lib/markers/implementations/CursorMarker.js +137 -0
- package/lib/lib/markers/implementations/CustomMarker.js +79 -0
- package/lib/lib/markers/implementations/TodayMarker.js +123 -0
- package/lib/lib/markers/implementations/shared.js +51 -0
- package/lib/lib/markers/markerType.js +12 -0
- package/lib/lib/markers/public/CursorMarker.js +97 -0
- package/lib/lib/markers/public/CustomMarker.js +116 -0
- package/lib/lib/markers/public/TimelineMarkers.js +27 -0
- package/lib/lib/markers/public/TodayMarker.js +121 -0
- package/lib/lib/row/GroupRow.js +94 -0
- package/lib/lib/row/GroupRows.js +117 -0
- package/lib/lib/scroll/ScrollElement.js +285 -0
- package/lib/lib/timeline/TimelineStateContext.js +155 -0
- package/lib/lib/utility/calendar.js +672 -0
- package/lib/lib/utility/dom-helpers.js +62 -0
- package/lib/lib/utility/events.js +23 -0
- package/lib/lib/utility/generic.js +44 -0
- package/lib/resize-detector/container.js +36 -0
- package/lib/resize-detector/window.js +25 -0
- package/package.json +162 -0
- package/src/global.d.ts +373 -0
|
@@ -0,0 +1,672 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.coordinateToTimeRatio = coordinateToTimeRatio;
|
|
7
|
+
exports.calculateXPositionForTime = calculateXPositionForTime;
|
|
8
|
+
exports.calculateTimeForXPosition = calculateTimeForXPosition;
|
|
9
|
+
exports.iterateTimes = iterateTimes;
|
|
10
|
+
exports.getMinUnit = getMinUnit;
|
|
11
|
+
exports.getNextUnit = getNextUnit;
|
|
12
|
+
exports.calculateInteractionNewTimes = calculateInteractionNewTimes;
|
|
13
|
+
exports.calculateDimensions = calculateDimensions;
|
|
14
|
+
exports.getGroupOrders = getGroupOrders;
|
|
15
|
+
exports.getGroupedItems = getGroupedItems;
|
|
16
|
+
exports.getVisibleItems = getVisibleItems;
|
|
17
|
+
exports.collision = collision;
|
|
18
|
+
exports.groupStack = groupStack;
|
|
19
|
+
exports.groupNoStack = groupNoStack;
|
|
20
|
+
exports.stackAll = stackAll;
|
|
21
|
+
exports.stackGroup = stackGroup;
|
|
22
|
+
exports.stackTimelineItems = stackTimelineItems;
|
|
23
|
+
exports.getCanvasWidth = getCanvasWidth;
|
|
24
|
+
exports.getItemDimensions = getItemDimensions;
|
|
25
|
+
exports.getItemWithInteractions = getItemWithInteractions;
|
|
26
|
+
exports.getCanvasBoundariesFromVisibleTime = getCanvasBoundariesFromVisibleTime;
|
|
27
|
+
exports.calculateScrollCanvas = calculateScrollCanvas;
|
|
28
|
+
exports.minCellWidth = void 0;
|
|
29
|
+
|
|
30
|
+
var _moment = _interopRequireDefault(require("moment"));
|
|
31
|
+
|
|
32
|
+
var _generic = require("./generic");
|
|
33
|
+
|
|
34
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
|
|
35
|
+
|
|
36
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { if (i % 2) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } else { Object.defineProperties(target, Object.getOwnPropertyDescriptors(arguments[i])); } } return target; }
|
|
37
|
+
|
|
38
|
+
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
39
|
+
|
|
40
|
+
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }
|
|
41
|
+
|
|
42
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }
|
|
43
|
+
|
|
44
|
+
function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
|
45
|
+
|
|
46
|
+
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Calculate the ms / pixel ratio of the timeline state
|
|
50
|
+
* @param {number} canvasTimeStart
|
|
51
|
+
* @param {number} canvasTimeEnd
|
|
52
|
+
* @param {number} canvasWidth
|
|
53
|
+
* @returns {number}
|
|
54
|
+
*/
|
|
55
|
+
function coordinateToTimeRatio(canvasTimeStart, canvasTimeEnd, canvasWidth) {
|
|
56
|
+
return (canvasTimeEnd - canvasTimeStart) / canvasWidth;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* For a given time, calculate the pixel position given timeline state
|
|
60
|
+
* (timeline width in px, canvas time range)
|
|
61
|
+
* @param {number} canvasTimeStart
|
|
62
|
+
* @param {number} canvasTimeEnd
|
|
63
|
+
* @param {number} canvasWidth
|
|
64
|
+
* @param {number} time
|
|
65
|
+
* @returns {number}
|
|
66
|
+
*/
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
function calculateXPositionForTime(canvasTimeStart, canvasTimeEnd, canvasWidth, time) {
|
|
70
|
+
var widthToZoomRatio = canvasWidth / (canvasTimeEnd - canvasTimeStart);
|
|
71
|
+
var timeOffset = time - canvasTimeStart;
|
|
72
|
+
return timeOffset * widthToZoomRatio;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* For a given x position (leftOffset) in pixels, calculate time based on
|
|
76
|
+
* timeline state (timeline width in px, canvas time range)
|
|
77
|
+
* @param {number} canvasTimeStart
|
|
78
|
+
* @param {number} canvasTimeEnd
|
|
79
|
+
* @param {number} canvasWidth
|
|
80
|
+
* @param {number} leftOffset
|
|
81
|
+
* @returns {number}
|
|
82
|
+
*/
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
function calculateTimeForXPosition(canvasTimeStart, canvasTimeEnd, canvasWidth, leftOffset) {
|
|
86
|
+
var timeToPxRatio = (canvasTimeEnd - canvasTimeStart) / canvasWidth;
|
|
87
|
+
var timeFromCanvasTimeStart = timeToPxRatio * leftOffset;
|
|
88
|
+
return timeFromCanvasTimeStart + canvasTimeStart;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function iterateTimes(start, end, unit, timeSteps, callback) {
|
|
92
|
+
var time = (0, _moment["default"])(start).startOf(unit);
|
|
93
|
+
|
|
94
|
+
if (timeSteps[unit] && timeSteps[unit] > 1) {
|
|
95
|
+
var value = time.get(unit);
|
|
96
|
+
time.set(unit, value - value % timeSteps[unit]);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
while (time.valueOf() < end) {
|
|
100
|
+
var nextTime = (0, _moment["default"])(time).add(timeSteps[unit] || 1, "".concat(unit, "s"));
|
|
101
|
+
callback(time, nextTime);
|
|
102
|
+
time = nextTime;
|
|
103
|
+
}
|
|
104
|
+
} // this function is VERY HOT as its used in Timeline.js render function
|
|
105
|
+
// TODO: check if there are performance implications here
|
|
106
|
+
// when "weeks" feature is implemented, this function will be modified heavily
|
|
107
|
+
|
|
108
|
+
/** determine the current rendered time unit based on timeline time span
|
|
109
|
+
*
|
|
110
|
+
* zoom: (in milliseconds) difference between time start and time end of timeline canvas
|
|
111
|
+
* width: (in pixels) pixel width of timeline canvas
|
|
112
|
+
* timeSteps: map of timeDividers with number to indicate step of each divider
|
|
113
|
+
*/
|
|
114
|
+
// the smallest cell we want to render is 17px
|
|
115
|
+
// this can be manipulated to make the breakpoints change more/less
|
|
116
|
+
// i.e. on zoom how often do we switch to the next unit of time
|
|
117
|
+
// i think this is the distance between cell lines
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
var minCellWidth = 17;
|
|
121
|
+
exports.minCellWidth = minCellWidth;
|
|
122
|
+
|
|
123
|
+
function getMinUnit(zoom, width, timeSteps) {
|
|
124
|
+
// for supporting weeks, its important to remember that each of these
|
|
125
|
+
// units has a natural progression to the other. i.e. a year is 12 months
|
|
126
|
+
// a month is 24 days, a day is 24 hours.
|
|
127
|
+
// with weeks this isnt the case so weeks needs to be handled specially
|
|
128
|
+
var timeDividers = {
|
|
129
|
+
second: 1000,
|
|
130
|
+
minute: 60,
|
|
131
|
+
hour: 60,
|
|
132
|
+
day: 24,
|
|
133
|
+
month: 30,
|
|
134
|
+
year: 12
|
|
135
|
+
};
|
|
136
|
+
var minUnit = 'year'; // this timespan is in ms initially
|
|
137
|
+
|
|
138
|
+
var nextTimeSpanInUnitContext = zoom;
|
|
139
|
+
Object.keys(timeDividers).some(function (unit) {
|
|
140
|
+
// converts previous time span to current unit
|
|
141
|
+
// (e.g. milliseconds to seconds, seconds to minutes, etc)
|
|
142
|
+
nextTimeSpanInUnitContext = nextTimeSpanInUnitContext / timeDividers[unit]; // timeSteps is "
|
|
143
|
+
// With what step to display different units. E.g. 15 for minute means only minutes 0, 15, 30 and 45 will be shown."
|
|
144
|
+
// how many cells would be rendered given this time span, for this unit?
|
|
145
|
+
// e.g. for time span of 60 minutes, and time step of 1, we would render 60 cells
|
|
146
|
+
|
|
147
|
+
var cellsToBeRenderedForCurrentUnit = nextTimeSpanInUnitContext / timeSteps[unit]; // what is happening here? why 3 if time steps are greater than 1??
|
|
148
|
+
|
|
149
|
+
var cellWidthToUse = timeSteps[unit] && timeSteps[unit] > 1 ? 3 * minCellWidth : minCellWidth; // for the minWidth of a cell, how many cells would be rendered given
|
|
150
|
+
// the current pixel width
|
|
151
|
+
// i.e. f
|
|
152
|
+
|
|
153
|
+
var minimumCellsToRenderUnit = width / cellWidthToUse;
|
|
154
|
+
|
|
155
|
+
if (cellsToBeRenderedForCurrentUnit < minimumCellsToRenderUnit) {
|
|
156
|
+
// for the current zoom, the number of cells we'd need to render all parts of this unit
|
|
157
|
+
// is less than the minimum number of cells needed at minimum cell width
|
|
158
|
+
minUnit = unit;
|
|
159
|
+
return true;
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
return minUnit;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function getNextUnit(unit) {
|
|
166
|
+
var nextUnits = {
|
|
167
|
+
second: 'minute',
|
|
168
|
+
minute: 'hour',
|
|
169
|
+
hour: 'day',
|
|
170
|
+
day: 'month',
|
|
171
|
+
month: 'year',
|
|
172
|
+
year: 'year'
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
if (!nextUnits[unit]) {
|
|
176
|
+
throw new Error("unit ".concat(unit, " in not acceptable"));
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return nextUnits[unit];
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* get the new start and new end time of item that is being
|
|
183
|
+
* dragged or resized
|
|
184
|
+
* @param {*} itemTimeStart original item time in milliseconds
|
|
185
|
+
* @param {*} itemTimeEnd original item time in milliseconds
|
|
186
|
+
* @param {*} dragTime new start time if item is dragged in milliseconds
|
|
187
|
+
* @param {*} isDragging is item being dragged
|
|
188
|
+
* @param {*} isResizing is item being resized
|
|
189
|
+
* @param {`right` or `left`} resizingEdge resize edge
|
|
190
|
+
* @param {*} resizeTime new resize time in milliseconds
|
|
191
|
+
*/
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
function calculateInteractionNewTimes(_ref) {
|
|
195
|
+
var itemTimeStart = _ref.itemTimeStart,
|
|
196
|
+
itemTimeEnd = _ref.itemTimeEnd,
|
|
197
|
+
dragTime = _ref.dragTime,
|
|
198
|
+
isDragging = _ref.isDragging,
|
|
199
|
+
isResizing = _ref.isResizing,
|
|
200
|
+
resizingEdge = _ref.resizingEdge,
|
|
201
|
+
resizeTime = _ref.resizeTime;
|
|
202
|
+
var originalItemRange = itemTimeEnd - itemTimeStart;
|
|
203
|
+
var itemStart = isResizing && resizingEdge === 'left' ? resizeTime : itemTimeStart;
|
|
204
|
+
var itemEnd = isResizing && resizingEdge === 'right' ? resizeTime : itemTimeEnd;
|
|
205
|
+
return [isDragging ? dragTime : itemStart, isDragging ? dragTime + originalItemRange : itemEnd];
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
function calculateDimensions(_ref2) {
|
|
209
|
+
var itemTimeStart = _ref2.itemTimeStart,
|
|
210
|
+
itemTimeEnd = _ref2.itemTimeEnd,
|
|
211
|
+
canvasTimeStart = _ref2.canvasTimeStart,
|
|
212
|
+
canvasTimeEnd = _ref2.canvasTimeEnd,
|
|
213
|
+
canvasWidth = _ref2.canvasWidth;
|
|
214
|
+
var itemTimeRange = itemTimeEnd - itemTimeStart; // restrict startTime and endTime to be bounded by canvasTimeStart and canvasTimeEnd
|
|
215
|
+
|
|
216
|
+
var effectiveStartTime = Math.max(itemTimeStart, canvasTimeStart);
|
|
217
|
+
var effectiveEndTime = Math.min(itemTimeEnd, canvasTimeEnd);
|
|
218
|
+
var left = calculateXPositionForTime(canvasTimeStart, canvasTimeEnd, canvasWidth, effectiveStartTime);
|
|
219
|
+
var right = calculateXPositionForTime(canvasTimeStart, canvasTimeEnd, canvasWidth, effectiveEndTime);
|
|
220
|
+
var itemWidth = right - left;
|
|
221
|
+
var dimensions = {
|
|
222
|
+
left: left,
|
|
223
|
+
width: Math.max(itemWidth, 3),
|
|
224
|
+
collisionLeft: itemTimeStart,
|
|
225
|
+
collisionWidth: itemTimeRange
|
|
226
|
+
};
|
|
227
|
+
return dimensions;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Get the order of groups based on their keys
|
|
231
|
+
* @param {*} groups array of groups
|
|
232
|
+
* @param {*} keys the keys object
|
|
233
|
+
* @returns Ordered hash of objects with their array index and group
|
|
234
|
+
*/
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
function getGroupOrders(groups, keys) {
|
|
238
|
+
var groupIdKey = keys.groupIdKey;
|
|
239
|
+
var groupOrders = {};
|
|
240
|
+
|
|
241
|
+
for (var i = 0; i < groups.length; i++) {
|
|
242
|
+
groupOrders[(0, _generic._get)(groups[i], groupIdKey)] = {
|
|
243
|
+
index: i,
|
|
244
|
+
group: groups[i]
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
return groupOrders;
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Adds items relevant to each group to the result of getGroupOrders
|
|
252
|
+
* @param {*} items list of all items
|
|
253
|
+
* @param {*} groupOrders the result of getGroupOrders
|
|
254
|
+
*/
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
function getGroupedItems(items, groupOrders) {
|
|
258
|
+
var groupedItems = {};
|
|
259
|
+
var keys = Object.keys(groupOrders); // Initialize with result object for each group
|
|
260
|
+
|
|
261
|
+
for (var i = 0; i < keys.length; i++) {
|
|
262
|
+
var groupOrder = groupOrders[keys[i]];
|
|
263
|
+
groupedItems[i] = {
|
|
264
|
+
index: groupOrder.index,
|
|
265
|
+
group: groupOrder.group,
|
|
266
|
+
items: []
|
|
267
|
+
};
|
|
268
|
+
} // Populate groups
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
for (var _i = 0; _i < items.length; _i++) {
|
|
272
|
+
if (items[_i].dimensions.order !== undefined) {
|
|
273
|
+
var groupItem = groupedItems[items[_i].dimensions.order.index];
|
|
274
|
+
|
|
275
|
+
if (groupItem) {
|
|
276
|
+
groupItem.items.push(items[_i]);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
return groupedItems;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
function getVisibleItems(items, canvasTimeStart, canvasTimeEnd, keys) {
|
|
285
|
+
var itemTimeStartKey = keys.itemTimeStartKey,
|
|
286
|
+
itemTimeEndKey = keys.itemTimeEndKey;
|
|
287
|
+
return items.filter(function (item) {
|
|
288
|
+
return (0, _generic._get)(item, itemTimeStartKey) <= canvasTimeEnd && (0, _generic._get)(item, itemTimeEndKey) >= canvasTimeStart;
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
var EPSILON = 0.001;
|
|
293
|
+
|
|
294
|
+
function collision(a, b, lineHeight) {
|
|
295
|
+
var collisionPadding = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : EPSILON;
|
|
296
|
+
// 2d collisions detection - https://developer.mozilla.org/en-US/docs/Games/Techniques/2D_collision_detection
|
|
297
|
+
var verticalMargin = 0;
|
|
298
|
+
return a.collisionLeft + collisionPadding < b.collisionLeft + b.collisionWidth && a.collisionLeft + a.collisionWidth - collisionPadding > b.collisionLeft && a.top - verticalMargin + collisionPadding < b.top + b.height && a.top + a.height + verticalMargin - collisionPadding > b.top;
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* Calculate the position of a given item for a group that
|
|
302
|
+
* is being stacked
|
|
303
|
+
*/
|
|
304
|
+
|
|
305
|
+
|
|
306
|
+
function groupStack(lineHeight, item, group, groupHeight, groupTop, itemIndex) {
|
|
307
|
+
// calculate non-overlapping positions
|
|
308
|
+
var curHeight = groupHeight;
|
|
309
|
+
var verticalMargin = (lineHeight - item.dimensions.height) / 2;
|
|
310
|
+
|
|
311
|
+
if (item.dimensions.stack && item.dimensions.top === null) {
|
|
312
|
+
item.dimensions.top = groupTop + verticalMargin;
|
|
313
|
+
curHeight = Math.max(curHeight, lineHeight);
|
|
314
|
+
|
|
315
|
+
do {
|
|
316
|
+
var collidingItem = null; //Items are placed from i=0 onwards, only check items with index < i
|
|
317
|
+
|
|
318
|
+
for (var j = itemIndex - 1, jj = 0; j >= jj; j--) {
|
|
319
|
+
var other = group[j];
|
|
320
|
+
|
|
321
|
+
if (other.dimensions.top !== null && other.dimensions.stack && collision(item.dimensions, other.dimensions, lineHeight)) {
|
|
322
|
+
collidingItem = other;
|
|
323
|
+
break;
|
|
324
|
+
} else {// console.log('dont test', other.top !== null, other !== item, other.stack);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
if (collidingItem != null) {
|
|
329
|
+
// There is a collision. Reposition the items above the colliding element
|
|
330
|
+
item.dimensions.top = collidingItem.dimensions.top + lineHeight;
|
|
331
|
+
curHeight = Math.max(curHeight, item.dimensions.top + item.dimensions.height + verticalMargin - groupTop);
|
|
332
|
+
}
|
|
333
|
+
} while (collidingItem);
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
return {
|
|
337
|
+
groupHeight: curHeight,
|
|
338
|
+
verticalMargin: verticalMargin,
|
|
339
|
+
itemTop: item.dimensions.top
|
|
340
|
+
};
|
|
341
|
+
} // Calculate the position of this item for a group that is not being stacked
|
|
342
|
+
|
|
343
|
+
|
|
344
|
+
function groupNoStack(lineHeight, item, groupHeight, groupTop) {
|
|
345
|
+
var verticalMargin = (lineHeight - item.dimensions.height) / 2;
|
|
346
|
+
|
|
347
|
+
if (item.dimensions.top === null) {
|
|
348
|
+
item.dimensions.top = groupTop + verticalMargin;
|
|
349
|
+
groupHeight = Math.max(groupHeight, lineHeight);
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
return {
|
|
353
|
+
groupHeight: groupHeight,
|
|
354
|
+
verticalMargin: 0,
|
|
355
|
+
itemTop: item.dimensions.top
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
function sum() {
|
|
360
|
+
var arr = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
|
|
361
|
+
return arr.reduce(function (acc, i) {
|
|
362
|
+
return acc + i;
|
|
363
|
+
}, 0);
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* Stack all groups
|
|
367
|
+
* @param {*} items items to be stacked
|
|
368
|
+
* @param {*} groupOrders the groupOrders object
|
|
369
|
+
* @param {*} lineHeight
|
|
370
|
+
* @param {*} stackItems should items be stacked?
|
|
371
|
+
*/
|
|
372
|
+
|
|
373
|
+
|
|
374
|
+
function stackAll(itemsDimensions, groupOrders, lineHeight, stackItems) {
|
|
375
|
+
var groupHeights = [];
|
|
376
|
+
var groupTops = [];
|
|
377
|
+
var groupedItems = getGroupedItems(itemsDimensions, groupOrders);
|
|
378
|
+
|
|
379
|
+
for (var index in groupedItems) {
|
|
380
|
+
var groupItems = groupedItems[index];
|
|
381
|
+
var _itemsDimensions = groupItems.items,
|
|
382
|
+
group = groupItems.group;
|
|
383
|
+
var groupTop = sum(groupHeights); // Is group being stacked?
|
|
384
|
+
|
|
385
|
+
var isGroupStacked = group.stackItems !== undefined ? group.stackItems : stackItems;
|
|
386
|
+
|
|
387
|
+
var _stackGroup = stackGroup(_itemsDimensions, isGroupStacked, lineHeight, groupTop),
|
|
388
|
+
groupHeight = _stackGroup.groupHeight; // If group height is overridden, push new height
|
|
389
|
+
// Do this late as item position still needs to be calculated
|
|
390
|
+
|
|
391
|
+
|
|
392
|
+
groupTops.push(groupTop);
|
|
393
|
+
|
|
394
|
+
if (group.height) {
|
|
395
|
+
groupHeights.push(group.height);
|
|
396
|
+
} else {
|
|
397
|
+
groupHeights.push(Math.max(groupHeight, lineHeight));
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
return {
|
|
402
|
+
height: sum(groupHeights),
|
|
403
|
+
groupHeights: groupHeights,
|
|
404
|
+
groupTops: groupTops
|
|
405
|
+
};
|
|
406
|
+
}
|
|
407
|
+
/**
|
|
408
|
+
*
|
|
409
|
+
* @param {*} itemsDimensions
|
|
410
|
+
* @param {*} isGroupStacked
|
|
411
|
+
* @param {*} lineHeight
|
|
412
|
+
* @param {*} groupTop
|
|
413
|
+
*/
|
|
414
|
+
|
|
415
|
+
|
|
416
|
+
function stackGroup(itemsDimensions, isGroupStacked, lineHeight, groupTop) {
|
|
417
|
+
var groupHeight = 0;
|
|
418
|
+
var verticalMargin = 0; // Find positions for each item in group
|
|
419
|
+
|
|
420
|
+
for (var itemIndex = 0; itemIndex < itemsDimensions.length; itemIndex++) {
|
|
421
|
+
var r = {};
|
|
422
|
+
|
|
423
|
+
if (isGroupStacked) {
|
|
424
|
+
r = groupStack(lineHeight, itemsDimensions[itemIndex], itemsDimensions, groupHeight, groupTop, itemIndex);
|
|
425
|
+
} else {
|
|
426
|
+
r = groupNoStack(lineHeight, itemsDimensions[itemIndex], groupHeight, groupTop);
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
groupHeight = r.groupHeight;
|
|
430
|
+
verticalMargin = r.verticalMargin;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
return {
|
|
434
|
+
groupHeight: groupHeight,
|
|
435
|
+
verticalMargin: verticalMargin
|
|
436
|
+
};
|
|
437
|
+
}
|
|
438
|
+
/**
|
|
439
|
+
* Stack the items that will be visible
|
|
440
|
+
* within the canvas area
|
|
441
|
+
* @param {item[]} items
|
|
442
|
+
* @param {group[]} groups
|
|
443
|
+
* @param {number} canvasWidth
|
|
444
|
+
* @param {number} canvasTimeStart
|
|
445
|
+
* @param {number} canvasTimeEnd
|
|
446
|
+
* @param {*} keys
|
|
447
|
+
* @param {number} lineHeight
|
|
448
|
+
* @param {number} itemHeightRatio
|
|
449
|
+
* @param {boolean} stackItems
|
|
450
|
+
* @param {*} draggingItem
|
|
451
|
+
* @param {*} resizingItem
|
|
452
|
+
* @param {number} dragTime
|
|
453
|
+
* @param {left or right} resizingEdge
|
|
454
|
+
* @param {number} resizeTime
|
|
455
|
+
* @param {number} newGroupOrder
|
|
456
|
+
*/
|
|
457
|
+
|
|
458
|
+
|
|
459
|
+
function stackTimelineItems(items, groups, canvasWidth, canvasTimeStart, canvasTimeEnd, keys, lineHeight, itemHeightRatio, stackItems, draggingItem, resizingItem, dragTime, resizingEdge, resizeTime, newGroupOrder) {
|
|
460
|
+
var visibleItems = getVisibleItems(items, canvasTimeStart, canvasTimeEnd, keys);
|
|
461
|
+
var visibleItemsWithInteraction = visibleItems.map(function (item) {
|
|
462
|
+
return getItemWithInteractions({
|
|
463
|
+
item: item,
|
|
464
|
+
keys: keys,
|
|
465
|
+
draggingItem: draggingItem,
|
|
466
|
+
resizingItem: resizingItem,
|
|
467
|
+
dragTime: dragTime,
|
|
468
|
+
resizingEdge: resizingEdge,
|
|
469
|
+
resizeTime: resizeTime,
|
|
470
|
+
groups: groups,
|
|
471
|
+
newGroupOrder: newGroupOrder
|
|
472
|
+
});
|
|
473
|
+
}); // if there are no groups return an empty array of dimensions
|
|
474
|
+
|
|
475
|
+
if (groups.length === 0) {
|
|
476
|
+
return {
|
|
477
|
+
dimensionItems: [],
|
|
478
|
+
height: 0,
|
|
479
|
+
groupHeights: [],
|
|
480
|
+
groupTops: []
|
|
481
|
+
};
|
|
482
|
+
} // Get the order of groups based on their id key
|
|
483
|
+
|
|
484
|
+
|
|
485
|
+
var groupOrders = getGroupOrders(groups, keys);
|
|
486
|
+
var dimensionItems = visibleItemsWithInteraction.map(function (item) {
|
|
487
|
+
return getItemDimensions({
|
|
488
|
+
item: item,
|
|
489
|
+
keys: keys,
|
|
490
|
+
canvasTimeStart: canvasTimeStart,
|
|
491
|
+
canvasTimeEnd: canvasTimeEnd,
|
|
492
|
+
canvasWidth: canvasWidth,
|
|
493
|
+
groupOrders: groupOrders,
|
|
494
|
+
lineHeight: lineHeight,
|
|
495
|
+
itemHeightRatio: itemHeightRatio
|
|
496
|
+
});
|
|
497
|
+
}).filter(function (item) {
|
|
498
|
+
return !!item;
|
|
499
|
+
}); // Get a new array of groupOrders holding the stacked items
|
|
500
|
+
|
|
501
|
+
var _stackAll = stackAll(dimensionItems, groupOrders, lineHeight, stackItems),
|
|
502
|
+
height = _stackAll.height,
|
|
503
|
+
groupHeights = _stackAll.groupHeights,
|
|
504
|
+
groupTops = _stackAll.groupTops;
|
|
505
|
+
|
|
506
|
+
return {
|
|
507
|
+
dimensionItems: dimensionItems,
|
|
508
|
+
height: height,
|
|
509
|
+
groupHeights: groupHeights,
|
|
510
|
+
groupTops: groupTops
|
|
511
|
+
};
|
|
512
|
+
}
|
|
513
|
+
/**
|
|
514
|
+
* get canvas width from visible width
|
|
515
|
+
* @param {*} width
|
|
516
|
+
* @param {*} buffer
|
|
517
|
+
*/
|
|
518
|
+
|
|
519
|
+
|
|
520
|
+
function getCanvasWidth(width, buffer) {
|
|
521
|
+
return width * buffer;
|
|
522
|
+
}
|
|
523
|
+
/**
|
|
524
|
+
* get item's position, dimensions and collisions
|
|
525
|
+
* @param {*} item
|
|
526
|
+
* @param {*} keys
|
|
527
|
+
* @param {*} canvasTimeStart
|
|
528
|
+
* @param {*} canvasTimeEnd
|
|
529
|
+
* @param {*} canvasWidth
|
|
530
|
+
* @param {*} groupOrders
|
|
531
|
+
* @param {*} lineHeight
|
|
532
|
+
* @param {*} itemHeightRatio
|
|
533
|
+
*/
|
|
534
|
+
|
|
535
|
+
|
|
536
|
+
function getItemDimensions(_ref3) {
|
|
537
|
+
var item = _ref3.item,
|
|
538
|
+
keys = _ref3.keys,
|
|
539
|
+
canvasTimeStart = _ref3.canvasTimeStart,
|
|
540
|
+
canvasTimeEnd = _ref3.canvasTimeEnd,
|
|
541
|
+
canvasWidth = _ref3.canvasWidth,
|
|
542
|
+
groupOrders = _ref3.groupOrders,
|
|
543
|
+
lineHeight = _ref3.lineHeight,
|
|
544
|
+
itemHeightRatio = _ref3.itemHeightRatio;
|
|
545
|
+
var itemId = (0, _generic._get)(item, keys.itemIdKey);
|
|
546
|
+
var dimension = calculateDimensions({
|
|
547
|
+
itemTimeStart: (0, _generic._get)(item, keys.itemTimeStartKey),
|
|
548
|
+
itemTimeEnd: (0, _generic._get)(item, keys.itemTimeEndKey),
|
|
549
|
+
canvasTimeStart: canvasTimeStart,
|
|
550
|
+
canvasTimeEnd: canvasTimeEnd,
|
|
551
|
+
canvasWidth: canvasWidth
|
|
552
|
+
});
|
|
553
|
+
|
|
554
|
+
if (dimension) {
|
|
555
|
+
dimension.top = null;
|
|
556
|
+
dimension.order = groupOrders[(0, _generic._get)(item, keys.itemGroupKey)];
|
|
557
|
+
dimension.stack = !item.isOverlay;
|
|
558
|
+
dimension.height = lineHeight * itemHeightRatio;
|
|
559
|
+
return {
|
|
560
|
+
id: itemId,
|
|
561
|
+
dimensions: dimension
|
|
562
|
+
};
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
/**
|
|
566
|
+
* get new item with changed `itemTimeStart` , `itemTimeEnd` and `itemGroupKey` according to user interaction
|
|
567
|
+
* user interaction is dragging an item and resize left and right
|
|
568
|
+
* @param {*} item
|
|
569
|
+
* @param {*} keys
|
|
570
|
+
* @param {*} draggingItem
|
|
571
|
+
* @param {*} resizingItem
|
|
572
|
+
* @param {*} dragTime
|
|
573
|
+
* @param {*} resizingEdge
|
|
574
|
+
* @param {*} resizeTime
|
|
575
|
+
* @param {*} groups
|
|
576
|
+
* @param {*} newGroupOrder
|
|
577
|
+
*/
|
|
578
|
+
|
|
579
|
+
|
|
580
|
+
function getItemWithInteractions(_ref4) {
|
|
581
|
+
var _objectSpread2;
|
|
582
|
+
|
|
583
|
+
var item = _ref4.item,
|
|
584
|
+
keys = _ref4.keys,
|
|
585
|
+
draggingItem = _ref4.draggingItem,
|
|
586
|
+
resizingItem = _ref4.resizingItem,
|
|
587
|
+
dragTime = _ref4.dragTime,
|
|
588
|
+
resizingEdge = _ref4.resizingEdge,
|
|
589
|
+
resizeTime = _ref4.resizeTime,
|
|
590
|
+
groups = _ref4.groups,
|
|
591
|
+
newGroupOrder = _ref4.newGroupOrder;
|
|
592
|
+
if (!resizingItem && !draggingItem) return item;
|
|
593
|
+
var itemId = (0, _generic._get)(item, keys.itemIdKey);
|
|
594
|
+
var isDragging = itemId === draggingItem;
|
|
595
|
+
var isResizing = itemId === resizingItem;
|
|
596
|
+
|
|
597
|
+
var _calculateInteraction = calculateInteractionNewTimes({
|
|
598
|
+
itemTimeStart: (0, _generic._get)(item, keys.itemTimeStartKey),
|
|
599
|
+
itemTimeEnd: (0, _generic._get)(item, keys.itemTimeEndKey),
|
|
600
|
+
isDragging: isDragging,
|
|
601
|
+
isResizing: isResizing,
|
|
602
|
+
dragTime: dragTime,
|
|
603
|
+
resizingEdge: resizingEdge,
|
|
604
|
+
resizeTime: resizeTime
|
|
605
|
+
}),
|
|
606
|
+
_calculateInteraction2 = _slicedToArray(_calculateInteraction, 2),
|
|
607
|
+
itemTimeStart = _calculateInteraction2[0],
|
|
608
|
+
itemTimeEnd = _calculateInteraction2[1];
|
|
609
|
+
|
|
610
|
+
var newItem = _objectSpread({}, item, (_objectSpread2 = {}, _defineProperty(_objectSpread2, keys.itemTimeStartKey, itemTimeStart), _defineProperty(_objectSpread2, keys.itemTimeEndKey, itemTimeEnd), _defineProperty(_objectSpread2, keys.itemGroupKey, isDragging ? (0, _generic._get)(groups[newGroupOrder], keys.groupIdKey) : (0, _generic._get)(item, keys.itemGroupKey)), _objectSpread2));
|
|
611
|
+
|
|
612
|
+
return newItem;
|
|
613
|
+
}
|
|
614
|
+
/**
|
|
615
|
+
* get canvas start and end time from visible start and end time
|
|
616
|
+
* @param {number} visibleTimeStart
|
|
617
|
+
* @param {number} visibleTimeEnd
|
|
618
|
+
*/
|
|
619
|
+
|
|
620
|
+
|
|
621
|
+
function getCanvasBoundariesFromVisibleTime(visibleTimeStart, visibleTimeEnd, buffer) {
|
|
622
|
+
var zoom = visibleTimeEnd - visibleTimeStart; // buffer - 1 (1 is visible area) divided by 2 (2 is the buffer split on the right and left of the timeline)
|
|
623
|
+
|
|
624
|
+
var canvasTimeStart = visibleTimeStart - zoom * (buffer - 1) / 2;
|
|
625
|
+
var canvasTimeEnd = canvasTimeStart + zoom * buffer;
|
|
626
|
+
return [canvasTimeStart, canvasTimeEnd];
|
|
627
|
+
}
|
|
628
|
+
/**
|
|
629
|
+
* Get the the canvas area for a given visible time
|
|
630
|
+
* Will shift the start/end of the canvas if the visible time
|
|
631
|
+
* does not fit within the existing
|
|
632
|
+
* @param {number} visibleTimeStart
|
|
633
|
+
* @param {number} visibleTimeEnd
|
|
634
|
+
* @param {boolean} forceUpdateDimensions
|
|
635
|
+
* @param {*} items
|
|
636
|
+
* @param {*} groups
|
|
637
|
+
* @param {*} props
|
|
638
|
+
* @param {*} state
|
|
639
|
+
*/
|
|
640
|
+
|
|
641
|
+
|
|
642
|
+
function calculateScrollCanvas(visibleTimeStart, visibleTimeEnd, forceUpdateDimensions, items, groups, props, state) {
|
|
643
|
+
var buffer = props.buffer;
|
|
644
|
+
var oldCanvasTimeStart = state.canvasTimeStart;
|
|
645
|
+
var oldCanvasTimeEnd = state.canvasTimeEnd;
|
|
646
|
+
var oldZoom = state.visibleTimeEnd - state.visibleTimeStart;
|
|
647
|
+
var newZoom = visibleTimeEnd - visibleTimeStart;
|
|
648
|
+
var newState = {
|
|
649
|
+
visibleTimeStart: visibleTimeStart,
|
|
650
|
+
visibleTimeEnd: visibleTimeEnd // Check if the current canvas covers the new times
|
|
651
|
+
|
|
652
|
+
};
|
|
653
|
+
var canKeepCanvas = newZoom === oldZoom && visibleTimeStart >= oldCanvasTimeStart + oldZoom * 0.5 && visibleTimeStart <= oldCanvasTimeEnd - oldZoom * 1.5 && visibleTimeEnd >= oldCanvasTimeStart + oldZoom * 1.5 && visibleTimeEnd <= oldCanvasTimeEnd - oldZoom * 0.5;
|
|
654
|
+
|
|
655
|
+
if (!canKeepCanvas || forceUpdateDimensions) {
|
|
656
|
+
var _getCanvasBoundariesF = getCanvasBoundariesFromVisibleTime(visibleTimeStart, visibleTimeEnd, buffer),
|
|
657
|
+
_getCanvasBoundariesF2 = _slicedToArray(_getCanvasBoundariesF, 2),
|
|
658
|
+
canvasTimeStart = _getCanvasBoundariesF2[0],
|
|
659
|
+
canvasTimeEnd = _getCanvasBoundariesF2[1];
|
|
660
|
+
|
|
661
|
+
newState.canvasTimeStart = canvasTimeStart;
|
|
662
|
+
newState.canvasTimeEnd = canvasTimeEnd;
|
|
663
|
+
|
|
664
|
+
var mergedState = _objectSpread({}, state, {}, newState);
|
|
665
|
+
|
|
666
|
+
var canvasWidth = getCanvasWidth(mergedState.width, props.buffer); // The canvas cannot be kept, so calculate the new items position
|
|
667
|
+
|
|
668
|
+
Object.assign(newState, stackTimelineItems(items, groups, canvasWidth, mergedState.canvasTimeStart, mergedState.canvasTimeEnd, props.keys, props.lineHeight, props.itemHeightRatio, props.stackItems, mergedState.draggingItem, mergedState.resizingItem, mergedState.dragTime, mergedState.resizingEdge, mergedState.resizeTime, mergedState.newGroupOrder));
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
return newState;
|
|
672
|
+
}
|