我有一个D3力导向图。
我希望能够缩放和平移图形(使用当前代码),但也可以将鼠标悬停在元素上(不起作用,因为用于捕获缩放/平移的rect
覆盖了{ {1}}应该接受circles
。如何支持这两种功能?
mouseover
答案 0 :(得分:0)
正如@ rioV8提到的,您要做的就是将缩放应用于SVG。非常简单。
以下是完整的代码,以防有人感兴趣:
css
.links line {
stroke: #999;
stroke-opacity: 0.6;
}
.nodes circle {
stroke: #fff;
stroke-width: 1.5px;
cursor: pointer;
}
.tooltip {
position: absolute;
text-align: center;
padding: 2px;
font: 15px sans-serif;
background: lightsteelblue;
border: 0px;
border-radius: 8px;
pointer-events: none;
}
javascript
const {
nodes,
links
} = await this.getData();
console.log(nodes)
console.log(links.map(({
source,
target
}) => source + '->' + target).join('\n'))
const svg = select('svg');
const width = +svg.attr("width");
const height = +svg.attr("height");
// Define the div for the tooltip
var tooltip = select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
const g = svg.append("g")
.attr('width', width)
.attr('height', height)
const zoomHandler = zoom()
.scaleExtent([1 / 2, 10])
.on("zoom", () => g.attr("transform", event.transform));
zoomHandler(svg);
const simulation = forceSimulation(nodes)
.force("link", forceLink(links).id(d => d.id))
.force("charge", forceManyBody())
.force("center", forceCenter(width / 2, height / 2))
.on("tick", ticked);
const link = g.append("g")
.attr("stroke", "#999")
.attr("stroke-opacity", 0.6)
.selectAll("line")
.data(links)
.enter().append("line")
.attr("stroke-width", d => d.value);
const node = g.append("g")
.attr("stroke", "#fff")
.attr("stroke-width", 1.5)
.selectAll("circle")
.data(nodes)
.enter()
.append("circle")
.attr("r", 5)
.attr("fill", (d) => d.group === 1 ? '#ff0000' : '#0000ff')
.on("mouseover", function (d) {
tooltip.transition()
.duration(100)
.style("opacity", .9);
tooltip.html(d.id)
.style("left", (event.pageX) + "px")
.style("top", (event.pageY - 28) + "px");
})
.on("mouseout", function (d) {
tooltip.transition()
.duration(100)
.style("opacity", 0);
})
.call(drag(simulation))
function 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("cx", d => d.x)
.attr("cy", d => d.y);
}