我试图在强制布局中使用图像作为节点,但我不知道如何指定图像的x,y位置:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>D3: Force layout</title>
<script src="https://d3js.org/d3.v4.min.js"></script>
<style type="text/css">
/* No style rules here yet */
</style>
</head>
<body>
<script type="text/javascript">
//Width and height
var w = 500;
var h = 300;
//Original data
var dataset = {
nodes: [{
name: "Adam"
},
{
name: "Bob"
},
{
name: "Carrie"
},
{
name: "Donovan"
},
{
name: "Edward"
}
],
edges: [{
source: 0,
target: 1
},
{
source: 0,
target: 2
},
{
source: 0,
target: 3
},
{
source: 0,
target: 4
},
{
source: 1,
target: 2
},
{
source: 2,
target: 3
},
{
source: 1,
target: 4
}
]
};
//Initialize a simple force layout, using the nodes and edges in dataset
var force = d3.forceSimulation(dataset.nodes)
.force("charge", d3.forceManyBody())
.force("link", d3.forceLink(dataset.edges))
.force("center", d3.forceCenter().x(w / 2).y(h / 2));
var colors = d3.scaleOrdinal(d3.schemeCategory10);
//Create SVG element
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
//Create edges as lines
var edges = svg.selectAll("line")
.data(dataset.edges)
.enter()
.append("line")
.style("stroke", "#ccc")
.style("stroke-width", 1);
//Create nodes as circles
var nodes = svg.selectAll("circle")
.data(dataset.nodes)
.enter()
.append("svg:image")
.attr('x', function(d) {
return d.x;
})
.attr('y', function(d) {
return d.y;
})
.attr('width', 15)
.attr('height', 15)
.attr("xlink:href", "https://github.com/favicon.ico");
//Every time the simulation "ticks", this will be called
force.on("tick", function() {
edges.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;
});
nodes.attr("cx", function(d) {
return d.x;
})
.attr("cy", function(d) {
return d.y;
});
});
</script>
</body>
</html>
&#13;
如果节点是圆形的并且图像是方形的,我如何找到所有节点的坐标,并让节点剪切图像?
如果数据是json格式,每个节点都有自己的图像,我怎样才能将图像名称推送到原始数据?感谢。
答案 0 :(得分:2)
您要追加<image>
个元素,而不是圈子(您使用selectAll("circle")
的事实没有区别)。因此,您应该在x
函数中使用y
和tick
。除此之外,你应该将图像移动宽度/高度的一半:
nodes.attr("x", function(d) { return d.x - 8; })
.attr("y", function(d) { return d.y - 8; });
以下是更新后的代码:
var w = 500;
var h = 300;
//Original data
var dataset = {
nodes: [{
name: "Adam"
},
{
name: "Bob"
},
{
name: "Carrie"
},
{
name: "Donovan"
},
{
name: "Edward"
}
],
edges: [{
source: 0,
target: 1
},
{
source: 0,
target: 2
},
{
source: 0,
target: 3
},
{
source: 0,
target: 4
},
{
source: 1,
target: 2
},
{
source: 2,
target: 3
},
{
source: 1,
target: 4
}
]
};
//Initialize a simple force layout, using the nodes and edges in dataset
var force = d3.forceSimulation(dataset.nodes)
.force("charge", d3.forceManyBody())
.force("link", d3.forceLink(dataset.edges))
.force("center", d3.forceCenter().x(w / 2).y(h / 2));
var colors = d3.scaleOrdinal(d3.schemeCategory10);
//Create SVG element
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
//Create edges as lines
var edges = svg.selectAll("line")
.data(dataset.edges)
.enter()
.append("line")
.style("stroke", "#ccc")
.style("stroke-width", 1);
//Create nodes as circles
var nodes = svg.selectAll("circle")
.data(dataset.nodes)
.enter()
.append("svg:image")
.attr('width', 16)
.attr('height', 16)
.attr("xlink:href", "https://github.com/favicon.ico");
//Every time the simulation "ticks", this will be called
force.on("tick", function() {
edges.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;
});
nodes.attr("x", function(d) {
return d.x - 8;
})
.attr("y", function(d) {
return d.y - 8;
});
});
<script src="https://d3js.org/d3.v4.min.js"></script>
另外,请注意您的节点现在不是圆形,并且没有剪裁图像。如果您想要附加图片和圈子,就像看起来一样,您可以尝试不同的方法,例如:Making D3 like Force-Directed Graph with PNGs