D3 forceRadial() 嵌套数据以父为中心

D3 forceRadial() with nested data centered around parent

我试图让 d3.forceRadial() 围绕它们各自的父级分层分布节点,但是当我在力上设置 x 和 y 参数时,所有节点都向右下角发射,并且超出以万为单位的 x 和 y 值..

我的代码如下所示:

let simulation = d3.forceSimulation()
    .force('radial', d3.forceRadial((d) => (d.distance * 100))
        .x((d) => ((d.parent && !isNaN(d.parent.x)) ? d.parent.x + d.parent.vx : 0))
        .y((d) => ((d.parent && !isNaN(d.parent.y)) ? d.parent.y + d.parent.vy : 0))
        .strength(3))
    .force('link', d3.forceLink().id((d) => (d.entity_id)).strength(0))
    .nodes(data.nodes);

其中parent是对父节点的引用,d.distance是距根节点的步数。我试过事先将所有节点的 x 和 y 设置为 0 但无济于事..

不幸的是,在当前版本(撰写本文时为 4.13.0)中,d3.forceRadial 接受 x() 的函数和 y() 方法,尽管它确实接受 radius() 方法的函数。

我们可以看到这个检查 source code

这是 radius() 的代码:

force.radius = function(_) {
    return arguments.length ? (radius = typeof _ === "function" ? _ :
        constant(+_), initialize(), force) : radius;
};

如您所见,它接受一个函数。

但这是 x()y() 的代码:

force.x = function(_) {
    return arguments.length ? (x = +_, force) : x;
};

force.y = function(_) {
    return arguments.length ? (y = +_, force) : y;
};

如您所见,它接受函数。

你也可以看到API只讲数字,不讲函数。关于radial.x

If x is specified, sets the x-coordinate of the circle center to the specified number and returns this force. (emphasis mine)

radial.y也是如此。