Open happylolonly opened 4 months ago
onNodeHover?: (node: NodeObject
@happylolonly You can get the value of the node from the onNodeHover function.
In the case of react, <ForceGraph onNodeHover={(node) => console.log("hovering node", node) } /> Is this the right question for you?
Suppose i want to render a tooltip displaying the node details on hover, how would i do it. Also for some reason when i hover over the node, the entire graph re renders. It keeps re rendering until unless i remove my mouse from the node. the code ; ` import React, { useMemo, useState, useCallback, useRef } from 'react'; import ForceGraph2D from 'react-force-graph-2d'; import { graphData } from './data'; import { generateNodesForForceGraph } from './utils/nodeGenerator'; import { generateEdgesForForceGraph } from './utils/edgeGenerator';
const HighlightGraph: React.FC = () => { // Generate nodes and links const nodes = generateNodesForForceGraph(graphData); const links = generateEdgesForForceGraph(graphData);
// Memoize node and link cross-referencing
const { nodesWithNeighbors, enhancedLinks } = useMemo(() => {
// Cross-link node objects
const nodesMap = new Map(nodes.map(node => [node.id, { ...node, neighbors: [], links: [] }]));
const enhancedLinks = links.map(link => {
const sourceNode = nodesMap.get(link.source);
const targetNode = nodesMap.get(link.target);
if (sourceNode && targetNode) {
sourceNode.neighbors.push(targetNode);
targetNode.neighbors.push(sourceNode);
sourceNode.links.push(link);
targetNode.links.push(link);
}
return {
...link,
source: sourceNode,
target: targetNode
};
});
return {
nodesWithNeighbors: Array.from(nodesMap.values()),
enhancedLinks
};
}, [nodes, links]);
// State for highlighting with useRef to prevent unnecessary re-renders
const highlightNodesRef = useRef(new Set());
const highlightLinksRef = useRef(new Set());
const [hoverNode, setHoverNode] = useState<any>(null);
// Optimized node hover handler
const handleNodeHover = useCallback((node) => {
// Prevent unnecessary state updates if the hovered node is the same
if (node === hoverNode) return;
console.log("node hovered", node)
// Clear previous highlights
highlightNodesRef.current.clear();
highlightLinksRef.current.clear();
if (node) {
// Add hovered node
highlightNodesRef.current.add(node);
// Add neighbors and their links
node.neighbors.forEach(neighbor => {
highlightNodesRef.current.add(neighbor);
});
node.links.forEach(link => {
highlightLinksRef.current.add(link);
});
}
// Update hover node state
setHoverNode(node);
}, [hoverNode]);
// Link hover handler
const handleLinkHover = useCallback((link) => {
// Clear previous highlights
highlightNodesRef.current.clear();
highlightLinksRef.current.clear();
if (link) {
highlightLinksRef.current.add(link);
highlightNodesRef.current.add(link.source);
highlightNodesRef.current.add(link.target);
}
// Reset hover node
setHoverNode(null);
}, []);
// Optimized ring painting with useCallback
const paintRing = useCallback((node, ctx) => {
// Only paint for highlighted nodes
if (highlightNodesRef.current.has(node)) {
ctx.beginPath();
ctx.arc(node.x, node.y, 4 * 1.4, 0, 2 * Math.PI, false);
ctx.fillStyle = node === hoverNode ? 'red' : 'orange';
ctx.fill();
}
}, [hoverNode]);
// Full node pointer area
const nodePointerAreaPaint = useCallback((node, color, ctx) => {
ctx.fillStyle = color;
ctx.beginPath();
ctx.arc(node.x, node.y, 4 * 1.4, 0, 2 * Math.PI, false);
ctx.fill();
}, []);
console.log("Node paint", nodePointerAreaPaint)
return (
<ForceGraph2D
graphData={{
nodes: nodesWithNeighbors,
links: enhancedLinks
}}
nodeRelSize={4}
autoPauseRedraw={false}
nodePointerAreaPaint={nodePointerAreaPaint}
// Link styling
linkWidth={link => highlightLinksRef.current.has(link) ? 5 : 1}
linkDirectionalParticles={4}
linkDirectionalParticleWidth={link => highlightLinksRef.current.has(link) ? 4 : 0}
// Node styling
nodeCanvasObjectMode={node => highlightNodesRef.current.has(node) ? 'before' : undefined}
nodeCanvasObject={paintRing}
// Interaction handlers
onNodeHover={handleNodeHover}
onLinkHover={handleLinkHover}
/>
);
};
export default HighlightGraph;`
What is correct way to load node data on hover?