2017-02-18 2 views
1

Nach diesem example, warum ist Drag-Event-Triggerung auf die Polygone im folgenden Code nicht? Warum löst das Voronoi-Polygon-Drag-Ereignis d3 nicht auf Polygone in der Kraftsimulation aus?

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>

Ist es wegen der Update-Funktion? Ich habe es versucht, ohne die Kreise in g Elemente verschachtelt und es funktioniert immer noch nicht. Ich vermute, es liegt an Scoping, aber ich verstehe nicht, warum es im Beispiel funktioniert, aber nicht hier. (Auch nicht sicher, warum der Knoten in der Tick-Funktion wieder zu binden scheint).

Ziel ist es, mit d3 voronoi und force simulation die Knoten zum Ziehen, Tooltips, MouseOvers und anderen Ereignissen einfach anzusteuern und Knoten (und Links) dynamisch zu aktualisieren.

Antwort

1

warum ziehen nicht Ereignistriggerung auf den Polygonen

Die Drag-Ereignis in der bl.ock passiert, weil der Füllung als Beispiel verwendet haben. Wenn Sie in Ihren Polygonen die Füllung auf none ändern, werden die Ziehereignisse nur ausgelöst, wenn Sie auf den Umriss klicken.

Wenn Sie none als Füllung zu halten für Ihre Polygone diese Zeile in Ihrem CSS:

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