gpt4 book ai didi

javascript - 强制从分配的 SVG 大小绘制有向图

转载 作者:行者123 更新时间:2023-12-01 03:54:39 24 4
gpt4 key购买 nike

我正在尝试创建像 this 这样的力定向图。当我使用示例数据时,它画得很好。但是当我使用自己的数据时,节点似乎是超出 svg 大小的。这是我得到的: enter image description here

这是我的代码:

var nodes = createFDGNodes(stopsByLine);
var links = createFDGLinks(stopsByLine);

var simulation = d3.forceSimulation()
.force("link", d3.forceLink()
.id(function(d) { return d.id; })
)
.force("charge", d3.forceManyBody()
.distanceMin(function(d) {return 1; })
)
.force("center", d3.forceCenter(960/2, 500/2));

const circleGroup = d3.select("div.transit-network")
.append("svg")
.attr("width", 960)
.attr("height", 500)
.append("g")
.attr("class","fdg");

var color = d3.scaleOrdinal(d3.schemeCategory20);

var link = circleGroup.append("g")
.attr("class", "links")
.selectAll("line")
.data(links)
.enter().append("line")
.attr("stroke", "black")
.attr("stroke-width", 1);

var node = circleGroup.append("g")
.attr("class", "nodes")
.selectAll("circle")
.data(nodes)
.enter().append("circle")
.attr("r", 5)
.attr("class", function(d) {return "line-"+d.lineId+" stop-"+d.id;})
.attr("fill", function(d){
return color(d.lineId);
});

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

simulation.force("link")
.links(links);

function ticked() {
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; });
}

如何制作图表,使其在分配的 svg 大小内绘制?

最佳答案

使模拟适合分配区域的“正确”方法是调整模拟中的所有力,例如 forceManyBodyforceLinkforceCenter 等等...

但是,您可以强制模拟(无双关语意图)以适合给定区域。例如,在下面的演示中,在 tick 函数中使用此函数,模拟将被限制在 100 x 100 像素的小区域内:

node.attr("transform", (d) => {
return "translate(" + (d.x < 10 ? dx = 10 : d.x > 90 ? d.x = 90 : d.x) +
"," + (d.y < 10 ? d.y = 10 : d.y > 90 ? d.y = 90 : d.y) + ")"
})

这是演示:

var width = 100;
var height = 100;

var svg = d3.select("body")
.append("svg")
.attr("width", width)
.attr("height", height);

var nodes = [{
"id": "foo"
}, {
"id": "bar"
}, {
"id": "baz"
}, {
"id": "foobar"
}];

var edges = [{
"source": 0,
"target": 1
}, {
"source": 0,
"target": 2
}, {
"source": 0,
"target": 3
}];

var simulation = d3.forceSimulation()
.force("link", d3.forceLink())
.force("charge", d3.forceManyBody().strength(-1000))
.force("center", d3.forceCenter(width / 2, height / 2));

var links = svg.selectAll("foo")
.data(edges)
.enter()
.append("line")
.style("stroke", "#ccc")
.style("stroke-width", 1);

var color = d3.scaleOrdinal(d3.schemeCategory20);

var node = svg.selectAll("foo")
.data(nodes)
.enter()
.append("g");

var nodeCircle = node.append("circle")
.attr("r", 5)
.attr("stroke", "gray")
.attr("stroke-width", "2px")
.attr("fill", "white");

simulation.nodes(nodes);
simulation.force("link")
.links(edges);

simulation.on("tick", function() {

node.attr("transform", (d) => {
return "translate(" + (d.x < 10 ? dx = 10 : d.x > 90 ? d.x = 90 : d.x) + "," + (d.y < 10 ? d.y = 10 : d.y > 90 ? d.y = 90 : d.y) + ")"
})

links.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;
})


});
svg{
background-color: lemonchiffon;
}
<script src="https://d3js.org/d3.v4.min.js"></script>

关于javascript - 强制从分配的 SVG 大小绘制有向图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42872856/

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