Mise à jour d'un Élément SVG Z-Index Avec D3
Ce qui est un moyen efficace pour apporter un élément SVG vers le haut de l'axe z, à l'aide de la D3 de la bibliothèque?
Mon scénario est un graphique qui met en évidence (par l'ajout d'un stroke
à la path
) lorsque la souris est sur une pièce donnée. Le bloc de code pour la génération de mon tableau ci-dessous:
svg.selectAll("path")
.data(d)
.enter().append("path")
.attr("d", arc)
.attr("class", "arc")
.attr("fill", function(d) { return color(d.name); })
.attr("stroke", "#fff")
.attr("stroke-width", 0)
.on("mouseover", function(d) {
d3.select(this)
.attr("stroke-width", 2)
.classed("top", true);
//.style("z-index", 1);
})
.on("mouseout", function(d) {
d3.select(this)
.attr("stroke-width", 0)
.classed("top", false);
//.style("z-index", -1);
});
J'ai essayé quelques options, mais pas de chance jusqu'à présent. À l'aide de style("z-index")
et de l'appel de classed
les deux n'ont pas de travail.
Le "top" de la classe est définie comme suit dans mon CSS:
.top {
fill: red;
z-index: 100;
}
La fill
déclaration est là pour s'assurer que je savais que c'était allumer/éteindre correctement. Il est.
J'ai entendu à l'aide de sort
est une option, mais je suis pas clair sur la façon dont il sera mis en œuvre pour amener les "sélectionnés" l'élément vers le haut.
Mise à JOUR:
Je fixe ma situation avec le code suivant, qui ajoute un nouvel arc pour la SVG sur le mouseover
évènement pour montrer une évidence.
svg.selectAll("path")
.data(d)
.enter().append("path")
.attr("d", arc)
.attr("class", "arc")
.style("fill", function(d) { return color(d.name); })
.style("stroke", "#fff")
.style("stroke-width", 0)
.on("mouseover", function(d) {
svg.append("path")
.attr("d", d3.select(this).attr("d"))
.attr("id", "arcSelection")
.style("fill", "none")
.style("stroke", "#fff")
.style("stroke-width", 2);
})
.on("mouseout", function(d) {
d3.select("#arcSelection").remove();
});
Vous devez vous connecter pour publier un commentaire.
L'une des solutions présentées par le développeur est: "l'utilisation D3 opérateur de tri pour trier les éléments." (voir https://github.com/mbostock/d3/issues/252)
Dans cette lumière, on peut trier les éléments par la comparaison de leurs données, ou des positions si elles étaient dataless éléments:
a.id
etd.id
. La solution est de comparer directement lesa
etd
.<g>
.svg:use
élément peut point dynamiquement à l'soulevées élément. Voir stackoverflow.com/a/6289809/292085 pour la solution.Comme expliqué dans les autres réponses, SVG ne pas avoir une notion de l'un z-index. Au lieu de cela, l'ordre des éléments dans le document détermine l'ordre dans le dessin.
En dehors de réordonner les éléments manuellement, il est une autre façon pour certaines situations:
De travail avec D3 vous avez souvent de certains types d'éléments qui devraient toujours être dessiné sur d'autres types d'éléments.
Par exemple, lors de la présentation des graphiques, des liens doivent toujours être placé au-dessous des nœuds. Plus généralement, certains éléments de décor ont généralement besoin d'être placé au-dessous de tout le reste, alors que certains des faits saillants et des superpositions doit être placé au-dessus.
Si vous avez ce genre de situation, j'ai trouvé que la création d' groupe parent éléments pour ces groupes d'éléments est la meilleure façon d'aller. En SVG, vous pouvez utiliser le
g
élément. Par exemple, si vous avez des liens qui doivent toujours être placé au-dessous des nœuds, procédez de la manière suivante:Maintenant, lorsque vous peignez vos liens et de nœuds, sélectionnez comme suit (les sélecteurs de départ avec
#
de référence de l'identifiant de l'élément):Maintenant, tous les liens seront toujours ajoutées structurellement avant que tous les éléments de nœuds. Ainsi, le SVG montrera tous les liens au-dessous de tous les nœuds, peu importe combien de fois et dans quel ordre vous d'ajouter ou de supprimer des éléments. Bien sûr, tous les éléments de même type (c'est à dire dans le même conteneur) seront toujours soumises à l'ordre dans lequel ils ont été ajoutés.
Depuis SVG n'a pas de Z-index, mais utiliser l'ordre des éléments du DOM, vous pouvez le porter à l'avant par:
Ensuite, vous pouvez par exemple faire usage de insertBefore de le remettre sur les
mouseout
. Toutefois, cela vous oblige à être en mesure de cibler le frère-nœud votre élément doit être inséré avant.DÉMO: Prendre un coup d'oeil à ce JSFiddle
:hover
les styles. Aussi, je ne pense pas que le ìnsert fonction à la fin serait nécessaire pour ce cas d'utilisation.insert
fonction n'est probablement pas la meilleure façon d'aller, parce qu'il crée un nouveau élément. Nous voulons juste pour déplacer un élément existant, donc j'utilise desinsertBefore
dans cet exemple à la place.SVG ne fait pas de z-index. Z-ordre est dicté par l'ordre du SVG éléments du DOM dans leur conteneur.
Aussi loin que je puisse dire (et j'ai essayé cette une couple de fois dans le passé), D3 n'est pas de fournir des méthodes pour le détachement et le rattachement à un seul élément pour l'amener à l'avant ou que sais-je encore.
Il y a un
.commande()
méthode, qui bouleverse les nœuds pour correspondre à l'ordre qu'ils apparaissent dans la sélection. Dans votre cas, vous devez apporter un seul élément à l'avant. Donc, techniquement, vous pourriez complexe de la sélection avec l'élément souhaité à l'avant (ou à la fin, ne peut pas se rappeler qui est le plus en haut), puis d'appelerorder()
sur elle.Ou, vous pouvez passer de d3 pour cette tâche et utiliser du JS (jQuery) pour ré-insérer le seul élément du DOM.
.style('pointer-events', 'none')
à la superposition de chemin. Malheureusement, cette propriété ne rien faire dans IE, mais tout de même....La réponse la plus simple est d'utiliser d3 méthodes de commande. En plus de d3.select('g').de commande(), il y est .lower() et .raise() dans la version 4. Cela change la façon dont votre éléments apparaissent. Veuillez consulter la documentation pour plus d'informations - https://github.com/d3/d3/blob/master/API.md#selections-d3-selection
J'ai mis en place futurend de la solution dans mon code et cela a fonctionné, mais avec le grand nombre d'éléments que j'ai été en utilisant, il était très lent. Voici la méthode alternative à l'utilisation de jQuery, qui a travaillé plus vite pour mon particulier de visualisation. Il s'appuie sur le svgs vous voulez sur le dessus d'avoir une classe en commun (dans mon exemple, la classe est noté dans mon jeu de données que d.la clé). Dans mon code il y a un
<g>
avec la catégorie "bureaux" qui contient tous les SVGs je suis en train de redéfinir l'organisation.Ainsi, lorsque vous passez la souris sur un point particulier de données, le code trouve toutes les autres points de données avec SVG des éléments du DOM avec cette classe particulière. Puis il se détache et ré-insère le SVG DOM éléments associés à ces points de données.
Voulu étendre sur ce que @notan3xit répondu plutôt que d'écrire une toute nouvelle réponse (mais je n'ai pas assez de réputation).
Une autre façon de résoudre l'élément de commande problème est l'utilisation de 'insert', plutôt que 'append' lors de l'élaboration . De cette façon, les chemins d'accès seront toujours placés avant les autres éléments svg(cela suppose que votre code déjà fait l'entrée() pour les liens avant l'entrée() pour les autres éléments svg).
d3 insérer api: https://github.com/mbostock/d3/wiki/Selections#insert
Il m'a fallu des âges à trouver comment modifier l'ordre de superposition dans un SVG. J'en avais vraiment besoin dans le contexte de la d3.brosse avec info-bulle comportement. Afin d'avoir les deux fonctions sont bien ensemble (http://wrobstory.github.io/2013/11/D3-brush-and-tooltip.html), vous avez besoin de la d3.pinceau pour être le premier dans l'ordre-Z (de la 1re à être attirée sur la toile, alors couverts par le reste des éléments SVG) et il va capturer tous les événements de la souris, peu importe ce qui est sur le dessus de celui-ci (avec plus Z indices).
La plupart des commentaires du forum disent que vous devriez ajouter la d3.pinceau d'abord dans votre code, votre SVG "dessin" du code. Mais pour moi, il n'était pas possible comme je l'ai chargé, une externe fichier SVG. Vous pouvez facilement ajouter de la brosse, à tout moment et modifier l'ordre de superposition avec:
Dans le contexte d'un d3.brosse de l'installation, il va ressembler:
d3.js insert() la fonction de l'API: https://github.com/mbostock/d3/wiki/Selections#insert
Espérons que cette aide!
Version 1
En théorie, la suivante devrait fonctionner correctement.
Le code CSS :
Ce code CSS va ajouter un trait pour le chemin d'accès sélectionné.
Le code JS :
Ce code JS enlève d'abord le chemin de l'arbre du DOM et ajoute que le dernier enfant de son parent. Cela permet de s'assurer que le chemin est dessinée au-dessus de tous les autres enfants de la même mère.
Dans la pratique, ce code fonctionne dans Chrome, mais les pauses dans certains autres navigateurs. Je l'ai essayé dans Firefox 20 sur mon Linux Mint machine et ne pouvait pas le faire fonctionner. En quelque sorte, Firefox ne parvient pas à déclencher la
:hover
styles et je n'ai pas trouvé un moyen de résoudre ce problème.Version 2
Alors je suis venu avec une solution de rechange. Il peut être un peu "sale", mais au moins il fonctionne, et il ne nécessite pas de boucle sur tous les éléments (comme certains des autres réponses).
Le code CSS :
Au lieu d'utiliser le
:hover
pseudoselector, j'utilise un.hover
classeLe code JS :
À la souris, j'ai ajouter de la
.hover
classe de mon chemin. Sur mouseout, je le supprime.Comme dans le premier cas, le code supprime également le chemin de l'arbre du DOM et ajoute que le dernier enfant de son parent.
Vous pouvez le Faire comme ceci Sur le Dessus de la Souris, Vous pouvez Tirer vers le haut.
};
Si Vous voulez Pousser À Dos