gpt4 book ai didi

javascript - 如何让特定的 d3 Node 成为力导向图中的图像?

转载 作者:行者123 更新时间:2023-11-29 23:59:55 25 4
gpt4 key购买 nike

我制作了一个与此类似的力导向图。 note this is a random example from the internet

我希望中心的九寸钉 Node 是一个图像,而其余 Node 只是圆圈。按照这个 answer它似乎并不太难,但我就是无法理解 svg、defs、patterns 和 d3 的组合。

我的代码是:

      var simulation =
d3.forceSimulation()
.force("charge", d3.forceManyBody().strength(-50))
.force("collide", d3.forceCollide().radius(function (d) { return 15 - d.group}).strength(2).iterations(2))
.force("link", d3.forceLink().id(function(d, i) { return i;}).distance(20).strength(0.9))
.force("center", d3.forceCenter(width/2, height/2))
.force('X', d3.forceX(width/2).strength(0.15))
.force('Y', d3.forceY(height/2).strength(0.15));

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

var defs = svg.append('svg:defs');

defs.append("svg:pattern")
.attr("id", "vit-icon")
.attr("width", 48)
.attr("height", 48)
.attr("patternUnits", "userSpaceOnUse")
.append("svg:image")
.attr("xlink:href", "http://placekitten.com/g/48/48")
.attr("width", 48)
.attr("height", 48)
.attr("x", width/2)
.attr("y", height/2)

var node = svg.append("g")
.attr("class", "nodes")
.selectAll("circle")
.data(graph.nodes)
.enter().append("circle")
.attr("id", function(d, i) { return 'c'+i})
.attr("r", radius)
.attr("fill", function(d) {
if(d.group==0) {return "url(#vit-icon)";}
else {return color(d.group); }
})
.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended));

正如我所说,在我看来这似乎是直截了当的。基本上我想我要做的是让图像采用 svg 模式,然后使用 if 语句告诉我的根 Node 使用图像 url 而不是填充颜色。

在开发工具中,我可以看到检查图像,它显示它将占用的蓝色区域以及我希望它关联到的 Node 具有“url(#vit-icon)”作为它的填充属性。但它没有显示该 Node 的图像或任何填充。

我做错了什么?或者这是完全错误的方法?谢谢。

最佳答案

在您的 defs 中,只需更改:

.attr("x", width/2)
.attr("y", height/2)

收件人:

.attr("x", 0)
.attr("y", 0);

这是一个演示:

var nodes = [{
"id": 1,
}, {
"id": 2,
}, {
"id": 3,
}, {
"id": 4,
}, {
"id": 5,
}, {
"id": 6,
}, {
"id": 7,
}, {
"id": 8,
}];

var links = [{
source: 1,
target: 2
}, {
source: 1,
target: 3
}, {
source: 1,
target: 4
}, {
source: 2,
target: 5
}, {
source: 2,
target: 6
}, {
source: 1,
target: 7
}, {
source: 7,
target: 8
}];

var index = 10;
var svg = d3.select("svg"),
width = +svg.attr("width"),
height = +svg.attr("height"),
node,
link;

var defs = svg.append('svg:defs');

defs.append("svg:pattern")
.attr("id", "vit-icon")
.attr("width", 1)
.attr("height", 1)
.append("svg:image")
.attr("xlink:href", "http://66.media.tumblr.com/avatar_1c725152c551_128.png")
.attr("width", 48)
.attr("height", 48)
.attr("x", 0)
.attr("y", 0);

var simulation = d3.forceSimulation()
.force("link", d3.forceLink().id(function(d) {
return d.id;
}).distance(100))
.force("collide", d3.forceCollide(50))
.force("charge", d3.forceManyBody())
.force("center", d3.forceCenter(width / 2, height / 2));

link = svg.selectAll(".link")
.data(links, function(d) {
return d.target.id;
})

link = link.enter()
.append("line")
.attr("class", "link");

node = svg.selectAll(".node")
.data(nodes, function(d) {
return d.id;
})

node = node.enter()
.append("g")
.attr("class", "node")
.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended));

node.append("circle")
.attr("r", d=> d.id === 1 ? 24 : 14)
.style("fill", function(d) {
if (d.id === 1) {
return "url(#vit-icon)";
} else {
return "teal"
}
})

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("transform", function(d) {
return "translate(" + d.x + ", " + d.y + ")";
});
}

function dragstarted(d) {
if (!d3.event.active) simulation.alphaTarget(0.3).restart()
}

function dragged(d) {
d.fx = d3.event.x;
d.fy = d3.event.y;
}

function dragended(d) {
if (!d3.event.active) simulation.alphaTarget(0);
d.fx = undefined;
d.fy = undefined;
}
.link {
stroke: #aaa;
}

.node {
pointer-events: all;
stroke: none;
stroke-width: 40px;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width="500" height="300"></svg>

关于javascript - 如何让特定的 d3 Node 成为力导向图中的图像?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40856799/

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