Question

Ma compréhension de D3 est actuellement plutôt limitée et je crée actuellement un exemple de dendrogramme de d3.js. On peut le trouver à plusieurs endroits: sur Cette version interactive par exemple.

Lorsque je l'implémente, tout va bien jusqu'à ce que vous essayiez de mettre à jour une propriété comme le diamètre du cercle des nœuds. Si je le fais (en utilisant un cadre interactif comme angularjs qui regarde le changement de paramètre): les nœuds changent de taille. Donc, pas de problème encore. Toutefois, si je clique sur l'un des nœuds, la taille est réinitialisée à la taille d'initialisation au lieu de la nouvelle.

Lorsqu'un nœud a cliqué, il suive la fonction de clic:

 var nodeEnter = node.enter().append("g")
                        .attr("class", "dendrogramnode2")
                        .on("click", click);

La fonction de clic appelle une fonction de mise à jour.

        function click(d) {
            if (d.children) {
                d._children = d.children;
                d.children = null;
            } else {
                d.children = d._children;
                d._children = null;
            }
            update(d);
        }

qui met ensuite à jour le dendrogramme et ouvre ou ferme les nœuds nécessaires.

function update(source) {

  // Compute the new tree layout.
  var nodes = tree.nodes(root),
      links = tree.links(nodes);

  // Normalize for fixed-depth.
  nodes.forEach(function(d) { d.y = d.depth * 80; });

  // Update the nodes…
  var node = svg.selectAll("g.node")
      .data(nodes, function(d) { return d.id || (d.id = ++i); });

  // Enter any new nodes at the parent's previous position.
  var nodeEnter = node.enter().append("g")
      .attr("class", "node")
      //.attr("transform", function(d) { return "rotate(" + (d.x - 90) + ")translate(" + d.y + ")"; })
      .on("click", click);

  nodeEnter.append("circle")
      .attr("r", 1e-6)
      .style("fill", function(d) { return d._children ? "lightsteelblue" : "#fff"; });

  nodeEnter.append("text")
      .attr("x", 10)
      .attr("dy", ".35em")
      .attr("text-anchor", "start")
      //.attr("transform", function(d) { return d.x < 180 ? "translate(0)" : "rotate(180)translate(-" + (d.name.length * 8.5)  + ")"; })
      .text(function(d) { return d.name; })
      .style("fill-opacity", 1e-6);

  // Transition nodes to their new position.
  var nodeUpdate = node.transition()
      .duration(duration)
      .attr("transform", function(d) { return "rotate(" + (d.x - 90) + ")translate(" + d.y + ")"; })

  nodeUpdate.select("circle")
      .attr("r", 4.5)
      .style("fill", function(d) { return d._children ? "lightsteelblue" : "#fff"; });

  nodeUpdate.select("text")
      .style("fill-opacity", 1)
      .attr("transform", function(d) { return d.x < 180 ? "translate(0)" : "rotate(180)translate(-" + (d.name.length + 50)  + ")"; });

  // TODO: appropriate transform
  var nodeExit = node.exit().transition()
      .duration(duration)
      //.attr("transform", function(d) { return "diagonal(" + source.y + "," + source.x + ")"; })
      .remove();

  nodeExit.select("circle")
      .attr("r", 1e-6);

  nodeExit.select("text")
      .style("fill-opacity", 1e-6);

  // Update the links…
  var link = svg.selectAll("path.link")
      .data(links, function(d) { return d.target.id; });

  // Enter any new links at the parent's previous position.
  link.enter().insert("path", "g")
      .attr("class", "link")
      .attr("d", function(d) {
        var o = {x: source.x0, y: source.y0};
        return diagonal({source: o, target: o});
      });

  // Transition links to their new position.
  link.transition()
      .duration(duration)
      .attr("d", diagonal);

  // Transition exiting nodes to the parent's new position.
  link.exit().transition()
      .duration(duration)
      .attr("d", function(d) {
        var o = {x: source.x, y: source.y};
        return diagonal({source: o, target: o});
      })
      .remove();

  // Stash the old positions for transition.
  nodes.forEach(function(d) {
    d.x0 = d.x;
    d.y0 = d.y;
  });
}

Cette fonction de mise à jour est appelée:

  1. à l'initialisation -> Pas de problème (exemple: Cercle R= 5)

  2. Lorsqu'un paramètre est mis à jour -> Pas de problème, les mises à jour du paramètre. (Exemple: Cercle R= 10)

  3. Lorsque vous cliquez sur un nœud -> problematic -> graphique prend des paramètres initiaux. (Exemple: Cercle R= 5)

  4. Tout cela a probablement beaucoup à faire avec le scoping et la façon dont Javascript gère la base de données de la base de données, mais je ne sais pas comment faire cela correctement. J'ai besoin de pouvoir accéder aux nouvelles propriétés au lieu des anciens.

    Y a-t-il un moyen de

    1. Adaptez le code afin que le nouveau paramètre soit pris au lieu des anciens?

    2. lie les paramètres au groupe SVG en tant qu'objet (probablement non aussi efficace?) Alors je peut l'accéder manuellement à partir de n'importe quelle portée à l'aide des sélecteurs D3?

Était-ce utile?

La solution

J'ai défini une propriété à l'élément DOM pour ces attributs qui ne diffèrent pas par datum.

            function dograph(p){
                //paramater object is passed and it's name is "p"
                d3.select(elementid).selectAll("svg")[0][0]["p"] = p
                //at some point update function gets called as part of an event and p is no longer available. 

                //someSvgElement
                        .on("mouseover"){update())}

                function update(source) {
                    var p = d3.select(elementid).selectAll("svg")[0][0]["p"];
                    //stuff happens
                }
            }

Pourrait ne pas être la solution parfaite mais cela fonctionne pour moi.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top