如何通过半径大小将节点放置在中心?

问题描述 投票:1回答:1

我想通过圆的大小将力指向图表中的节点居中:我们希望最大的圆居中,周围的第二大圆为中心。

这里是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个回答
0
投票

如果您停止想在数学和视觉上都变得很复杂,因为如果最大的圆在圆心附近,并且到圆心的距离与圆的直径成正比,那么您将有很多空白中心附近有空格,并且模拟无法很好地处理它。

但是,仅是为了尝试,这是一种可能的解决方案:抛开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/

© www.soinside.com 2019 - 2024. All rights reserved.