I need to override the default node hover effect on a network graph in Highchart.js. The default behaviour is that when you hover on a Node the linkedTo and linkedFrom Nodes are highlighted, the desired behaviour would be that when I hover on a Node,only the linkedFrom Nodes are highlighted, basically like a Breadth-First-Search visualization, I’ve managed to write the algorithm, but some extra Nodes are highlighted.
This is the algorithm I use to highlight all the Nodes, but this doesn’t override the default functionality
point: { events: { mouseOver: function () { var point = this, chart = this.series.chart, nodes = chart.series[0].nodes; bfs(this.id); function bfs(start) { const queue = [findNodeById(start)]; // Store visited nodes in a set const visited = new Set(); // Loop until we have something in the queue while (queue.length > 0) { // Pop out first element from queue const topNode = queue.shift(); // Edges TO first element const prevEdges = topNode.linksTo; for (const edge of prevEdges) { // For each edge find their corresponding nodes and set their state to 'hover' let prevNode = findNodeById(edge.from); prevNode.setState("hover"); // If edge is not visited yet, push to Set and add to queue if (!visited.has(prevNode)) { visited.add(prevNode); queue.push(prevNode); } // nextNode.setState('inactive') } } } function findNodeById(id) { return nodes.filter((node) => node.id == id)[0]; } }, }, },
I’ve tried to disable/enable the hover state, but didn’t work. My approach might be completely wrong here, any suggestion is appreciated!
Advertisement
Answer
The simplest solution is to overwrite the default setState
function, example:
(function(H) { H.seriesTypes.networkgraph.prototype.pointClass.prototype.setState = function(state) { var args = arguments, Point = H.Point, others = this.isNode ? this.linksTo.concat(this.linksFrom) : [this.fromNode, this.toNode ]; if (state !== 'select') { others.forEach(function(linkOrNode) { if (linkOrNode && linkOrNode.series) { Point.prototype.setState.apply(linkOrNode, args); if (!linkOrNode.isNode) { if (linkOrNode.fromNode.graphic) { Point.prototype.setState.apply(linkOrNode.fromNode, args); } /* Modification - prevent hover effect on toNode if (linkOrNode.toNode && linkOrNode.toNode.graphic) { Point.prototype.setState.apply(linkOrNode.toNode, args); } */ } } }); } Point.prototype.setState.apply(this, args); } }(Highcharts));
Live demo: https://jsfiddle.net/BlackLabel/1039zwbt/1/
Docs: https://www.highcharts.com/docs/extending-highcharts/extending-highcharts