// // Add a line for each link, and a circle for each node.
// const link = svg
// .append("g")
// .attr("stroke", "#CCCCCC")
// .attr("stroke-opacity", 0.6)
// .selectAll()
// .data(links)
// .join("line")
// .attr("stroke-width", 3)
// .attr("class", "link")
// .style("opacity", 0); // Initial opacity set to 0
// const node = svg
// .append("g")
// .attr("stroke", "#CCCCCC")
// .attr("stroke-width", 1.5)
// .selectAll()
// .data(nodes)
// .join("circle")
// .attr("r", 5)
// .attr("fill", "lightblue")
// .attr("class", "node")
// .style("opacity", 0); // Initial opacity set to 0
// node.append("title").text((d) => d.productId);
// link
// .attr("x1", (d) => d.source.x)
// .attr("y1", (d) => d.source.y)
// .attr("x2", (d) => d.target.x)
// .attr("y2", (d) => d.target.y);
// node.attr("cx", (d) => d.x).attr("cy", (d) => d.y);
// node
// .transition()
// .duration(7500) // Duration of fade-in
// .delay((d, i) => i * 5) // Stagger the fade-in of nodes
// .style("opacity", 1);
// link
// .transition()
// .duration(7500)
// .delay((d, i) => i * 5)
// .style("opacity", 1);
// // Default styles
// const defaultNodeStyle = { stroke: "#fff", strokeWidth: 1.5 };
// const defaultLinkStyle = {
// stroke: "#999",
// strokeWidth: 3
// };
// // Highlighted styles
// const highlightStyle = { stroke: "red", strokeWidth: 3 };
// node.on("mouseover", handleMouseOver).on("mouseout", handleMouseOut);
// function handleMouseOver(event, d) {
// // Highlight the node with transition
// d3.select(this)
// .transition()
// .duration(transitionTime) // Duration in milliseconds
// .style("stroke", highlightStyle.stroke)
// .style("stroke-width", highlightStyle.strokeWidth);
// // Highlight the links and connected nodes with transition
// link
// .transition()
// .duration(transitionTime)
// .style("stroke", (l) =>
// l.source === d || l.target === d
// ? highlightStyle.stroke
// : defaultLinkStyle.stroke
// )
// .style("stroke-width", (l) =>
// l.source === d || l.target === d
// ? highlightStyle.strokeWidth
// : defaultLinkStyle.strokeWidth(l)
// );
// node
// .transition()
// .duration(transitionTime)
// .style("stroke", (n) =>
// isConnected(d, n) ? highlightStyle.stroke : defaultNodeStyle.stroke
// )
// .style("stroke-width", (n) =>
// isConnected(d, n)
// ? highlightStyle.strokeWidth
// : defaultNodeStyle.strokeWidth
// );
// // Show tooltip
// showTooltip(event, d);
// }
// function handleMouseOut(event, d) {
// // Revert to default styles with transition
// link
// .transition()
// .duration(transitionTime / 2)
// .style("stroke", defaultLinkStyle.stroke)
// .style("stroke-width", defaultLinkStyle.strokeWidth);
// node
// .transition()
// .duration(transitionTime / 2)
// .style("stroke", defaultNodeStyle.stroke)
// .style("stroke-width", defaultNodeStyle.strokeWidth);
// // Hide tooltip
// hideTooltip();
// }
// function isConnected(a, b) {
// return links.some(
// (l) =>
// (l.source === a && l.target === b) || (l.source === b && l.target === a)
// );
// }
// function showTooltip(event, d) {
// const tooltip = d3
// .select("body")
// .append("div")
// .attr("class", "tooltip")
// .style("opacity", 0);
// tooltip.transition().duration(200).style("opacity", 0.9);
// tooltip
// .html("Target: " + d.Target) // Adjust according to your data structure
// .style("left", event.pageX + "px")
// .style("top", event.pageY - 28 + "px");
// }
// function hideTooltip() {
// d3.select(".tooltip").remove();
// }
// // When this cell is re-run, stop the previous simulation. (This doesn’t
// // really matter since the target alpha is zero and the simulation will
// // stop naturally, but it’s a good practice.)
// invalidation.then(() => simulation.stop());
// return svg.node();
// }