@@ -17,6 +17,7 @@ var calcMarkerSize = require('../scatter/calc').calcMarkerSize;
1717var calcAxisExpansion = require ( '../scatter/calc' ) . calcAxisExpansion ;
1818var calcColorscales = require ( '../scatter/colorscale_calc' ) ;
1919var convertMarkerStyle = require ( '../scattergl/convert' ) . convertMarkerStyle ;
20+ var getTraceColor = require ( '../scatter/get_trace_color' ) ;
2021
2122var BADNUM = require ( '../../constants/numerical' ) . BADNUM ;
2223var TOO_MANY_POINTS = require ( '../scattergl/constants' ) . TOO_MANY_POINTS ;
@@ -199,7 +200,6 @@ function plotOne(gd, cd0) {
199200
200201function hoverPoints ( pointData , xval , yval , hovermode ) {
201202 var cd = pointData . cd ;
202- var stash = cd [ 0 ] . t ;
203203 var trace = cd [ 0 ] . trace ;
204204 var xa = pointData . xa ;
205205 var ya = pointData . ya ;
@@ -208,17 +208,131 @@ function hoverPoints(pointData, xval, yval, hovermode) {
208208 var maxDistance = pointData . distance ;
209209 var dimensions = trace . dimensions ;
210210
211- var xi , yi ;
212- for ( var i = 0 ; i < dimensions . length ; i ++ ) {
211+ var xi , yi , i ;
212+ for ( i = 0 ; i < dimensions . length ; i ++ ) {
213213 if ( trace . xaxes [ i ] === xa . _id ) xi = i ;
214214 if ( trace . yaxes [ i ] === ya . _id ) yi = i ;
215215 }
216216
217- var x = dimensions [ xi ] . values ;
218- var y = dimensions [ yi ] . values ;
217+ var xData = dimensions [ xi ] . values ;
218+ var yData = dimensions [ yi ] . values ;
219+
220+ var id , ptx , pty , dx , dy , dist , dxy ;
221+
222+ if ( hovermode === 'x' ) {
223+ for ( i = 0 ; i < xData . length ; i ++ ) {
224+ ptx = xData [ i ] ;
225+ dx = Math . abs ( xa . c2p ( ptx ) - xpx ) ;
226+ if ( dx < maxDistance ) {
227+ maxDistance = dx ;
228+ dy = ya . c2p ( yData [ i ] ) - ypx ;
229+ dxy = Math . sqrt ( dx * dx + dy * dy ) ;
230+ id = i ;
231+ }
232+ }
233+ }
234+ else {
235+ for ( i = 0 ; i < xData . length ; i ++ ) {
236+ ptx = xData [ i ] ;
237+ pty = yData [ i ] ;
238+ dx = xa . c2p ( ptx ) - xpx ;
239+ dy = ya . c2p ( pty ) - ypx ;
240+
241+ dist = Math . sqrt ( dx * dx + dy * dy ) ;
242+ if ( dist < maxDistance ) {
243+ maxDistance = dxy = dist ;
244+ id = i ;
245+ }
246+ }
247+ }
248+
249+ pointData . index = id ;
250+
251+
252+ if ( id === undefined ) return [ pointData ] ;
253+
254+ // the closest data point
255+ var di = {
256+ pointNumber : id ,
257+ x : xData [ id ] ,
258+ y : yData [ id ]
259+ } ;
260+
261+
262+ // that is single-item arrays_to_calcdata excerpt, since we are doing it for a single point and we don't have to do it beforehead for 1e6 points
263+ // FIXME: combine with scattergl hover di calc
264+ di . tx = Array . isArray ( trace . text ) ? trace . text [ id ] : trace . text ;
265+ di . htx = Array . isArray ( trace . hovertext ) ? trace . hovertext [ id ] : trace . hovertext ;
266+ di . data = Array . isArray ( trace . customdata ) ? trace . customdata [ id ] : trace . customdata ;
267+ di . tp = Array . isArray ( trace . textposition ) ? trace . textposition [ id ] : trace . textposition ;
268+
269+ var font = trace . textfont ;
270+ if ( font ) {
271+ di . ts = Array . isArray ( font . size ) ? font . size [ id ] : font . size ;
272+ di . tc = Array . isArray ( font . color ) ? font . color [ id ] : font . color ;
273+ di . tf = Array . isArray ( font . family ) ? font . family [ id ] : font . family ;
274+ }
275+
276+ var marker = trace . marker ;
277+ if ( marker ) {
278+ di . ms = Lib . isArrayOrTypedArray ( marker . size ) ? marker . size [ id ] : marker . size ;
279+ di . mo = Lib . isArrayOrTypedArray ( marker . opacity ) ? marker . opacity [ id ] : marker . opacity ;
280+ di . mx = Array . isArray ( marker . symbol ) ? marker . symbol [ id ] : marker . symbol ;
281+ di . mc = Lib . isArrayOrTypedArray ( marker . color ) ? marker . color [ id ] : marker . color ;
282+ }
283+
284+ var line = marker && marker . line ;
285+ if ( line ) {
286+ di . mlc = Array . isArray ( line . color ) ? line . color [ id ] : line . color ;
287+ di . mlw = Lib . isArrayOrTypedArray ( line . width ) ? line . width [ id ] : line . width ;
288+ }
289+
290+ var grad = marker && marker . gradient ;
291+ if ( grad && grad . type !== 'none' ) {
292+ di . mgt = Array . isArray ( grad . type ) ? grad . type [ id ] : grad . type ;
293+ di . mgc = Array . isArray ( grad . color ) ? grad . color [ id ] : grad . color ;
294+ }
295+
296+ var xp = xa . c2p ( di . x , true ) ;
297+ var yp = ya . c2p ( di . y , true ) ;
298+ var rad = di . mrc || 1 ;
299+
300+ var hoverlabel = trace . hoverlabel ;
301+
302+ if ( hoverlabel ) {
303+ di . hbg = Array . isArray ( hoverlabel . bgcolor ) ? hoverlabel . bgcolor [ id ] : hoverlabel . bgcolor ;
304+ di . hbc = Array . isArray ( hoverlabel . bordercolor ) ? hoverlabel . bordercolor [ id ] : hoverlabel . bordercolor ;
305+ di . hts = Array . isArray ( hoverlabel . font . size ) ? hoverlabel . font . size [ id ] : hoverlabel . font . size ;
306+ di . htc = Array . isArray ( hoverlabel . font . color ) ? hoverlabel . font . color [ id ] : hoverlabel . font . color ;
307+ di . htf = Array . isArray ( hoverlabel . font . family ) ? hoverlabel . font . family [ id ] : hoverlabel . font . family ;
308+ di . hnl = Array . isArray ( hoverlabel . namelength ) ? hoverlabel . namelength [ id ] : hoverlabel . namelength ;
309+ }
310+ var hoverinfo = trace . hoverinfo ;
311+ if ( hoverinfo ) {
312+ di . hi = Array . isArray ( hoverinfo ) ? hoverinfo [ id ] : hoverinfo ;
313+ }
314+
315+
316+ var fakeCd = { } ;
317+ fakeCd [ pointData . index ] = di ;
318+
319+ Lib . extendFlat ( pointData , {
320+ color : getTraceColor ( trace , di ) ,
321+
322+ x0 : xp - rad ,
323+ x1 : xp + rad ,
324+ xLabelVal : di . x ,
325+
326+ y0 : yp - rad ,
327+ y1 : yp + rad ,
328+ yLabelVal : di . y ,
219329
330+ cd : fakeCd ,
331+ distance : maxDistance ,
332+ spikeDistance : dxy
333+ } ) ;
220334
221- console . log ( x , y ) ;
335+ return [ pointData ] ;
222336}
223337
224338function selectPoints ( searchInfo , polygon ) {
0 commit comments