【问题标题】:Why isn't the d3 voronoi polygon drag event triggering on polygons in force simulation?为什么 d3 voronoi 多边形拖动事件不会在力模拟中触发多边形?
【发布时间】:2017-07-08 06:00:18
【问题描述】:

按照example,为什么下面代码中的多边形没有触发拖动事件?

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)
	.force("charge", d3.forceManyBody())
	.force("center", d3.forceCenter(width / 2, height / 2))
	.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()
	.x(function(d) { return d.x; })
	.y(function(d) { return d.y; })
	.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()
  	.append("g")
  	.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() {
	var node = nodes.selectAll("g");
  var diagram = voronoi(node.data()).polygons();
	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 和强制模拟轻松定位节点以进行拖动、工具提示、鼠标悬停和其他事件,并动态更新节点(和链接)。

【问题讨论】:

    标签: d3.js polygon drag force-layout voronoi


    【解决方案1】:

    为什么多边形上没有触发拖动事件

    由于填充,拖动事件发生在您用作示例的块中。通过将多边形上的填充更改为none,拖动事件只会在您单击轮廓时触发

    如果您想保留none 作为多边形的填充,请在您的 css 中使用此行:

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

    【讨论】:

      猜你喜欢
      • 2017-07-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-11
      • 1970-01-01
      • 2016-04-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多