2017-02-18 2 views
1

Suite à ce example, pourquoi ne pas faire glisser l'événement de déclenchement sur les polygones dans le code suivant?Pourquoi l'événement de déplacement de polygone d3 voronoi n'est-il pas déclenché sur des polygones en simulation de force?

var data = [ 
 
    { 
 
    "index" : 0, 
 
     "vx" : 0, 
 
     "vy" : 0, 
 
      "x" : 842, 
 
      "y" : 106 
 
    }, 
 
    { 
 
     "index" : 1, 
 
     "vx" : 0, 
 
      "vy" : 0, 
 
      "x" : 839, 
 
       "y" : 56 
 
    }, 
 
    { 
 
     "index" : 2, 
 
      "vx" : 0, 
 
      "vy" : 0, 
 
       "x" : 771, 
 
       "y" : 72 
 
     } 
 
] 
 

 
var svg = d3.select("svg"), 
 
    width = +svg.attr("width"), 
 
    height = +svg.attr("height"); 
 
    
 
var simulation = d3.forceSimulation(data) 
 
\t .force("charge", d3.forceManyBody()) 
 
\t .force("center", d3.forceCenter(width/2, height/2)) 
 
\t .on("tick", ticked); 
 
    
 
var nodes = svg.append("g").attr("class", "nodes"), 
 
    node = nodes.selectAll("g"), 
 
    polygons = svg.append("g").attr("class", "polygons"), 
 
    polygon = polygons.selectAll("polygon"); 
 

 
var voronoi = d3.voronoi() 
 
\t .x(function(d) { return d.x; }) 
 
\t .y(function(d) { return d.y; }) 
 
\t .extent([[0, 0], [width, height]]); 
 
    
 
var update = function() { 
 

 
    polygon = polygons.selectAll("polygon") 
 
    .data(data).enter() 
 
    .append("polygon") 
 
    .call(d3.drag() 
 
       .on("start", dragstarted) 
 
       .on("drag", dragged) 
 
       .on("end", dragended)); 
 

 
    node = nodes.selectAll("g").data(data); 
 
    var nodeEnter = node.enter() 
 
    \t .append("g") 
 
    \t .attr("class", "node"); 
 
    nodeEnter.append("circle"); 
 
    nodeEnter.append("text") 
 
    .text(function(d, i) { return i; }) 
 
    .style("display", "none"); 
 
    node.merge(nodeEnter); 
 
    
 
    
 
    simulation.nodes(data); 
 
    simulation.restart(); 
 

 
}(); 
 
    
 
function ticked() { 
 
\t var node = nodes.selectAll("g"); 
 
    var diagram = voronoi(node.data()).polygons(); 
 
\t polygon = polygons.selectAll("polygon"); 
 
    
 
    node.call(d3.drag() 
 
    .on("start", dragstarted) 
 
    .on("drag", dragged) 
 
    .on("end", dragended)); 
 
    
 
    polygon 
 
    .attr("points", function(d, i) { return diagram[i]; }); 
 
    
 
    polygon.call(d3.drag() 
 
       .on("start", dragstarted) 
 
       .on("drag", function(d) { console.log("drag"); }) 
 
       .on("end", dragended)); 
 
    node 
 
    .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")" }); 
 
} 
 

 
function dragstarted(d) { 
 
    if (!d3.event.active) simulation.alphaTarget(0.3).restart(); 
 
    d.fx = d.x; 
 
    d.fy = d.y; 
 
} 
 

 
function dragged(d) { 
 
    d.fx = d3.event.x; 
 
    d.fy = d3.event.y; 
 
} 
 

 
function dragended(d) { 
 
    if (!d3.event.active) simulation.alphaTarget(0); 
 
    d.fx = null; 
 
    d.fy = null; 
 
}
svg { 
 
    border: 1px solid #888888; 
 
} 
 

 
circle { 
 
    r: 3; 
 
    cursor: move; 
 
    fill: black; 
 
} 
 

 
.node { 
 
    pointer-events: all; 
 
} 
 

 
.polygons { 
 
    fill: none; 
 
    stroke: #999; 
 
} 
 

 
text { 
 
    display: none; 
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.5.1/d3.min.js"></script> 
 
<svg width="400" height="200"></svg>

Est-ce à cause de la fonction de mise à jour? Je l'ai essayé sans les cercles imbriqués dans les éléments g et cela ne fonctionne toujours pas. Je suppose que c'est à cause de la portée, mais je ne vois pas encore pourquoi cela fonctionne dans l'exemple mais pas ici. (De plus, je ne sais pas pourquoi le nœud semble avoir besoin de se lier à nouveau dans la fonction de graduation). L'objectif est d'utiliser d3 voronoi et la simulation de force pour cibler facilement les nœuds pour le glisser, les info-bulles, les survols et autres événements, et mettre à jour les nœuds (et les liens) dynamiquement.

Répondre

1

pourquoi est l'événement traîne pas le déclenchement sur les polygones

L'événement de traînée se produit dans le bl.ock que vous avez utilisé comme exemple à cause du remplissage. En remplaçant le remplissage par none sur vos polygones, les événements de glissement ne se déclenchent que lorsque vous cliquez sur le contour.

Si vous voulez garder none que votre remplissage pour vos polygones utilisent cette ligne dans votre code CSS:

.polygon { 
    fill: none; 
    pointer-events: all; 
    ...