@@ -40,7 +40,7 @@ import { edgeLabelsToDisplayFromNodes, LabelGrid } from "./core/labels";
40
40
import { Settings , DEFAULT_SETTINGS , validateSettings } from "./settings" ;
41
41
import { INodeProgram } from "./rendering/webgl/programs/common/node" ;
42
42
import { IEdgeProgram } from "./rendering/webgl/programs/common/edge" ;
43
- import TouchCaptor from "./core/captors/touch" ;
43
+ import TouchCaptor , { FakeSigmaMouseEvent } from "./core/captors/touch" ;
44
44
import { identity , multiplyVec2 } from "./utils/matrices" ;
45
45
import { doEdgeCollideWithPoint , isPixelColored } from "./utils/edge-collisions" ;
46
46
@@ -368,6 +368,62 @@ export default class Sigma extends TypedEventEmitter<SigmaEvents> {
368
368
return this ;
369
369
}
370
370
371
+ /**
372
+ * Method that checks whether or not a node collides with a given position.
373
+ */
374
+ private mouseIsOnNode ( { x, y } : Coordinates , { x : nodeX , y : nodeY } : Coordinates , size : number ) : boolean {
375
+ return (
376
+ x > nodeX - size &&
377
+ x < nodeX + size &&
378
+ y > nodeY - size &&
379
+ y < nodeY + size &&
380
+ Math . sqrt ( Math . pow ( x - nodeX , 2 ) + Math . pow ( y - nodeY , 2 ) ) < size
381
+ ) ;
382
+ }
383
+
384
+ /**
385
+ * Method that returns all nodes in quad at a given position.
386
+ */
387
+ private getQuadNodes ( position : Coordinates ) : string [ ] {
388
+ const mouseGraphPosition = this . viewportToFramedGraph ( position ) ;
389
+
390
+ return this . quadtree . point ( mouseGraphPosition . x , 1 - mouseGraphPosition . y ) ;
391
+ }
392
+
393
+ /**
394
+ * Method that returns the closest node to a given position.
395
+ */
396
+ private getNodeAtPosition ( position : Coordinates ) : string | null {
397
+ const { x, y } = position ;
398
+ const quadNodes = this . getQuadNodes ( position ) ;
399
+
400
+ // We will hover the node whose center is closest to mouse
401
+ let minDistance = Infinity ,
402
+ nodeAtPosition = null ;
403
+
404
+ for ( let i = 0 , l = quadNodes . length ; i < l ; i ++ ) {
405
+ const node = quadNodes [ i ] ;
406
+
407
+ const data = this . nodeDataCache [ node ] ;
408
+
409
+ const nodePosition = this . framedGraphToViewport ( data ) ;
410
+
411
+ const size = this . scaleSize ( data . size ) ;
412
+
413
+ if ( ! data . hidden && this . mouseIsOnNode ( position , nodePosition , size ) ) {
414
+ const distance = Math . sqrt ( Math . pow ( x - nodePosition . x , 2 ) + Math . pow ( y - nodePosition . y , 2 ) ) ;
415
+
416
+ // TODO: sort by min size also for cases where center is the same
417
+ if ( distance < minDistance ) {
418
+ minDistance = distance ;
419
+ nodeAtPosition = node ;
420
+ }
421
+ }
422
+ }
423
+
424
+ return nodeAtPosition ;
425
+ }
426
+
371
427
/**
372
428
* Method binding event handlers.
373
429
*
@@ -382,62 +438,16 @@ export default class Sigma extends TypedEventEmitter<SigmaEvents> {
382
438
383
439
window . addEventListener ( "resize" , this . activeListeners . handleResize ) ;
384
440
385
- // Function checking if the mouse is on the given node
386
- const mouseIsOnNode = ( mouseX : number , mouseY : number , nodeX : number , nodeY : number , size : number ) : boolean => {
387
- return (
388
- mouseX > nodeX - size &&
389
- mouseX < nodeX + size &&
390
- mouseY > nodeY - size &&
391
- mouseY < nodeY + size &&
392
- Math . sqrt ( Math . pow ( mouseX - nodeX , 2 ) + Math . pow ( mouseY - nodeY , 2 ) ) < size
393
- ) ;
394
- } ;
395
-
396
- // Function returning the nodes in the mouse's quad
397
- const getQuadNodes = ( mouseX : number , mouseY : number ) => {
398
- const mouseGraphPosition = this . viewportToFramedGraph ( { x : mouseX , y : mouseY } ) ;
399
-
400
- // TODO: minus 1? lol
401
- return this . quadtree . point ( mouseGraphPosition . x , 1 - mouseGraphPosition . y ) ;
402
- } ;
403
-
404
441
// Handling mouse move
405
442
this . activeListeners . handleMove = ( e : MouseCoords ) : void => {
406
- // NOTE: for the canvas renderer, testing the pixel's alpha should
407
- // give some boost but this slows things down for WebGL empirically.
408
-
409
- const quadNodes = getQuadNodes ( e . x , e . y ) ;
410
-
411
443
const baseEvent = {
412
444
event : e ,
413
445
preventSigmaDefault ( ) : void {
414
446
this . event . preventSigmaDefault ( ) ;
415
447
} ,
416
448
} ;
417
449
418
- // We will hover the node whose center is closest to mouse
419
- let minDistance = Infinity ,
420
- nodeToHover = null ;
421
-
422
- for ( let i = 0 , l = quadNodes . length ; i < l ; i ++ ) {
423
- const node = quadNodes [ i ] ;
424
-
425
- const data = this . nodeDataCache [ node ] ;
426
-
427
- const pos = this . framedGraphToViewport ( data ) ;
428
-
429
- const size = this . scaleSize ( data . size ) ;
430
-
431
- if ( ! data . hidden && mouseIsOnNode ( e . x , e . y , pos . x , pos . y , size ) ) {
432
- const distance = Math . sqrt ( Math . pow ( e . x - pos . x , 2 ) + Math . pow ( e . y - pos . y , 2 ) ) ;
433
-
434
- // TODO: sort by min size also for cases where center is the same
435
- if ( distance < minDistance ) {
436
- minDistance = distance ;
437
- nodeToHover = node ;
438
- }
439
- }
440
- }
450
+ const nodeToHover = this . getNodeAtPosition ( e ) ;
441
451
442
452
if ( nodeToHover && this . hoveredNode !== nodeToHover && ! this . nodeDataCache [ nodeToHover ] . hidden ) {
443
453
// Handling passing from one node to the other directly
@@ -457,7 +467,7 @@ export default class Sigma extends TypedEventEmitter<SigmaEvents> {
457
467
458
468
const size = this . scaleSize ( data . size ) ;
459
469
460
- if ( ! mouseIsOnNode ( e . x , e . y , pos . x , pos . y , size ) ) {
470
+ if ( ! this . mouseIsOnNode ( e , pos , size ) ) {
461
471
const node = this . hoveredNode ;
462
472
this . hoveredNode = null ;
463
473
@@ -487,10 +497,13 @@ export default class Sigma extends TypedEventEmitter<SigmaEvents> {
487
497
} ,
488
498
} ;
489
499
490
- if ( this . hoveredNode )
500
+ const isFakeSigmaMouseEvent = ( e . original as FakeSigmaMouseEvent ) . isFakeSigmaMouseEvent ;
501
+ const nodeAtPosition = isFakeSigmaMouseEvent ? this . getNodeAtPosition ( e ) : this . hoveredNode ;
502
+
503
+ if ( nodeAtPosition )
491
504
return this . emit ( `${ eventType } Node` , {
492
505
...baseEvent ,
493
- node : this . hoveredNode ,
506
+ node : nodeAtPosition ,
494
507
} ) ;
495
508
496
509
if ( eventType === "wheel" ? this . settings . enableEdgeWheelEvents : this . settings . enableEdgeClickEvents ) {
0 commit comments