gpt4 book ai didi

javascript - 力模拟为新节点生成 NaN 坐标

转载 作者:行者123 更新时间:2023-11-30 11:25:15 26 4
gpt4 key购买 nike

我是 D3.js 框架的新手,正在寻求帮助。我正在尝试使用简单的力模拟来绘制网络。我希望每秒添加一个新节点并加入模拟。

下面是我的尝试。我用两个节点启动 sim,它们运行良好。但是,当我添加第三个节点时,模拟会为其 x 和 y 坐标分配 NaN 值。

HTML:

<head>
<script src="https://d3js.org/d3.v4.js"></script>
</head>
<body>
<svg width="300" height="300"></svg>
</body>

Javascript:

const svg = d3.select('svg');
const height = +svg.attr('height');
const width = +svg.attr('width');

// Test Data
const nodes = [ {}, {} ];

setTimeout(() => {
nodes.push({});
redraw();
}, 2000);

const ticked = () => {
svg.selectAll('g.node')
.attr('transform', d => {
if (isNaN(d.x) || isNaN(d.y)) {
console.error('nan!!!');
d.x = 50;
d.y = 50;
}

return `translate(${d.x},${d.y})`;
});
};

const simulation = d3.forceSimulation()
.force('repulsion', d3.forceManyBody().strength(-30))
.force('pin_y_to_center', d3.forceY().y(d => height / 2).strength(0.1))
.force('pin_x_to_center', d3.forceX().x(d => width / 2).strength(0.1));

simulation.nodes(nodes);
simulation.on('tick', ticked);

const redraw = () => {
const node = svg
.selectAll('.node')
.data(nodes)
.enter().append('g');

node.attr('class', 'node')
.append('circle')
.attr('r', 5);
};

redraw();

最佳答案

你必须将数组传递给模拟...

simulation.nodes(nodes);

... 在 redraw 函数中。

这是您的代码,仅进行了更改:

const svg = d3.select('svg');
const height = +svg.attr('height');
const width = +svg.attr('width');

// Test Data
const nodes = [{}, {}];

setTimeout(() => {
nodes.push({});
redraw();
}, 2000);

const ticked = () => {
svg.selectAll('g.node')
.attr('transform', d => {
if (isNaN(d.x) || isNaN(d.y)) {
console.error('nan!!!');
d.x = 50;
d.y = 50;
}

return `translate(${d.x},${d.y})`;
});
};

const simulation = d3.forceSimulation()
.force('repulsion', d3.forceManyBody().strength(-30))
.force('pin_y_to_center', d3.forceY().y(d => height / 2).strength(0.1))
.force('pin_x_to_center', d3.forceX().x(d => width / 2).strength(0.1));

simulation.on('tick', ticked);

const redraw = () => {
simulation.nodes(nodes);
const node = svg
.selectAll('.node')
.data(nodes)
.enter().append('g');

node.attr('class', 'node')
.append('circle')
.attr('r', 5);
};

redraw();
<script src="https://d3js.org/d3.v4.js"></script>
<svg width="300" height="300"></svg>

此外,考虑在添加新节点后重新加热模拟。

关于javascript - 力模拟为新节点生成 NaN 坐标,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48301978/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com