|
|
@ -1138,14 +1138,8 @@ exports.mergeOptions = function (mergeTarget, options, option) { |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* This function does a binary search for a visible item. The user can select either the this.orderedItems.byStart or .byEnd |
|
|
|
* arrays. This is done by giving a boolean value true if you want to use the byEnd. |
|
|
|
* This is done to be able to select the correct if statement (we do not want to check if an item is visible, we want to check |
|
|
|
* if the time we selected (start or end) is within the current range). |
|
|
|
* |
|
|
|
* The trick is that every interval has to either enter the screen at the initial load or by dragging. The case of the RangeItem that is |
|
|
|
* before and after the current range is handled by simply checking if it was in view before and if it is again. For all the rest, |
|
|
|
* either the start OR end time has to be in the range. |
|
|
|
* This function does a binary search for a visible item in a sorted list. If we find a visible item, the code that uses |
|
|
|
* this function will then iterate in both directions over this sorted list to find all visible items. |
|
|
|
* |
|
|
|
* @param {Item[]} orderedItems Items ordered by start |
|
|
|
* @param {{start: number, end: number}} range |
|
|
@ -1183,14 +1177,9 @@ exports.binarySearch = function(orderedItems, range, field, field2) { |
|
|
|
}; |
|
|
|
|
|
|
|
/** |
|
|
|
* This function does a binary search for a visible item. The user can select either the this.orderedItems.byStart or .byEnd |
|
|
|
* arrays. This is done by giving a boolean value true if you want to use the byEnd. |
|
|
|
* This is done to be able to select the correct if statement (we do not want to check if an item is visible, we want to check |
|
|
|
* if the time we selected (start or end) is within the current range). |
|
|
|
* |
|
|
|
* The trick is that every interval has to either enter the screen at the initial load or by dragging. The case of the RangeItem that is |
|
|
|
* before and after the current range is handled by simply checking if it was in view before and if it is again. For all the rest, |
|
|
|
* either the start OR end time has to be in the range. |
|
|
|
* This function does a binary search for a specific value in a sorted array. If it does not exist but is in between of |
|
|
|
* two values, we return either the one before or the one after, depending on user input |
|
|
|
* If it is found, we return the index, else -1. |
|
|
|
* |
|
|
|
* @param {Array} orderedItems |
|
|
|
* @param {{start: number, end: number}} target |
|
|
@ -1202,73 +1191,58 @@ exports.binarySearch = function(orderedItems, range, field, field2) { |
|
|
|
exports.binarySearchGeneric = function(orderedItems, target, field, sidePreference) { |
|
|
|
var maxIterations = 10000; |
|
|
|
var iteration = 0; |
|
|
|
var array = orderedItems; |
|
|
|
var found = false; |
|
|
|
var low = 0; |
|
|
|
var high = array.length; |
|
|
|
var high = orderedItems.length - 1; |
|
|
|
var newLow = low; |
|
|
|
var newHigh = high; |
|
|
|
var guess = Math.floor(0.5*(high+low)); |
|
|
|
var newGuess; |
|
|
|
var prevValue, value, nextValue; |
|
|
|
|
|
|
|
if (high == 0) {guess = -1;} |
|
|
|
else if (high == 1) { |
|
|
|
value = array[guess][field]; |
|
|
|
if (value == target) { |
|
|
|
guess = 0; |
|
|
|
} |
|
|
|
else { |
|
|
|
guess = -1; |
|
|
|
} |
|
|
|
var prevValue, value, nextValue, middle; |
|
|
|
|
|
|
|
if (orderedItems.length == 0) { |
|
|
|
return -1; // did not find the target value
|
|
|
|
} |
|
|
|
else if (orderedItems.length == 1) { |
|
|
|
if (orderedItems[0][field] == target) {return 0;} // if the value matched the value we look for, return index 0
|
|
|
|
else {return -1;} |
|
|
|
} |
|
|
|
else { |
|
|
|
high -= 1; |
|
|
|
while (found == false && iteration < maxIterations) { |
|
|
|
prevValue = array[Math.max(0,guess - 1)][field]; |
|
|
|
value = array[guess][field]; |
|
|
|
nextValue = array[Math.min(array.length-1,guess + 1)][field]; |
|
|
|
|
|
|
|
if (value == target || prevValue < target && value > target || value < target && nextValue > target) { |
|
|
|
found = true; |
|
|
|
if (value != target) { |
|
|
|
if (sidePreference == 'before') { |
|
|
|
if (prevValue < target && value > target) { |
|
|
|
guess = Math.max(0,guess - 1); |
|
|
|
} |
|
|
|
} |
|
|
|
else { |
|
|
|
if (value < target && nextValue > target) { |
|
|
|
guess = Math.min(array.length-1,guess + 1); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
while (iteration < maxIterations) { |
|
|
|
// get a new guess
|
|
|
|
middle = Math.floor(0.5*(high+low)); |
|
|
|
prevValue = orderedItems[Math.max(0,middle - 1)][field]; |
|
|
|
value = orderedItems[middle][field]; |
|
|
|
nextValue = orderedItems[Math.min(orderedItems.length-1,middle + 1)][field]; |
|
|
|
|
|
|
|
if (value == target) { // we found the target
|
|
|
|
return middle; |
|
|
|
} |
|
|
|
else { |
|
|
|
else if (prevValue < target && value > target) { // target is in between of the previous and the current
|
|
|
|
return sidePreference == 'before' ? Math.max(0,middle - 1) : middle; |
|
|
|
} |
|
|
|
else if (value < target && nextValue > target) { // target is in between of the current and the next
|
|
|
|
return sidePreference == 'before' ? middle : Math.min(orderedItems.length-1,middle + 1); |
|
|
|
} |
|
|
|
else { // didnt find the target, we need to change our boundaries.
|
|
|
|
if (value < target) { // it is too small --> increase low
|
|
|
|
newLow = Math.floor(0.5*(high+low)); |
|
|
|
newLow = middle; |
|
|
|
} |
|
|
|
else { // it is too big --> decrease high
|
|
|
|
newHigh = Math.floor(0.5*(high+low)); |
|
|
|
newHigh = middle; |
|
|
|
} |
|
|
|
newGuess = Math.floor(0.5*(high+low)); |
|
|
|
// not in list;
|
|
|
|
if (low == newLow && high == newHigh) { |
|
|
|
guess = -1; |
|
|
|
found = true; |
|
|
|
|
|
|
|
if (low == newLow && high == newHigh) { // if we did not find it and our new boundaries are the same as the old, the target is not in the list
|
|
|
|
return -1; |
|
|
|
} |
|
|
|
else { |
|
|
|
high = newHigh; low = newLow; |
|
|
|
guess = Math.floor(0.5*(high+low)); |
|
|
|
else { // we have new boundaries, lets use them!
|
|
|
|
high = newHigh; |
|
|
|
low = newLow; |
|
|
|
} |
|
|
|
} |
|
|
|
iteration++; |
|
|
|
} |
|
|
|
if (iteration >= maxIterations) { |
|
|
|
console.log("BinarySearch too many iterations. Aborting."); |
|
|
|
} |
|
|
|
} |
|
|
|
return guess; |
|
|
|
// didnt find anything. Return the last guess.
|
|
|
|
console.log("BinarySearchGeneric did too many iterations. Aborting."); |
|
|
|
return middle; |
|
|
|
}; |
|
|
|
|
|
|
|
/** |
|
|
|