function binarySearch(metaset, axis, value, intersect) {
  const {controller, data, _sorted} = metaset;
  const iScale = controller._cachedMeta.iScale;
  const spanGaps = metaset.dataset ? metaset.dataset.options ? metaset.dataset.options.spanGaps : null : null;

  if (iScale && axis === iScale.axis && axis !== 'r' && _sorted && data.length) {
    const lookupMethod = iScale._reversePixels ? _rlookupByKey : _lookupByKey;
    if (!intersect) {
      const result = lookupMethod(data, axis, value);
      if (spanGaps) {
        const {vScale} = controller._cachedMeta;
        const {_parsed} = metaset;

        const distanceToDefinedLo = (_parsed
          .slice(0, result.lo + 1)
          .reverse()
          .findIndex(
            point => !isNullOrUndef(point[vScale.axis])));
        result.lo -= Math.max(0, distanceToDefinedLo);

        const distanceToDefinedHi = (_parsed
          .slice(result.hi)
          .findIndex(
            point => !isNullOrUndef(point[vScale.axis])));
        result.hi += Math.max(0, distanceToDefinedHi);
      }
      return result;
    } else if (controller._sharedOptions) {
      // _sharedOptions indicates that each element has equal options -> equal proportions
      // So we can do a ranged binary search based on the range of first element and
      // be confident to get the full range of indices that can intersect with the value.
      const el = data[0];
      const range = typeof el.getRange === 'function' && el.getRange(axis);
      if (range) {
        const start = lookupMethod(data, axis, value - range);
        const end = lookupMethod(data, axis, value + range);
        return {lo: start.lo, hi: end.hi};
      }
    }
  }
  // Default to all elements, when binary search can not be used.
  return {lo: 0, hi: data.length - 1};
}
Helper function to do binary search when possible
@param {object} metaset - the dataset meta
@param {string} axis - the axis mode. x|y|xy|r
@param {number} value - the value to find
@param {boolean} [intersect] - should the element intersect
@returns {{lo:number, hi:number}} indices to search data array between