title: Getting Screen Positions of D3 Nodes After Transform
body: <p>I'm trying to get the screen position of a node after the layout has been transformed by d3.behavior.zoom() but I'm not having much luck. How might I go about getting a node's actual position in the window after translating and scaling the layout?</p>
  
  <pre><code>mouseOver = function(node) {
    screenX = magic(node.x); // Need a magic function to transform node
    screenY = magic(node.y); // positions into screen coordinates.
  };
  </code></pre>
  
  <p>Any guidance would be appreciated.</p>
  
  <p>EDIT: 'node' above is a force layout node, so it's x and y properties are set by the simulation and remain constant after the simulation comes to rest, regardless of what type of transform is applied.</p>
  
  <p>EDIT: The strategy I'm using to transform the SVG comes from d3's zoom behavior, which is outlined here: <a href="http://bl.ocks.org/mbostock/3680999" rel="noreferrer">SVG Geometric Zooming</a>.</p>
  
  <pre><code>var svg = d3.select("body").append("svg")
      .attr("width", width)
      .attr("height", height)
    .append("g")
      .call(d3.behavior.zoom().scaleExtent([1, 8]).on("zoom", zoom))
    .append("g");
  
  svg.append("rect")
      .attr("class", "overlay")
      .attr("width", width)
      .attr("height", height);
  
  svg.selectAll("circle")
      .data(data)
    .enter().append("circle")
      .attr("r", 2.5)
      .attr("transform", function(d) { return "translate(" + d + ")"; });
  
  function zoom() {
    svg.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
  }
  </code></pre>
  
  <p>It's pretty straightforward. d3's zoom behavior delivers pan and zoom events to a handler, which applies the transforms to the container element by way of the transform attribute.</p>
  
  <p>EDIT: I'm working around the issue by using mouse coordinates instead of node coordinates, since I'm interested in the node position when the node is hovered over with the mouse pointer. It's not exactly the behavior I'm after, but it works for the most part, and is better than nothing.</p>
  
  <p>EDIT: The solution was to get the current transformation matrix of the svg element with element.getCTM() and then use it to offset the x and y coordinates to a screen-relative state. See below.</p>