【问题标题】:Remove/Don't show empty node in D3 Force Layout / Force Simulation [duplicate]在 D3 Force Layout / Force Simulation 中删除/不显示空节点 [重复]
【发布时间】:2020-03-24 15:17:56
【问题描述】:

我有一个与此类似的问题:d3.js V3 force directed graph and unlinked nodes 但那里的解决方案对我没有帮助。

我的 csv 数据集有一些空的源和目标 我的 csv 看起来像这样:(抱歉这不是真实数据,因为它要大得多,但我希望这样做)

John,
,Alex
Alice,Bob
Eve,Carol
Dave,Bob
Charlie,

所以我得到的是通过“空”节点连接的 John、Alex 和 Charlie。我想要的是它们与任何其他节点没有任何连接。只是一个节点。 这是我的代码 sn-p:

var simulation = d3.forceSimulation()
        .force("link", d3.forceLink())
        .force("x", d3.forceX(width / 2).strength(0.8))
        .force("y", d3.forceY(height / 2).strength(0.8))
        .force("center", d3.forceCenter(width / 2, height / 2))
        .force("collide",d3.forceCollide().radius(d => d.r * 10))
        .force("charge", d3.forceManyBody().strength(-100));


d3.csv("myData.csv", function(error, links) {
            if (error) throw error;

            var nodesByName = {}

            links.forEach(function(link) {
                link.source = nodesByName[link.source] || (nodesByName[link.source] = {name: link.source});
                link.target = nodesByName[link.target] || (nodesByName[link.target] = {name: link.target});  
            }); 

 var nodes = d3.values(nodesByName);

            var link = svg.selectAll(".link")
            .data(links)
            .enter().append("line")
            .attr("class", "link");

            var node = svg.selectAll(".node")
            .data(nodes)
            .enter().append("circle")
            .attr("class", "node")
            .attr("r", 4.5)
            .on("mouseover", tooltipOn)
            .on("mouseout", tooltipOff)

            simulation
                .nodes(nodes)
                .on("tick", tick)
                .force("link").links(links);

function tick() {
                link.attr("x1", function(d) { return d.source.x; })
                    .attr("y1", function(d) { return d.source.y; })
                    .attr("x2", function(d) { return d.target.x; })
                    .attr("y2", function(d) { return d.target.y; });

                node.attr("cx", function(d) { return d.x; })
                    .attr("cy", function(d) { return d.y; });
            }

(我用d3.v3力布局和d3.v4力模拟试了一下,结果一样)

感谢您的帮助(如有任何错误,我们深表歉意 - 英语不是我的母语,这是我在这里的第一个问题)

【问题讨论】:

  • 链接问题的解决方案应该可以解决您的问题。你有没有尝试过?
  • 不,正如我的问题的第一行所述,我已经尝试了那里建议的解决方案
  • 您可以尝试过滤掉您不喜欢的数据吗? stackoverflow.com/questions/12922236/…
  • 您能否说明为什么其他问题不能解决您的问题,或者您如何更改代码以采用建议的解决方案?就像@Mehdi 建议的那样,我很确定这是重复的。
  • 顺便说一句,欢迎来到 stackOverflow。期望是你展示你尝试过的东西,我们从这里开始。应该关注These guidelines

标签: javascript d3.js nodes force-layout


【解决方案1】:

这个问题可以通过以下方式解决:

  • 根据源值和目标值存储节点,仅当值不是且为空字符串时
  • 仅当源和目标都不为空时才存储链接。

可以根据源和目标的存在来填充新的links 数组,而不是从已解析的 CSV 数据集中删除记录。

下面sn-p中的功能演示

let csv = 'source,target\nJohn,\n,Alex\nAlice,Bob\nEve,Carol\nDave,Bob\nCharlie,'
	, input = d3.csvParse(csv)
	, nodesByName = {}
	, links = []

input.forEach(function(link) {

	if (link.source)
    // source is not empty, record node
		nodesByName[link.source] = {name: link.source}
		
	if (link.target)
    // target is not empty, record node
		nodesByName[link.target] = {name: link.target}
		
	if (link.source && link.target)
    // both source and target are not empty, record link
		links.push({
			source: nodesByName[link.source]
			, target: nodesByName[link.target]
		})
})

console.log('-------------')
console.log('nodes')
console.log(nodesByName)

console.log('-------------')
console.log('links')
console.log(links)
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3-dsv/1.0.8/d3-dsv.min.js"></script>

【讨论】:

    猜你喜欢
    • 2013-04-27
    • 1970-01-01
    • 2018-03-10
    • 2015-05-10
    • 1970-01-01
    • 2017-02-15
    • 1970-01-01
    • 1970-01-01
    • 2020-08-07
    相关资源
    最近更新 更多