From 8dfb13ffa4b7ac1736b903ae624a126c6427437c Mon Sep 17 00:00:00 2001 From: Sebastian Busch Date: Wed, 24 Apr 2019 09:21:00 +0200 Subject: [PATCH] Large items spanning the whole visible range (extended by 25% to the left and right as a "buffer zone") are initially hidden until their start or end scrolls into that range. This commit fixes this by increasing the buffer zone depending on the items, so that its large enough to fit all *potentially visible* items. The current implementation has two performance-related drawbacks: 1. As the whole "scanning range" is enlarged, more items need to be processed and more items will be visible. I see no problems for light datasets, but for large datasets with many items - especially item types without end date - this could become a problem. Possible solutions: a) two scanning passes: first one for items with start and end using the extended buffer zone (as implemented in this patch), a second one for items without end using the fixed buffer zone (as before) b) same as a) but items with start and end could be grouped in *some* groups depending on their duration c) add an option to choose: have this fix with the performance drawback, or tolerate the bug but with higher performance for large, mixed datasets 2. Maximum duration is calculated per group at rendering level, which happens more often than needed. Possible solution: calculate on item changes and cache it. Should be easy to fix for someone who knows the location where this could be implemented without missing any changes. As a side note, I think the initial buffer zone size should be configurable, currently at 1/2 of visible range (1/4 to the left, 1/4 to the right). --- lib/timeline/component/Group.js | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/lib/timeline/component/Group.js b/lib/timeline/component/Group.js index b9107a9..84a555f 100644 --- a/lib/timeline/component/Group.js +++ b/lib/timeline/component/Group.js @@ -827,7 +827,20 @@ class Group { return visibleItems; } - const interval = (range.end - range.start) / 4; + const rangeDuration = range.end - range.start; + let interval = rangeDuration / 4; + + for (let i = 0; i < orderedItems.byEnd.length; i++) { + const item = orderedItems.byEnd[i]; + + const duration = item.data.end - item.data.start; + const maxProtruding = duration - rangeDuration; + + if (maxProtruding > interval) { + interval = maxProtruding; + } + } + const lowerBound = range.start - interval; const upperBound = range.end + interval;