首页 > 解决方案 > 如何使用 d3.js 通过鼠标悬停显示 XY 图表的 x 和 y 坐标

问题描述

当我将鼠标悬停在我的 XY 图表上时,我试图显示我的数据点的 x 和 y 坐标。我的小提琴的链接可以在这里找到。我按照这里的示例进行操作,但我不知道为什么当我将鼠标悬停在我的 XY 图表上的点上时工具提示没有显示。代码如下,不胜感激!

  var data = [ {x: 0, y: 0}, {x: 5, y: 30}, {x: 10, y: 40},
              {x: 15, y: 60}, {x: 20, y: 70}, {x: 25, y: 100} ];

  const margin = {
    left: 20,
    right: 20,
    top: 20,
    bottom: 80
  };

  const svg = d3.select('svg');
  svg.selectAll("*").remove();

  const width = 200 - margin.left - margin.right;
  const height = 200 - margin.top - margin.bottom;

  const g = svg.append('g').attr('transform', `translate(${margin.left},${margin.top})`);


  var x = d3.scaleLinear()
          .domain([0, d3.max(data, function(d){ return d.x; })])
          .range([0,width])
          .nice();

  var y = d3.scaleLinear()
          .domain([0, d3.max(data, function(d){ return d.y; })])
          .range([0,height])
          .nice();

  const xAxis = d3.axisTop()
              .scale(x)
              .ticks(5)
              .tickPadding(5)
              .tickSize(-height)

  const yAxis = d3.axisLeft()
              .scale(y)
              .ticks(5)
              .tickPadding(5)
              .tickSize(-width);

  svg.append("g")
    .attr("class", "x axis")
    .attr("transform", `translate(20,${height-margin.top-60})`)
    .call(xAxis);

  svg.append("g")
    .attr("class", "y axis")
    .attr("transform", "translate(20,20)")
    .call(yAxis);

  var lineFunction = d3.line()
  .x(function(d) {return x(d.x); })
  .y(function(d) {return y(d.y); })
  .curve(d3.curveLinear);

  var tooltip = d3.select("svg")
      .append("div")
      .style("opacity", 0)
      .attr("class", "tooltip")
      .style("background-color", "white")
      .style("border", "solid")
      .style("border-width", "1px")
      .style("border-radius", "5px")
      .style("padding", "10px")

  // A function that change this tooltip when the user hover a point.
  // Its opacity is set to 1: we can now see it. Plus it set the text and position of tooltip depending on the datapoint (d)
  var mouseover = function(d) {
    tooltip
      .style("opacity", 1)
  }

  var mousemove = function(d) {
    tooltip
      .html("x: " + d.x + "<br/>" + "y: " + d.y)
      .style("left", (d3.mouse(this)[0]+90) + "px")
      .style("top", (d3.mouse(this)[1]) + "px")
  }

  // A function that change this tooltip when the leaves a point: just need to set opacity to 0 again
  var mouseleave = function(d) {
    tooltip
      .transition()
      .duration(200)
      .style("opacity", 0)
  }

  //defining and plotting the lines
  var path = g.append("path")
              .attr("class", "path1")
              .attr("id", "blueLine")
              .attr("d", lineFunction(data))
              .attr("stroke", "blue")
              .attr("stroke-width", 2)
              .attr("fill", "none")
              .attr("clip-path", "url(#clip)");

        // plot a circle at each data point
        g.selectAll(".dot")
            .data(data)
            .enter().append("circle")
            .attr("cx", function(d) { return x(d.x); } )
            .attr("cy", function(d) { return y(d.y); } )
            .attr("r", 3)
            .attr("class", "blackDot")
            .attr("clip-path", "url(#clip)")
            .on("mouseover", mouseover )
            .on("mousemove", mousemove )
            .on("mouseleave", mouseleave )

标签: javascriptd3.js

解决方案


<div>标记中不能存在标记<svg>,因此不会呈现工具提示元素。

我建议您修改.select(...)元素访问器的功能。您应该选择 body 元素并将其附加到那里,而不是选择 svg 元素。

此外,要在图表上方呈现 div 工具提示,您需要将 div 元素的位置设置为绝对位置,如下所示:

var tooltip = d3.select("body")
      .append("div")
      .style("opacity", 0)
      .attr("class", "tooltip")
      .style("background-color", "white")
      .style("border", "solid")
      .style("border-width", "1px")
      .style("border-radius", "5px")
      .style("padding", "10px")
      .style("position", "absolute")


它应该按预期工作,这里是更新代码的小提琴链接。


推荐阅读