D3.js 在D3中,我如何支持Pan&;力定向图上的缩放和鼠标悬停?

D3.js 在D3中,我如何支持Pan&;力定向图上的缩放和鼠标悬停?,d3.js,D3.js,我有一个D3力有向图 我希望能够缩放和平移图形(使用当前代码),但也可以将鼠标悬停在元素上(不起作用,因为用于捕获缩放/平移的rect覆盖了圆圈,这应该可以接受鼠标悬停。我如何支持这两种功能 const svg = select('svg'); const width = +svg.attr("width"); const height = +svg.attr("height"); var div = select("body").append("div") .attr("class"

我有一个D3力有向图

我希望能够缩放和平移图形(使用当前代码),但也可以将鼠标悬停在元素上(不起作用,因为用于捕获缩放/平移的
rect
覆盖了
圆圈
,这应该可以接受
鼠标悬停
。我如何支持这两种功能

const svg = select('svg');


const width = +svg.attr("width");
const height = +svg.attr("height");

var div = select("body").append("div")
  .attr("class", "tooltip")
  .style("opacity", 0);


var g = svg.append("g")
  .attr('width', width)
  .attr('height', height)

svg.append("rect")
  .attr("width", width)
  .attr("height", height)
  .style("fill", "none")
  .style("pointer-events", "all")
  .call(zoom()
    .scaleExtent([1 / 2, 10])
    .on("zoom", zoomed));

function zoomed() {
  g.attr("transform", event.transform);
}

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 focus = svg.append("g")
  .attr("class", "focus")
  .style("display", "none");

const link = g.append("g")
  .attr("stroke", "#999")
  .attr("stroke-opacity", 0.6)
  .selectAll("line")
  .data(links)
  .enter().append("line")
  .attr("stroke-width", d => Math.sqrt(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')
  .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);
  }

正如@rioV8所提到的,您所要做的就是将缩放应用于SVG。非常简单

以下是完整的代码,以防有人感兴趣:

css

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);
}

在svg上设置缩放,然后进行搜索。这需要很多操作(缩放力图),并且有很多块示例
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);
}