2017-02-18 42 views
1

繼此example之後,爲什麼不在以下代碼中的多邊形上進行拖動事件觸發?爲什麼不能在多邊形逼真模擬中觸發d3 voronoi多邊形拖動事件?

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>

是因爲更新的功能? 我試過它沒有嵌套在g元素中的圓圈,它仍然不起作用。我猜這是因爲範圍限制,但不明白爲什麼它在示例中有效,但不在這裏。 (另外,不知道爲什麼節點似乎需要在tick函數中再次綁定)。

目標是使用d3 voronoi和力仿真來輕鬆地定位節點以進行拖動,工具提示,鼠標懸停和其他事件以及動態更新節點(和鏈接)。

回答

1

爲什麼不拖累多邊形中你作爲你的榜樣,因爲填充的bl.ock

拖拽事件發生事件觸發。通過將多邊形上的填充更改爲none,僅當您單擊輪廓時纔會觸發拖動事件

如果你想保持none作爲個夠您的多邊形在你的CSS使用這行:

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