vis-utils
Version:
Utility functions for data visualization
62 lines (52 loc) • 1.96 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = findClosestSorted;
var _binarySearch = require('binary-search');
var _binarySearch2 = _interopRequireDefault(_binarySearch);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Helper function to compute distance and find the closest item
* Since it assumes the data is sorted, it does a binary search O(log n)
*
* @param {Array} array the input array to search
* @param {Number} value the value to match against (typically pixels)
* @param {Function} accessor applied to each item in the array to get equivalent
* value to compare against
* @return {Any} The item in the array that is closest to `value`
*/
function findClosestSorted(array, value) {
var accessor = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : function (d) {
return d;
};
// binary search uses the value directly in comparisons, so make sure not to
// run the accessor on it
var index = (0, _binarySearch2.default)(array, value, function (a, b) {
var aValue = a === value ? value : accessor(a);
var bValue = b === value ? value : accessor(b);
return aValue - bValue;
});
// index is positive = we found it exactly
if (index < 0) {
// should match first element
if (index === -1) {
index = 0;
} else {
// map back to the input location since the binary search uses -(low + 1) as the result
index = -index - 1;
// should match last element
if (index >= array.length) {
index = array.length - 1;
}
}
}
// this result is always to the right, so see if the one to the left is closer
// and use it if it is.
var result = array[index];
var before = array[index - 1];
if (before != null && Math.abs(accessor(result) - value) > Math.abs(accessor(before) - value)) {
result = before;
}
return result;
}