web-dev-qa-db-fra.com

Comment accéder à l'élément DOM en corrélation avec un objet D3 SVG?

J'essaie d'apprendre D3 en expérimentant avec l'un de leurs bubblecharts de base . Première tâche: comprendre comment faire glisser une bulle et la faire devenir l'objet le plus haut pendant qu'elle est glissée. (Le problème est d'obtenir le modèle d'objet de D3 à mapper sur le DOM, mais j'y arriverai ...)

Pour le faire glisser, nous pouvons simplement invoquer le comportement de glissement de d3 en utilisant le code qu'ils fournissent:

var drag = d3.behavior.drag()
    .on("dragstart", dragstart)
    .on("drag", dragmove)
    .on("dragend", dragend);

Fonctionne très bien. Ça traîne bien. Maintenant, comment pouvons-nous l'obtenir pour être l'élément le plus haut? Recherchez "svg z-index" ici et il devient rapidement évident que la seule façon de changer l'index est de déplacer un objet plus bas dans le DOM. D'ACCORD. Ils ne facilitent pas la tâche car les bulles individuelles n'ont pas d'ID, mais en jouant avec la console, nous pouvons localiser l'un de ces objets avec:

$("text:contains('TimeScale')").parent()

et nous pouvons le déplacer à la fin de l'élément svg contenant avec:

.appendTo('svg')

Faites-le glisser après cela, et c'est l'élément le plus haut. Jusqu'à présent, tout va bien si vous travaillez entièrement dans le DOM.

MAIS: ce que je veux vraiment faire, c'est que cela se produise automatiquement chaque fois qu'un objet/bulle donné est déplacé. D3 fournit un modèle pour les fonctions dragstart() et dragend() qui nous permettra d'incorporer une instruction pour faire ce que nous voulons pendant le processus de glissement. Et D3 fournit la syntaxe d3.select(this) qui nous permet d'accéder à la représentation d'objet d3 de l'objet/bulle que vous faites actuellement glisser. Mais comment puis-je transformer proprement ce tableau massif qu'ils retournent en référence à un élément DOM avec lequel je peux interagir et - par exemple - le déplacer à la fin du conteneur svg, ou effectuer d'autres références dans le DOM, comme la soumission de formulaire ?

54
XML

Vous pouvez également accéder à l'élément DOM représenté par une sélection via méthode selection.node ()

var selection = d3.select(domElement);

// later via the selection you can retrieve the element with .node()
var elt = selection.node();
173
Tom Dunn

Tout élément DOM dans un document SVG aura une propriété ownerSVGElement qui fait référence au document SVG dans lequel il se trouve.

Les sélections de D3 ne sont que des tableaux imbriqués avec des méthodes supplémentaires; si vous avez .select() édité un seul élément DOM, vous pouvez l'obtenir avec [0][0], par exemple:

var foo = d3.select(someDOM);

// later, where you don't have someDOM but you do have foo
var someDom = foo[0][0];
var svgRoot = someDom.ownerSVGElement;

Notez cependant que si vous utilisez d3.select(this) alors this déjà est l'élément DOM; vous n'avez pas besoin de l'envelopper dans une sélection D3 juste pour le déballer.

31
Phrogz

Vous pouvez attribuer des ID et des classes aux éléments individuels si vous le souhaitez lorsque vous ajoutez:

node.append("circle.bubble")
.attr("r", function(d) { return d.r; })
.style("fill", function(d) { return fill(d.packageName); })
.attr("id", function(d, i) { return ("idlabel_" + i)})
.attr("class", "bubble")
;

Et puis vous pouvez sélectionner par classe avec selectAll ("circle.bubble") ou sélectionner par id et modifier les attributs comme suit:

var testCircle = svg.select("#idlabel_3")
.style("stroke-width", 8);
11
Elijah