Skip to content

Commit

Permalink
Conditionally use binarySearch for intersect mode
Browse files Browse the repository at this point in the history
  • Loading branch information
kurkle committed Jan 16, 2020
1 parent 55faccf commit 8303f4b
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 26 deletions.
4 changes: 4 additions & 0 deletions src/core/core.datasetController.js
Original file line number Diff line number Diff line change
Expand Up @@ -980,6 +980,10 @@ helpers.extend(DatasetController.prototype, {
* @private
*/
_getSharedOptions: function(mode, el, options) {
if (!mode) {
// store element option sharing status for usage in interactions
this._elementsShareOptions = options && options.$shared;
}
if (mode !== 'reset' && options && options.$shared && el && el.options && el.options.$shared) {
return {target: el.options, options};
}
Expand Down
49 changes: 23 additions & 26 deletions src/core/core.interaction.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,36 +41,38 @@ function evaluateAllVisibleItems(chart, handler) {
}
}

function useBinarySearch(axis, controller, _sorted, intersect) {
const iScale = controller._cachedMeta.iScale;
return iScale && axis === iScale.axis && _sorted &&
(!intersect || controller._elementsShareOptions);
}

/**
* Helper function to get items using binary search, when the data is sorted.
* @param {Chart} chart - the chart
* @param {string} axis - the axis mode. x|y|xy
* @param {object} position - the point to be nearest to
* @param {function} handler - the callback to execute for each visible item
* @return whether all scales were of a suitable type
* @param {boolean} intersect - consider intersecting items
*/
function binarySearchItems(chart, axis, position, handler) {
function optimizedEvaluateItems(chart, axis, position, handler, intersect) {
const metasets = chart._getSortedVisibleDatasetMetas();
for (let i = 0, ilen = metasets.length; i < ilen; ++i) {
const metaset = metasets[i];
const iScale = metaset.controller._cachedMeta.iScale;
if (!iScale || axis !== iScale.axis || !metaset._sorted) {
return false;
}
}

// do this only after checking whether all scales are of a suitable type
for (let i = 0, ilen = metasets.length; i < ilen; ++i) {
const {index, data} = metasets[i];
const {lo, hi, loIndex, hiIndex} = _lookup(data, axis, position[axis]);
if (lo) {
handler(lo, index, loIndex);
const {controller, data, index, _sorted} = metasets[i];
let startIndex = 0;
let endIndex = data.length - 1;
if (useBinarySearch(axis, controller, _sorted, intersect)) {
const {loIndex, hiIndex} = _lookup(data, axis, position[axis]);
startIndex = loIndex === null ? hiIndex : loIndex;
endIndex = hiIndex === null ? loIndex : hiIndex;
}
if (hi) {
handler(hi, index, hiIndex);
for (let j = startIndex; j <= endIndex; ++j) {
const element = data[j];
if (!element.skip) {
handler(element, index, j);
}
}
}
return true;
}

/**
Expand All @@ -96,7 +98,7 @@ function getDistanceMetricForAxis(axis) {
* @param {string} axis - the axis mode. x|y|xy
* @return {ChartElement[]} the nearest items
*/
function getIntersectItems(chart, position) {
function getIntersectItems(chart, position, axis) {
const items = [];

if (!_isPointInArea(position, chart.chartArea)) {
Expand All @@ -109,7 +111,7 @@ function getIntersectItems(chart, position) {
}
};

evaluateAllVisibleItems(chart, evaluationFunc);
optimizedEvaluateItems(chart, axis, position, evaluationFunc, true);
return items;
}

Expand Down Expand Up @@ -146,12 +148,7 @@ function getNearestItems(chart, position, axis, intersect) {
}
};

const optimized = binarySearchItems(chart, axis, position, evaluationFunc);
if (optimized) {
return items;
}

evaluateAllVisibleItems(chart, evaluationFunc);
optimizedEvaluateItems(chart, axis, position, evaluationFunc);
return items;
}

Expand Down

0 comments on commit 8303f4b

Please sign in to comment.