我有一个共享国界的国家强制指导图。我想在每个节点上显示国家的标志。我可以在生成的HTML中看到图像,也可以看到它占据了窗口中的空间,但它不可见。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="flags/flags.css">
<link rel="stylesheet" href="index.css">
<title>National Contiguity Visualization</title>
</head>
<body>
<div class="details">National Contiguity</div>
<svg class="plot"></svg>
<div class="tooltip hidden"></div>
<svg width="100" height="100">
<foreignobject class="node" >
<img class="flag flag-cz" alt="Czech Republic" src="flags/blank.png"/>
</foreignobject>
</svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="index.js"></script>
</body>
</html>
这是JS文件。
const apiUrl = 'https://raw.githubusercontent.com/DealPete/forceDirected/master/countries.json';
const tooltip = document.getElementsByClassName('tooltip')[0];
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 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('.flag')
.data(data.nodes)
.enter()
.append('foreignobject')
.append('img')
.attr('src', 'flags/blank.png')
.attr('class', d => `flag flag-cz`)
.attr('width', '5px')
.attr('height', '5px')
.attr("x", -8)
.attr("y", -8)
.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);
}
const fetchData = () => {
return fetch(apiUrl)
.then(response => {
return response.json();
});
};
const fetchAndPlot = async () => {
try {
const response = await fetchData();
console.log(response);
plot(response);
} catch (e) {
console.error(e);
}
}
fetchAndPlot();
尝试了svg图像元素和foreignobject方法。直接用HTML编写的那个是正确呈现的。在过去的3/4天内无法弄清楚这个问题。
回购:National Contiguity Visualization
提前致谢。
答案 0 :(得分:1)
由于您没有提供标记,我使用了示例标记。请注意,目前您的所有节点都是一个在另一个上面,但我想如果您无法解决这个问题,那么这就是另一个问题。
const apiUrl = 'https://raw.githubusercontent.com/DealPete/forceDirected/master/countries.json';
const tooltip = document.getElementsByClassName('tooltip')[0];
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 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('.flag')
.data(data.nodes)
.enter()
.append('foreignObject')
.attr('width', '100')
.attr('height', '100')
.append('xhtml:img')
.attr('src', 'https://flaglane.com/download/british-flag/british-flag-small.gif')
.attr('class', d => `flag flag-cz`)
.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);
}
const fetchData = () => {
return fetch(apiUrl)
.then(response => {
return response.json();
});
};
const fetchAndPlot = async () => {
try {
const response = await fetchData();
plot(response);
} catch (e) {
console.error(e);
}
}
fetchAndPlot();
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="flags/flags.css">
<link rel="stylesheet" href="index.css">
<title>National Contiguity Visualization</title>
</head>
<body>
<div class="details">National Contiguity</div>
<svg class="plot"></svg>
<div class="tooltip hidden"></div>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="index.js"></script>
</body>
</html>
&#13;