d3.js力导向图球形

3
我修改了Christopher Manning在球体上的力导向图。 我希望该图会缓慢停下来,然后旋转球体而不更改图中点之间的关系。 然而,当我拖动时,似乎是拖动了图形,而不是旋转球体。 拖动图形会启动力引导开始。 如果我关闭force.start(),也没有任何变化。
var svg = d3.select("#cluster").append("svg")
    .attr("width", width)
    .attr("height", height)
    .call(d3.behavior.drag()
      .origin(function() { var r = projection.rotate(); return {x: 2 * r[0], y: -2 * r[1]}; })
      .on("drag", function() { force.start(); var r = [d3.event.x / 2, -d3.event.y / 2, projection.rotate()[2]]; t0 = Date.now(); origin = r; projection.rotate(r); }))

我从http://bl.ocks.org/mbostock/3795040发现,我可以旋转网格线,但这样一来所有的链接和节点都消失了。

var path = d3.geo.path()
    .projection(projection);

var λ = d3.scale.linear()
    .domain([0, width])
    .range([-180, 180]);

var φ = d3.scale.linear()
    .domain([0, height])
    .range([90, -90]);

var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height);

svg.on("mousemove", function() {
  var p = d3.mouse(this);
  projection.rotate([λ(p[0]), φ(p[1])]);
  svg.selectAll("path").attr("d", path);
});

链接和节点可以像这样添加:
  var link = svg.selectAll("path.link")
      .data(graph.links)
      .enter().append("path").attr("class", "link")
      .attr ("stroke-width", function(d){return d.value/3});

  var node = svg.selectAll("path.node")
      .data(graph.nodes)
      .enter()
      .append("g")
      .attr("class", "gnode")
      .attr("text-anchor", "middle")

      .append("path").attr("class", "node")
      .style("fill", function(d) { return d.color; })
      .style("stroke", function(d) { return d3.rgb(fill(d.group)).darker(); })

我希望实现的目标是:当图形定位到位置后,我想使用拖动手势来旋转球体及其上的节点和链接。
我该如何实现这个目标?
2个回答

2

这可以通过调整在第一个片段中定义的svg上注册的drag事件处理程序来完成。 这需要两个编辑:

  1. 去掉 force.start(),因为您不想在拖动时重新启动力导向。
  2. 在投影更新后触发节点和链接的渲染,这可以通过调用tick()轻松完成。 如果步骤1中未禁用力,则会重复调用此函数,因为该函数被注册为力布局的tick事件的处理程序。 现在,您已禁用了力,必须明确调用它。

重新格式化的代码如下:

.on("drag", function() { 
  //force.start();     // 1. Don't restart the force.
  var r = [d3.event.x / 2, -d3.event.y / 2, projection.rotate()[2]];
  t0 = Date.now();
  origin = r;
  projection.rotate(r);
  tick();              // 2. Trigger the rendering after adjusting the projection.
}))

请看这个可工作的示例


谢谢,这个例子正是我需要的。我快速尝试了一下你的建议,但并没有解决问题,不过这个例子明显可行。我会再仔细研究一下,相信能够解决我的问题。谢谢。 - user1430965
非常有效,需要在你的例子中包含tick函数。 再次感谢! - user1430965

0

这可能会沿一个轴旋转

var rotateScale = d3.scale.linear().domain([0, width]).range([-180,180]);//width of  SVG

d3.select("svg").on("mousedown",startRotating).on("mouseup",stopRotating);

function startRotating() {
   d3.select("svg").on("mousemove",function() {
      var p = d3.mouse(this);
      projection.rotate([rotateScale(p[0]),0]);
   });
}
function stopRotating() {
   d3.select("svg").on("mousemove",null);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接