D3: get dimensions of DOM node while appending elements

Viewed 20

Working with d3.js, I'm trying to create a set of nodes, append an SVG circle and text element to each node and then re-position the text element (set its dx and dy attributes). Specifically, I'd like to center the text element inside the SVG.

In my current implementation, the SVG elements are created/appended first, then I'm iterating over the nodes a second time to measure each text element and transform it accordingly:

///////////////////////////////////////
// Create node elements from data... //
///////////////////////////////////////

const canvas = document.getElementById("canvas");
const data_nodes = state.data.nodes;

const elements = canvas.svg
  .append("g")
  .attr("class", "nodes")
  //////
  .selectAll(".node") // <— create empty selection
  .data(data_nodes)
  .enter()
  //////
  .append("svg")      // <— added nested SVG
  .attr("class", "node");

////////////////////////////////
// ...append circle & text... //
////////////////////////////////

elements.append("circle").attr("r", (data) => data.size / 2);
elements.append("text").text((data) => data.text.content)

////////////////////
// ...center text //
////////////////////

for (let node of elements.nodes()) {
  const textEl = node.querySelector("text");
  const width = textEl.getBoundingClientRect().width;
  const height = textEl.getBoundingClientRect().height;
  //////
  textEl.setAttribute("dx", (width / 2) * -1);
  textEl.setAttribute("dy", height / 2);
}

This works, but I'm wondering if it's possible to reference the DOM node corresponding to each appended text element while/after appending it and dynamically setting dx/dy then?

0 Answers
Related