D3.js: como obter a largura e a altura calculadas para um elemento arbitrário?

120

Preciso saber exatamente a largura e a altura de um gelemento arbitrário no meu, SVGporque preciso desenhar um marcador de seleção ao redor dele depois que o usuário clicar nele.

O que eu vi na internet é algo como: d3.select("myG").style("width"). O problema é que o elemento nem sempre terá um atributo explícito de largura definido. Por exemplo, quando eu criar um círculo dentro do g, ele terá o radious ( r) definido em vez da largura. Mesmo se eu usar o window.getComputedStylemétodo em a circle, ele retornará "auto".

Existe uma maneira de calcular a largura de uma svgseleção arbitrária D3?

Obrigado.

André Pena
fonte

Respostas:

225

Para elementos SVG

Usando algo como selection.node().getBBox()você obtém valores como

{
    height: 5, 
    width: 5, 
    y: 50, 
    x: 20
} 

Para elementos HTML

Usar selection.node().getBoundingClientRect()

Christopher Hackett
fonte
36
Para elementos HTML, use em getBoundingClientRect()vez do somente SVG getBBox(). Assim:d3.select("body").node().getBoundingClientRect().width
Toph 03/02
1
Poderia fazer com um pouco mais de informação para ajudar. Para elementos SVG ou HTML? É apenas o Firefox que é o problema? Há algo relatado no console? Qual é o valor retornado? Você tem um exemplo de código mínimo (jsfiddle) que demonstrou o problema?
Christopher Hackett
29

.getBoundingClientRect () retorna o tamanho de um elemento e sua posição em relação à janela de visualização.

  • esquerda direita
  • superior, inferior
  • altura largura

Exemplo:

var element = d3.select('.elementClassName').node();
element.getBoundingClientRect().width;
Malik Khalil
fonte
1

Uma vez me deparei com o problema, quando não sabia qual o elemento atualmente armazenado na minha variável (svg ou html), mas precisava obtê-lo em largura e altura. Criei esta função e quero compartilhá-la:

function computeDimensions(selection) {
  var dimensions = null;
  var node = selection.node();

  if (node instanceof SVGElement) { // check if node is svg element
    dimensions = node.getBBox();
  } else { // else is html element
    dimensions = node.getBoundingClientRect();
  }
  console.log(dimensions);
  return dimensions;
}

Pequena demonstração no trecho oculto abaixo. Lidamos com clique na div azul e no círculo svg vermelho com a mesma função.

Mikhail Shabrikov
fonte