web-dev-qa-db-fra.com

D3.js: Comment obtenir la largeur et la hauteur calculées pour un élément arbitraire?

J'ai besoin de connaître exactement la largeur et la hauteur d'un élément g arbitraire dans ma SVG car je dois dessiner un marqueur de sélection autour de celui-ci une fois que l'utilisateur a cliqué dessus.

Ce que j'ai vu sur Internet ressemble à quelque chose comme: d3.select("myG").style("width"). Le problème est que l'élément n'aura pas toujours un attribut explicite de largeur. Par exemple, lorsque je crée un cercle à l'intérieur de g, le radious (r) est défini à la place de la largeur. Même si j'utilise la méthode window.getComputedStyle sur une circle, elle retournera "auto".

Existe-t-il un moyen de calculer la largeur d’un sélecteur svg arbitraire dans D3?

Je vous remercie.

111
André Pena

Pour les éléments SVG

En utilisant quelque chose comme selection.node().getBBox() vous obtenez des valeurs comme

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

Pour les éléments HTML

Utilisez selection.node().getBoundingClientRect()

204
Christopher Hackett

.getBoundingClientRect () retourne la taille d'un élément et sa position par rapport à la fenêtre d'affichage.

  • gauche droite 
  • haut, bas 
  • hauteur largeur

Exemple :

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

Une fois, j’ai fait face au problème lorsque je ne savais pas quel élément était actuellement stocké dans ma variable (svg ou html) mais j’avais besoin de l’obtenir en largeur et en hauteur. J'ai créé cette fonction et je souhaite la partager:

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;
}

Petite démo dans l'extrait caché ci-dessous. Nous nous occupons de cliquer sur le div bleu et sur le cercle rouge svg avec la même fonction.

var svg = d3.select('svg')
  .attr('width', 50)
  .attr('height', 50);

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

  if (node instanceof SVGElement) {
   	dimensions = node.getBBox();
  } else {
  	dimensions = node.getBoundingClientRect();
  }
  console.clear();
  console.log(dimensions);
  return dimensions;
}

var circle = svg
    .append("circle")
    .attr("r", 20)
    .attr("cx", 30)
    .attr("cy", 30)
    .attr("fill", "red")
    .on("click", function() { computeDimensions(circle); });
    
var div = d3.selectAll("div").on("click", function() { computeDimensions(div) });
* {
  margin: 0;
  padding: 0;
  border: 0;
}

body {
  background: #ffd;
}

.div {
  display: inline-block;
  background-color: blue;
  margin-right: 30px;
  width: 30px;
  height: 30px;
}
<h3>
  Click on blue div block or svg circle
</h3>
<svg></svg>
<div class="div"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.11.0/d3.min.js"></script>

1