【问题标题】:How to position a node in the center by radius size?如何通过半径大小将节点定位在中心?
【发布时间】:2020-02-04 09:17:35
【问题描述】:

我想根据圆的大小在力导向图中将节点居中:我们希望最大的圆居中,下一个最大的圆围绕它。

这里是 JSFiddle:https://jsfiddle.net/5zrxgteh/1/

这里是模拟和刻度函数:

 var simulation = d3.forceSimulation()
            .force("center", d3.forceCenter().x(width / 2).y(height / 2))
            .force("charge", d3.forceManyBody().strength(5))
            .force("collide", d3.forceCollide().strength(1).radius(function (d) {
                return rScale(d.value * 1.2);
            }).iterations(3));

 simulation
            .nodes(data)
            .on("tick", function (d) {
                elemEnter.selectAll(".pulse")
                    .attr("cx", function (d) {
                        return d.x = Math.max(50, Math.min(width - 50, d.x));
                    })
                    .attr("cy", function (d) {
                        return d.y = Math.max(50, Math.min(height - 50, d.y));
                    });

                elemEnter.selectAll(".circle")
                    .attr("cx", function (d) {
                        return d.x = Math.max(50, Math.min(width - 50, d.x));
                    })
                    .attr("cy", function (d) {
                        return d.y = Math.max(50, Math.min(height - 50, d.y));
                    });

                elemEnter.selectAll("text")
                    .attr("x", function (d) {
                        return d.x = Math.max(50, Math.min(width - 50, d.x));
                    })
                    .attr("y", function (d) {
                        return d.y = Math.max(50, Math.min(height - 50, d.y));
                    });
            });

【问题讨论】:

    标签: javascript d3.js force-layout


    【解决方案1】:

    如果你停下来认为你想要的东西在数学和视觉上都很复杂,因为如果最大的圆靠近中心并且到中心的距离与圆的直径成正比,那么你会有很多中心旁边的空白区域,模拟不会很好地处理它。

    但是,只是为了尝试,这是一个可能的解决方案:放弃d3.forceCenter 并改用forceXforceY,根据圈子的大小调整它们的强度。

    为此,我们首先设置了一个比例:

    var strengthScale = d3.scalePow()
        .exponent(2)
        .range([0, 1])
        .domain([0, d3.max(data, function(d) {
            return d.value;
        })]);
    

    然后,我们改变模拟:

    var simulation = d3.forceSimulation()
        .force("x", d3.forceX(width / 2).strength(function(d) {
          return strengthScale(d.value);
        }))
        .force("y", d3.forceY(height / 2).strength(function(d) {
          return strengthScale(d.value);
        }))
        .force("charge", d3.forceManyBody().strength(5))
        .force("collide", d3.forceCollide().strength(1).radius(function(d) {
          return rScale(d.value * 1.2);
        }).iterations(30));
    

    这是生成的 JSFiddle:https://jsfiddle.net/mea9nygb/2/

    【讨论】:

    • 非常感谢。多亏了你,我才知道如何处理它。我什至无法尝试访问它,它确实对我帮助很大。
    猜你喜欢
    • 2010-09-16
    • 2016-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-24
    • 2013-12-05
    • 1970-01-01
    相关资源
    最近更新 更多