Quindi, in pratica, stiamo cercando di visualizzare in modo condizionale un suggerimento quando la posizione del cursore soddisfa il requisito che si trovi sopra una linea sul grafico. Poiché le linee non sono un'entità con cui possiamo lavorare, è necessario calcolare la linea tra i due punti più vicini su entrambi i lati del cursore e verificare se la posizione corrente si trova su di essa. Ho semplificato il vostro esempio un po ':
Funzione per calcolare la distanza tra due punti:
function lineDistance(p1x, p1y,p2x, p2y) {
return Math.sqrt((p2x - p1x)*(p2x - p1x) + (p2y-p1y)*(p2y-p1y));
}
Supponendo che il più vicino due punti sono A e B per il cursore C allora la distanza deve essere uguale AB
AC + BC
.
Quindi per determinare se è sulla linea: Math.abs(AB-(AC+BC)) < SomeThreshold
. Usando la soglia si disegna essenzialmente un riquadro attorno alla linea nella quale il cursore può cadere.
Poi estendere il codice nelle 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('');
}
}
});
Le cose non fatto qui:
- Controllare i casi limite in modo più appropriato - quanto sopra assume il primo e l'ultimo punto sono sul bordi del grafico.
- Aggiungi indietro nel secondo grafico
- Migliora le prestazioni di ricerca dei set di dati utilizzando un approccio come bubblesort per trovare gli indici prima/dopo.
- Si noti che sto ridimensionando l'asse x di 10000. I numeri erano troppo grandi e nel grande divario tra i primi due punti le differenze dell'asse y erano insignificanti (il risultato era sempre zero tra questi due punti).
Nota, l'aggiunta del secondo grafico richiede di trovare i punti più vicini per entrambi i grafici e di verificare se cade su entrambe le linee. Se le tue linee sono vicine o intersecanti, puoi semplicemente creare una linea di priorità. Se tenti di aggiungere nuovamente la seconda linea, posso aiutarti in seguito.
in che modo l'utente passa con il mouse su un suggerimento? il tooltip non sparirà quando ti focalizzi fuori dal controllo? Se mostri un esempio, ti posso aiutare –
Il tooltip per un punto dati viene reso utilizzando l'evento "plothover" nativo di flot che si attiva quando un utente passa su un punto dati. Non sembra esserci alcun evento del genere per la linea stessa però. Un esempio sarebbe post difficile in quanto è strettamente integrato nell'app che sto sviluppando. Vedrò cosa posso fare comunque. – gordyr
anche un jsfiddle lo farà, ma capisco che potrebbe essere difficile –