in src/components/InteractiveForceGraph.js [96:232]
render() {
const {
highlightDependencies,
opacityFactor,
children,
className,
selectedNode: propsSelectedNode,
...spreadableProps
} = this.props;
const { hoveredNode, selectedNode: stateSelectedNode } = this.state;
const { links } = ForceGraph.getDataFromChildren(children);
const selectedNode = propsSelectedNode || stateSelectedNode;
const applyOpacity = (opacity = 1) => opacity / opacityFactor;
const createEventHandler = (name, node, fn) => (event) => {
this[name](event, node);
if (fn) {
fn(event);
}
};
const areNodesRelatives = (node1, node2) =>
node1 && node2 && links.findIndex(link =>
link.value > 0 && (
(link.source === nodeId(node1) && link.target === nodeId(node2)) ||
(link.source === nodeId(node2) && link.target === nodeId(node1))
)
) > -1;
const isNodeHighlighted = (focusedNode, node) =>
focusedNode && (
(nodeId(focusedNode) === nodeId(node)) ||
(selectedNode && nodeId(selectedNode) === nodeId(node)) ||
(highlightDependencies && areNodesRelatives(node, selectedNode || focusedNode))
);
const isLinkHighlighted = (focusedNode, link) =>
focusedNode && highlightDependencies && link.value > 0 &&
(nodeId(focusedNode) === link.source ||
nodeId(focusedNode) === link.target);
const fontSizeForNode = node =>
(selectedNode && nodeId(node) === nodeId(selectedNode) ? 14 : 10);
const fontWeightForNode = node =>
(selectedNode && nodeId(node) === nodeId(selectedNode) ? 700 : null);
const showLabelForNode = node =>
isNodeHighlighted(selectedNode, node) ||
isNodeHighlighted(hoveredNode, node);
const opacityForNode = (node, origOpacity = 1) => {
if (
highlightDependencies && selectedNode &&
!isNodeHighlighted(selectedNode, node) &&
!isNodeHighlighted(hoveredNode, node)
) {
return applyOpacity(origOpacity / 4);
} else if (
(selectedNode &&
!isNodeHighlighted(selectedNode, node) &&
!isNodeHighlighted(hoveredNode, node)
) || (
hoveredNode && !isNodeHighlighted(hoveredNode, node)
)
) {
return applyOpacity(origOpacity);
}
return origOpacity;
};
const opacityForLink = (link, origOpacity = 1) => {
if (
highlightDependencies ? (
(!selectedNode && hoveredNode && !isLinkHighlighted(hoveredNode, link)) ||
(selectedNode && !isLinkHighlighted(selectedNode, link))
) : (hoveredNode || selectedNode)
) {
return applyOpacity(origOpacity / 4);
}
if (
hoveredNode && !isLinkHighlighted(hoveredNode, link) &&
selectedNode && !isLinkHighlighted(selectedNode, link)
) {
return applyOpacity(origOpacity);
}
return origOpacity;
};
return (
<ForceGraph className={`rv-force__interactive ${className}`} {...spreadableProps}>
{Children.map(children, (child) => {
if (isNode(child)) {
const {
node,
labelStyle,
fontSize = fontSizeForNode(node),
fontWeight = fontWeightForNode(node),
showLabel = showLabelForNode(node),
onMouseEnter,
onMouseLeave,
onClick,
} = child.props;
let { opacity } = child.props;
opacity = opacityForNode(node, opacity);
return cloneElement(child, {
showLabel,
opacity,
labelStyle: {
fontSize,
fontWeight,
opacity,
...labelStyle,
},
onMouseEnter: createEventHandler('onHoverNode', node, onMouseEnter),
onMouseLeave: createEventHandler('onBlurNode', node, onMouseLeave),
onClick: createEventHandler('onClickNode', node, onClick),
});
} else if (isLink(child)) {
const { link } = child.props;
let { opacity } = child.props;
opacity = opacityForLink(link, opacity);
return cloneElement(child, { opacity });
}
return child;
})}
</ForceGraph>
);
}