【问题标题】:D3- positioning of a tooltip using d3.mouse is not workingD3-使用 d3.mouse 定位工具提示不起作用
【发布时间】:2020-03-10 18:18:16
【问题描述】:

我正在尝试在圆圈上悬停一个工具提示 Example

SVG 顶部有一个 div,它有高度,因为那个 div,工具提示位置不正确。

示例代码。

.on('mousemove', function (d) {
  tooltip
    .html('No data to display.')
    .style('left', (d3.mouse(this)[0] + 20) + 'px')
    .style('top', d3.mouse(this)[1] + 'px')
  })

我仍然可以做类似.style('top', (d3.mouse(this)[1] + 100) + 'px') 的事情。这应该可行,因为我知道上述 div 的高度。

是否有可能在不使用 d3.mouse() 事件将上方元素的高度添加到 SVG 的情况下获得 Y 位置?

【问题讨论】:

    标签: javascript d3.js


    【解决方案1】:

    您可以改用d3.event

    .on('mousemove', function(d) {
      tooltip
        .html('No data to display.')
        .style('left', (d3.event.pageX + 10) + 'px')
        .style('top', (d3.event.pageY + 10) + 'px')
    })
    

    带 div:

    var a = [{
        cx: 40,
        cy: 60,
        r: 20
      },
      {
        cx: 120,
        cy: 80,
        r: 20
      },
      {
        cx: 200,
        cy: 60,
        r: 20
      }
    ];
    
    const tooltip = d3.select('.tooltip')
    var circle = d3.select("svg").selectAll("circle")
      .data(a)
      .on('mouseover', function() {
        tooltip
          .style('display', 'block')
        d3.select(this)
          .style('opacity', 1)
      })
      .on('mousemove', function(d) {
        tooltip
          .html('No data to display.')
          .style('left', (d3.event.pageX + 10) + 'px')
          .style('top', (d3.event.pageY + 10) + 'px')
      })
      .on('mouseleave', function() {
        tooltip
          .style('display', 'none')
      })
    
    circle.exit().remove();
    
    circle
      .attr('r', function(d) {
        return d.r
      })
      .attr('cy', function(d) {
        return d.cy
      })
      .attr('cx', function(d) {
        return d.cx
      })
      .style('fill', 'steelblue');
    .tooltip {
      display: none;
      position: absolute;
      background-color: white;
      border: 1px solid #c1c1c1;
      border-radius: 5px;
      padding: 5px;
    }
    <script src="https://d3js.org/d3.v3.min.js" charset="utf-8"></script>
    <div style="height: 100px;">Need this div</div>
    <div class="tooltip"></div>
    <svg width="720" height="120">
      <circle cx="40" cy="40" r="30" style="fill:steelblue;"></circle>
      <circle cx="80" cy="40" r="30" style="fill:steelblue;"></circle>
    </svg>

    没有 div:

    var a = [{
        cx: 40,
        cy: 60,
        r: 20
      },
      {
        cx: 120,
        cy: 80,
        r: 20
      },
      {
        cx: 200,
        cy: 60,
        r: 20
      }
    ];
    
    const tooltip = d3.select('.tooltip')
    var circle = d3.select("svg").selectAll("circle")
      .data(a)
      .on('mouseover', function() {
        tooltip
          .style('display', 'block')
        d3.select(this)
          .style('opacity', 1)
      })
      .on('mousemove', function(d) {
        tooltip
          .html('No data to display.')
          .style('left', (d3.event.pageX + 10) + 'px')
          .style('top', (d3.event.pageY + 10) + 'px')
      })
      .on('mouseleave', function() {
        tooltip
          .style('display', 'none')
      })
    
    circle.exit().remove();
    
    circle
      .attr('r', function(d) {
        return d.r
      })
      .attr('cy', function(d) {
        return d.cy
      })
      .attr('cx', function(d) {
        return d.cx
      })
      .style('fill', 'steelblue');
    .tooltip {
      display: none;
      position: absolute;
      background-color: white;
      border: 1px solid #c1c1c1;
      border-radius: 5px;
      padding: 5px;
    }
    <script src="https://d3js.org/d3.v3.min.js" charset="utf-8"></script>
    <div class="tooltip"></div>
    <svg width="720" height="120">
      <circle cx="40" cy="40" r="30" style="fill:steelblue;"></circle>
      <circle cx="80" cy="40" r="30" style="fill:steelblue;"></circle>
    </svg>

    d3.mouse 与 div 一起使用:

    .on('mousemove', function(d, a, b) {
      tooltip
        .html('No data to display.')
        .style('left', (d3.mouse(this)[0] + d3.select('svg').node().getBoundingClientRect().x + 10) + 'px')
        .style('top', (d3.mouse(this)[1] + d3.select('svg').node().getBoundingClientRect().y + 10) + 'px')
    })
    

    var a = [{
        cx: 40,
        cy: 60,
        r: 20
      },
      {
        cx: 120,
        cy: 80,
        r: 20
      },
      {
        cx: 200,
        cy: 60,
        r: 20
      }
    ];
    
    const tooltip = d3.select('.tooltip')
    var circle = d3.select("svg").selectAll("circle")
      .data(a)
      .on('mouseover', function() {
        tooltip
          .style('display', 'block')
        d3.select(this)
          .style('opacity', 1)
      })
      .on('mousemove', function(d, a, b) {
        tooltip
          .html('No data to display.')
          .style('left', (d3.mouse(this)[0] + d3.select('svg').node().getBoundingClientRect().x + 10) + 'px')
          .style('top', (d3.mouse(this)[1] + d3.select('svg').node().getBoundingClientRect().y + 10) + 'px')
      })
      .on('mouseleave', function() {
        tooltip
          .style('display', 'none')
      })
    
    circle.exit().remove();
    
    circle
      .attr('r', function(d) {
        return d.r
      })
      .attr('cy', function(d) {
        return d.cy
      })
      .attr('cx', function(d) {
        return d.cx
      })
      .style('fill', 'steelblue');
    .tooltip {
      display: none;
      position: absolute;
      background-color: white;
      border: 1px solid #c1c1c1;
      border-radius: 5px;
      padding: 5px;
    }
    <script src="https://d3js.org/d3.v3.min.js" charset="utf-8"></script>
    <div style="height: 100px;">Need this div</div>
    <div class="tooltip"></div>
    <svg width="720" height="120">
      <circle cx="40" cy="40" r="30" style="fill:steelblue;"></circle>
      <circle cx="80" cy="40" r="30" style="fill:steelblue;"></circle>
    </svg>

    【讨论】:

    • 它工作正常。关于为什么它不能与 d3.mouse() 一起工作的任何想法?这是使用 d3.event 获取显示工具提示的位置的正确方法吗?
    • 那是因为d3.mouse 为您提供相对于 SVG 边界矩形而不是页面边界矩形的位置。你可以做什么我计算整个 svg 的边界记录并将其 x,y 值与 d3.mouse 值一起添加到你的 left,top 样式中
    • @Sam 还注意到滚动时d3.mouse 的缺点,例如在 sn-p 中。如果使用也需要处理
    【解决方案2】:

    很有用:

    https://www.jacklmoore.com/notes/mouse-position/

    您使用什么取决于 SVG 在页面上的位置、您是否需要滚动以及您的浏览器兼容性需求。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-09
      • 1970-01-01
      • 2013-04-21
      • 2022-11-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多