Drag behavior not targeting node text when Intended

23 Views Asked by At

I was able to remove the transition to text function and the drag behavior worked on the nodes, but combining both behaviors seems to result in the loss of the text node drag behavior. I am curious if I am technically ending the simulation after the transition to text, and therefore the drag behavior for the simulation is not happening.

I'm also curious if maybe the way I'm targeting the text node is only targeting the text, independent of the node, or if the area to drag the text is so small it's impossible to grab the right point.

If anyone has feedback on where my code is going wrong I would really appreciate the insight. I am a beginner and relying heavily on ChatGPT to get the write structure into place so I can tweak it afterwards.

function createVisualization() {
  const margin = { top: 20, right: 20, bottom: 20, left: 20 };
  const svgWidth = window.innerWidth - margin.left - margin.right;
  const svgHeight = window.innerHeight - margin.top - margin.bottom;

  svg = d3.select("#visualization")
    .append("svg")
    .attr("width", svgWidth)
    .attr("height", svgHeight);

  simulation = d3.forceSimulation(nodes)
    .force("link", d3.forceLink(links).id(d => d.id))
    .force("charge", d3.forceManyBody().strength(-150))
    .force("center", d3.forceCenter(svgWidth / 2, svgHeight / 2))
    .force("collide", d3.forceCollide().radius(20))
    .force("x", d3.forceX(svgWidth / 2).strength(0.010))
    .force("y", d3.forceY(svgHeight / 2).strength(0.05));

  const link = svg.selectAll(".link")
    .data(links)
    .enter().append("line")
    .attr("class", "link");

  const node = svg.selectAll(".node")
    .data(nodes)
    .enter().append("circle")
    .attr("class", "node")
    .attr("r", 0);

  simulation.on("tick", () => {
    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);

    if (simulation.alpha() < 0.001) {
      node.transition().duration(500)
        .attr("r", 0)
        .attr("opacity", 0)
        .remove()
        .end()
        .then(() => {
          const nodeText = svg.selectAll(".node-text")
            .data(nodes)
            .enter().append("text")
            .attr("class", "node-text")
            .attr("x", d => d.x)
            .attr("y", d => d.y)
            .text(d => d.id)
            .style("opacity", 0)
            .transition().duration(600)
            .style("opacity", 1)
            .call(drag(simulation)); // Add drag behavior after text transition
        });
    }
  });
}

function updateVisualization() {
  const svgWidth = window.innerWidth;
  const svgHeight = window.innerHeight;

  svg.attr("width", svgWidth)
    .attr("height", svgHeight);

  simulation.force("center", d3.forceCenter(svgWidth / 2, svgHeight / 2));
  simulation.alpha(1).restart();
}

function drag(simulation) {
  function dragstarted(event) {
    if (!event.active) simulation.alphaTarget(0.3).restart();
    event.subject.fx = event.subject.x;
    event.subject.fy = event.subject.y;
  }

  function dragged(event) {
    event.subject.fx = event.x;
    event.subject.fy = event.y;
  }

  function dragended(event) {
    if (!event.active) simulation.alphaTarget(0);
    event.subject.fx = null;
    event.subject.fy = null;
  }

  return d3.drag()
    .on("start", dragstarted)
    .on("drag", dragged)
    .on("end", dragended);
}

createVisualization();

window.addEventListener("resize", updateVisualization);
0

There are 0 best solutions below