61 lines
1.6 KiB
JavaScript
61 lines
1.6 KiB
JavaScript
import Chart from "chart.js";
|
|
import "chartjs-chart-timeline";
|
|
|
|
// This function add a new interaction mode to Chart.js that
|
|
// returns one point for every dataset.
|
|
Chart.Interaction.modes.neareach = function (chart, e, options) {
|
|
const getRange = {
|
|
x: (a, b) => Math.abs(a.x - b.x),
|
|
y: (a, b) => Math.abs(a.y - b.y),
|
|
// eslint-disable-next-line no-restricted-properties
|
|
xy: (a, b) => Math.pow(a.x - b.x, 2) + Math.pow(a.y - b.y, 2),
|
|
};
|
|
const getRangeMax = {
|
|
x: (r) => r,
|
|
y: (r) => r,
|
|
xy: (r) => r * r,
|
|
};
|
|
let position;
|
|
if (e.native) {
|
|
position = {
|
|
x: e.x,
|
|
y: e.y,
|
|
};
|
|
} else {
|
|
position = Chart.helpers.getRelativePosition(e, chart);
|
|
}
|
|
const elements = [];
|
|
const elementsRange = [];
|
|
const datasets = chart.data.datasets;
|
|
let meta;
|
|
options.axis = options.axis || "xy";
|
|
const rangeFunc = getRange[options.axis];
|
|
const rangeMaxFunc = getRangeMax[options.axis];
|
|
|
|
for (let i = 0, ilen = datasets.length; i < ilen; ++i) {
|
|
if (!chart.isDatasetVisible(i)) {
|
|
continue;
|
|
}
|
|
|
|
meta = chart.getDatasetMeta(i);
|
|
for (let j = 0, jlen = meta.data.length; j < jlen; ++j) {
|
|
const element = meta.data[j];
|
|
if (!element._view.skip) {
|
|
const vm = element._view;
|
|
const range = rangeFunc(vm, position);
|
|
const oldRange = elementsRange[i];
|
|
if (range < rangeMaxFunc(vm.radius + vm.hitRadius)) {
|
|
if (oldRange === undefined || oldRange > range) {
|
|
elementsRange[i] = range;
|
|
elements[i] = element;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
const ret = elements.filter((n) => n !== undefined);
|
|
return ret;
|
|
};
|
|
|
|
export default Chart;
|