Skip to content

Commit

Permalink
Network: Add pointer data to hover events (almende#3128)
Browse files Browse the repository at this point in the history
Fix for almende#1222.

This makes the passed data of events `hoverNode`, `hoverEdge`, `blurNode` and `blurEdge`
more conformant to the passed data of the click events. In particular, the following
fields are added to the event data:

```
event: [Object] original hover event,
pointer: {
    DOM: {x:pointer_x, y:pointer_y},
    canvas: {x:canvas_x, y:canvas_y}
}
```

The changes can be tested with example `network/events/InteractionEvents`.
  • Loading branch information
wimrijnders authored and Primoz Susa committed Jan 3, 2019
1 parent 1b891da commit 8ed51d3
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 39 deletions.
11 changes: 2 additions & 9 deletions lib/network/modules/InteractionHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -552,16 +552,9 @@ class InteractionHandler {
}
}

/**
* Adding hover highlights
*/
// adding hover highlights
if (this.options.hover === true) {
// adding hover highlights
let obj = this.selectionHandler.getNodeAt(pointer);
if (obj === undefined) {
obj = this.selectionHandler.getEdgeAt(pointer);
}
this.selectionHandler.hoverObject(obj);
this.selectionHandler.hoverObject(event, pointer);
}
}

Expand Down
122 changes: 92 additions & 30 deletions lib/network/modules/SelectionHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,20 +75,52 @@ class SelectionHandler {
return selectionChanged;
}

_generateClickEvent(eventType, event, pointer, oldSelection, emptySelection = false) {
let properties;
if (emptySelection === true) {
properties = {nodes:[], edges:[]};
}
else {
properties = this.getSelection();
}

/**
* Create an object containing the standard fields for an event.
*
* @param {Event} event
* @param {Object} pointer | object with the x and y screen coordinates of the mouse
* @private
*/
_initBaseEvent(event, pointer) {
let properties = {};

properties['pointer'] = {
DOM: {x: pointer.x, y: pointer.y},
canvas: this.canvas.DOMtoCanvas(pointer)
};
properties['event'] = event;

return properties;
}


/**
* Generate an event which the user can catch.
*
* This adds some extra data to the event with respect to cursor position and
* selected nodes and edges.
*
* @param {String} eventType | Name of event to send
* @param {Event} event
* @param {Object} pointer | object with the x and y screen coordinates of the mouse
* @param {Object|undefined} object | If present, selection state before event occured
* @param {boolean|undefined} | Indicate if selection data should be passed
*/
_generateClickEvent(eventType, event, pointer, oldSelection, emptySelection = false) {
let properties = this._initBaseEvent(event, pointer);

if (emptySelection === true) {
properties.nodes = [];
properties.edges = [];
}
else {
let tmp = this.getSelection();
properties.nodes = tmp.nodes;
properties.edges = tmp.edges;
}

if (oldSelection !== undefined) {
properties['previousSelection'] = oldSelection;
}
Expand Down Expand Up @@ -486,38 +518,78 @@ class SelectionHandler {


/**
* This is called when someone clicks on a node. either select or deselect it.
* If there is an existing selection and we don't want to append to it, clear the existing selection
* Remove the highlight from a node or edge, in response to mouse movement
*
* @param {Event} event
* @param {Object} pointer | object with the x and y screen coordinates of the mouse
* @param {Node || Edge} object
* @private
*/
blurObject(object) {
emitBlurEvent(event, pointer, object) {
let properties = this._initBaseEvent(event, pointer);

if (object.hover === true) {
object.hover = false;
if (object instanceof Node) {
this.body.emitter.emit("blurNode", {node: object.id});
properties.node = object.id;
this.body.emitter.emit("blurNode", properties);
}
else {
this.body.emitter.emit("blurEdge", {edge: object.id});
properties.edge = object.id;
this.body.emitter.emit("blurEdge", properties);
}
}
}


/**
* This is called when someone clicks on a node. either select or deselect it.
* If there is an existing selection and we don't want to append to it, clear the existing selection
* Create the highlight for a node or edge, in response to mouse movement
*
* @param {Event} event
* @param {Object} pointer | object with the x and y screen coordinates of the mouse
* @param {Node || Edge} object
* @private
*/
hoverObject(object) {
emitHoverEvent(event, pointer, object) {
let properties = this._initBaseEvent(event, pointer);
let hoverChanged = false;

if (object.hover === false) {
object.hover = true;
this._addToHover(object);
hoverChanged = true;
if (object instanceof Node) {
properties.node = object.id;
this.body.emitter.emit("hoverNode", properties);
}
else {
properties.edge = object.id;
this.body.emitter.emit("hoverEdge", properties);
}
}

return hoverChanged;
}


/**
* Perform actions in response to a mouse movement.
*
* @param {Event} event
* @param {Object} pointer | object with the x and y screen coordinates of the mouse
*/
hoverObject(event, pointer) {
let object = this.getNodeAt(pointer);
if (object === undefined) {
object = this.getEdgeAt(pointer);
}

let hoverChanged = false;
// remove all node hover highlights
for (let nodeId in this.hoverObj.nodes) {
if (this.hoverObj.nodes.hasOwnProperty(nodeId)) {
if (object === undefined || (object instanceof Node && object.id != nodeId) || object instanceof Edge) {
this.blurObject(this.hoverObj.nodes[nodeId]);
this.emitBlurEvent(event, pointer, this.hoverObj.nodes[nodeId]);
delete this.hoverObj.nodes[nodeId];
hoverChanged = true;
}
Expand All @@ -528,33 +600,23 @@ class SelectionHandler {
for (let edgeId in this.hoverObj.edges) {
if (this.hoverObj.edges.hasOwnProperty(edgeId)) {
// if the hover has been changed here it means that the node has been hovered over or off
// we then do not use the blurObject method here.
// we then do not use the emitBlurEvent method here.
if (hoverChanged === true) {
this.hoverObj.edges[edgeId].hover = false;
delete this.hoverObj.edges[edgeId];
}
// if the blur remains the same and the object is undefined (mouse off) or another
// edge has been hovered, or another node has been hovered we blur the edge.
else if (object === undefined || (object instanceof Edge && object.id != edgeId) || (object instanceof Node && !object.hover)) {
this.blurObject(this.hoverObj.edges[edgeId]);
this.emitBlurEvent(event, pointer, this.hoverObj.edges[edgeId]);
delete this.hoverObj.edges[edgeId];
hoverChanged = true;
}
}
}

if (object !== undefined) {
if (object.hover === false) {
object.hover = true;
this._addToHover(object);
hoverChanged = true;
if (object instanceof Node) {
this.body.emitter.emit("hoverNode", {node: object.id});
}
else {
this.body.emitter.emit("hoverEdge", {edge: object.id});
}
}
hoverChanged = hoverChanged || this.emitHoverEvent(event, pointer, object);
if (object instanceof Node && this.options.hoverConnectedEdges === true) {
this._hoverConnectedEdges(object);
}
Expand Down

0 comments on commit 8ed51d3

Please sign in to comment.