Таким образом, в основном мы хотим условно отобразить всплывающую подсказку, когда положение курсора соответствует требованию, что оно находится над линией на графике.Поскольку линии не являются сущностью, с которой мы можем работать, вам нужно вычислить линию между двумя ближайшими точками по обе стороны от курсора, а затем посмотреть, лежит ли на ней ваша текущая позиция.Я немного упростил ваш пример:
Функция для вычисления расстояния между двумя точками:
function lineDistance( p1x, p1y,p2x, p2y ) {
return Math.sqrt( (p2x - p1x)*(p2x - p1x) + (p2y-p1y)*(p2y-p1y) );
}
Предполагая, что ваши ближайшие две точки - это точки A и B до курсора C, а затем расстояние AB
должно равняться AC + BC
.
Итак, чтобы определить, находится ли он в строке: Math.abs(AB-(AC+BC)) < SomeThreshold
.Использование порога, по сути, рисует рамку вокруг линии, в которую может попасть курсор.
Затем расширение вашего кода в plothover
( jsFiddle )
$(placeholder).bind("plothover", function (event, pos, item) {
if (item) {
var tipText;
if (opts.xaxis.mode === "time" || opts.xaxes[0].mode === "time") {
tipText = stringFormat(to.content, item, timestampToDate);
} else {
tipText = stringFormat(to.content, item);
}
$tip.html(tipText).css({
left: tipPosition.x + to.shifts.x,
top: tipPosition.y + to.shifts.y
}).show();
} else {
// Extended for line hover
var series = plot.getData();
var xBeforeIndex = 0;
var xAfterIndex = -1;
var Threshold = 0.0000025;
var i = 1;
while (i <= series[0].data.length && xAfterIndex==-1) {
if (xAfterIndex == -1 && pos.x > series[0].data[i][0]) {
xBeforeIndex = i;
} else if (xAfterIndex == -1) {
xAfterIndex = i;
}
i++;
}
var onTheLine =
lineDistance(
series[0].data[xBeforeIndex][0]/10000,series[0].data[xBeforeIndex][1],
pos.x/10000, pos.y)
+lineDistance(pos.x/10000, pos.y,
series[0].data[xAfterIndex][0]/10000,series[0].data[xAfterIndex][1])
-lineDistance(
series[0].data[xBeforeIndex][0]/10000,series[0].data[xBeforeIndex][1],
series[0].data[xAfterIndex][0]/10000,series[0].data[xAfterIndex][1]);
if (Math.abs(onTheLine) < Threshold) {
tipText = "Found Line";
$tip.html(tipText).css({
left: tipPosition.x + to.shifts.x,
top: tipPosition.y + to.shifts.y
}).show();
} else {
$tip.hide().html('');
}
}
});
Здесь ничего не сделано:
- Проверьте ваши граничные случаи более правильно - вышеизложенное предполагает, что первая и последняя точки находятся на краях графика.
- Добавьте обратно во второй график
- Улучшение производительности поиска по наборам данных с использованием подхода, подобного пузырьковой сортировке, для поиска индексов до / после.
- Обратите внимание, что я уменьшаю ось X на 10000. Числа были слишком большими ив большом промежутке между первыми двумя точками различия по оси Y были незначительными (результат всегда был нулевым между этими двумя точками).
Обратите внимание, добавление второго графика потребует от вас найти ближайшийуказывает на оба графика и проверяет, попадает ли он на одну из линий.Если ваши линии близки или пересекаются, вы можете сделать одну из них приоритетной.Если вы затрудняетесь добавить вторую строку, я могу помочь позже.