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 mon SVG parce que j'ai besoin de dessiner un marqueur de sélection autour d'elle une fois que l'Utilisateur a cliqué dessus.

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

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

Merci.

103
demandé sur André Pena 2014-02-24 18:39:47

3 réponses

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

Utiliser selection.node().getBoundingClientRect()

193
répondu Christopher Hackett 2015-02-04 11:50:24

.getBoundingClientRect () renvoie la taille d'un élément et sa position par rapport à la fenêtre.Nous pouvons facilement obtenir suivant

  • gauche, droite
  • Haut, Bas
  • hauteur, largeur

Exemple :

var element = d3.select('.elementClassName').node();
element.getBoundingClientRect().width;
21
répondu Malik Khalil 2017-02-15 10:56:43

Une fois que j'ai fait face au problème quand 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 veux 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 manipulons cliquez sur le div bleu et sur le cercle svg rouge 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
répondu Mikhail Shabrikov 2017-11-01 08:45:28