问题描述
我有一个力导向图,其中每个节点都是一个组,并在其中包含一个ForeignObject和一个img。 x和y coordiantes应用于img标签,但我希望将它们放在foreignObject或g上。我不确定如何实现。
I have a force directed graph where each node is a group and contains a foreignObject and an img inside it. x and y coordiantes are applied to the img tag but I would like to have them on the foreignObject or g. I am not sure how this can be achieved.
我尝试将x和y坐标设置为foreignObject,但是它们始终以NaN的形式返回。
I tried setting x and y coordinates to the foreignObject but they are always returned as NaN.
const plot = (data) => {
data.nodes = data.nodes.map((d, index) => {
d['id'] = index;
return d;
});
const margin = {
top: 20,
right: 20,
bottom: 10,
left: 100
};
const width = Math.max((((window.innerWidth / 100) * 80) - margin.right - margin.left), 700);
const height = ((window.innerHeight / 100) * 80) - margin.bottom - margin.top;
const svg = d3.select('svg')
.attr('width', width + margin.left + margin.right + 100)
.attr('height', height + margin.top + margin.bottom + 100)
.append('g')
.attr('transform',
`translate(${margin.left}, ${margin.top})`);
const simulation = d3.forceSimulation()
.force('link', d3.forceLink().id(function (d) { return d.id; }).distance(100).strength(1))
.force('charge', d3.forceManyBody())
.force('center', d3.forceCenter(width / 2, height / 2));
const dragstarted = d => {
if (!d3.event.active) simulation.alphaTarget(0.3).restart();
d.fx = d.x;
d.fy = d.y;
}
const dragged = d => {
d.fx = d3.event.x;
d.fy = d3.event.y;
}
const dragended = d => {
if (!d3.event.active) simulation.alphaTarget(0);
d.fx = null;
d.fy = null;
}
const ticked = () => {
link
.attr("x1", d => d.source.x)
.attr("y1", d => d.source.y)
.attr("x2", d => d.target.x)
.attr("y2", d => d.target.y);
node
.attr("x", function (d) { return d.x = Math.max(5, Math.min(width - 5, d.x)); })
.attr("y", function (d) { return d.y = Math.max(5, Math.min(height - 5, d.y)); });
}
const link = svg.append('g')
.attr('class', 'links')
.selectAll('line')
.data(data.links)
.enter().append('line')
.attr('stroke-width', function (d) { return Math.sqrt(d.value); });
const node = svg.append('g')
.attr('class', 'nodes')
.selectAll('.node-group')
.data(data.nodes)
.enter()
.append('g')
.append('foreignObject')
.attr('class', 'node-group')
.attr('width', '10')
.attr('height', '10')
.insert('xhtml:img')
.attr('src', 'flags/blank.png')
.attr('class', d => `flag flag-${d.code}`)
.call(d3.drag()
.on('start', dragstarted)
.on('drag', dragged)
.on('end', dragended));
node.append("title")
.text(function (d) { return d.country; })
.exit();
simulation
.nodes(data.nodes)
.on("tick", ticked);
simulation.force("link")
.links(data.links);
}
推荐答案
如果看看您的节点
选择...
If you look at your node
selection...
const node = svg.append('g')
.attr('class', 'nodes')
.selectAll('.node-group')
.data(data.nodes)
.enter()
.append('g')
.append('foreignObject')
.attr('class', 'node-group')
.attr('width', '10')
.attr('height', '10')
.insert('xhtml:img')
.attr('src', 'flags/blank.png')
.attr('class', d => `flag flag-${d.code}`)
.call(d3.drag()
.on('start', dragstarted)
.on('drag', dragged)
.on('end', dragended));
...您会看到它是带有图像的选择
s。由于您要将 x
和 y
属性应用于 foreignObject
,只需将其破坏即可:
... you'll see that it is a selection with the image
s. Since you want to apply the x
and y
properties to the foreignObject
, just break it:
const node = svg.append('g')
.attr('class', 'nodes')
.selectAll('.node-group')
.data(data.nodes)
.enter()
.append('g')
.append('foreignObject')
.attr('class', 'node-group')
.attr('width', '10')
.attr('height', '10');
node.insert('xhtml:img')
.attr('src', 'flags/blank.png')
.attr('class', d => `flag flag-${d.code}`)
.call(d3.drag()
.on('start', dragstarted)
.on('drag', dragged)
.on('end', dragended));
这样, node
是 foreignObjects
。
这篇关于D3 x和y坐标应用于最后出现的元素而不是组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!