You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于SVG元素顶部位置定位Tooltip的技术问题求助

Fixing Tooltip Alignment & Undefined Error with Raphael SVG Polygons

Hey there! Let's sort out your tooltip issue and that annoying undefined error together. Here's what's going wrong and how to fix it:

Why You're Getting the "Undefined" Error

The problem comes from how JavaScript handles scope in loops with var. When your mouseover event fires, the loop has already finished running, so i is equal to shapes.length (which is 7 in your code), making shapes[i] undefined. Plus, even if you had the right index, shapes[i] is a Raphael object—not a DOM node—so you'd need to access its .node property to use getBoundingClientRect().

How to Align Tooltip to Polygon Top

Instead of relying on mouse position, we'll use Raphael's built-in getBBox() method to get the exact top position of each polygon, then calculate the correct absolute position for your tooltip. Here's the step-by-step fix:

  1. Get the current polygon's boundary box: Use this.getBBox() inside the mouseover handler (since this refers to the polygon that triggered the hover).
  2. Calculate the page position: Get the offset of your SVG container (#rsr) to convert the polygon's SVG-local coordinates to page-wide absolute positions.
  3. Position the tooltip: Set the tooltip's top position to match the polygon's top edge.

Full Corrected Code

var rsr = Raphael('rsr', '147.99', '151');
var shapes = [];
var path_a = rsr.path("M 59.288,50.5 44.58,25.5 59.288,0.5 88.703,0.5 103.41,25.5 88.703,50.5 z");
path_a.data('id', 'path_a');
var path_b = rsr.path("M 103.288,75.5 88.58,50.5 103.288,25.5 132.703,25.5 147.41,50.5 132.703,75.5 z");
path_b.data('id', 'path_b');
var path_c = rsr.path("M 59.288,100.5 44.58,75.5 59.288,50.5 88.703,50.5 103.41,75.5 88.703,100.5 z");
path_c.data('id', 'path_c');
var path_d = rsr.path("M 15.288,75.5 0.58,50.5 15.288,25.5 44.703,25.5 59.41,50.5 44.703,75.5 z");
path_d.data('id', 'path_d');
var path_e = rsr.path("M 103.288,125.5 88.58,100.5 103.288,75.5 132.703,75.5 147.41,100.5 132.703,125.5 z");
path_e.data('id', 'path_e');
var path_f = rsr.path("M 59.288,150.5 44.58,125.5 59.288,100.5 88.703,100.5 103.41,125.5 88.703,150.5 z");
path_f.data('id', 'path_f');
var path_g = rsr.path("M 15.288,125.5 0.58,100.5 15.288,75.5 44.703,75.5 59.41,100.5 44.703,125.5 z");
path_g.data('id', 'path_g');
shapes.push(path_a, path_b, path_c, path_d, path_e, path_f, path_g);

for (var i = 0; i < shapes.length; i++) {
 shapes[i].node.setAttribute('fill', '#8c1c40');
 shapes[i].node.setAttribute('stroke', 'white');
 shapes[i].node.setAttribute('stroke-width', '1');
 shapes[i].node.style.cursor = "pointer";
 
 shapes[i].mouseover(function(e) {
  // Get the tooltip element first
  const box = document.getElementById('textbox');
  // Get current polygon's bounding box (SVG-local coordinates)
  const bbox = this.getBBox();
  // Get SVG container's position on the page
  const containerRect = document.getElementById('rsr').getBoundingClientRect();
  
  // Calculate tooltip position: align top with polygon's top
  const tooltipTop = containerRect.top + bbox.y;
  
  this.node.setAttribute('fill', '#888');
  box.style.position = "absolute";
  box.style.left = '200px';
  box.style.top = `${tooltipTop}px`;
  box.innerHTML = this.data('id');
  
  e.preventDefault();
  e.stopPropagation();
 });
 
 shapes[i].mouseout(function(e) {
  this.node.setAttribute('fill', '#8c1c40');
  document.getElementById('textbox').innerHTML = "";
 });
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/raphael/2.1.0/raphael-min.js"></script>
<div id="rsr"></div>
<div id="textbox"></div>

Key Changes Explained

  • Replaced shapes[i] with this: Inside the mouseover handler, this refers directly to the polygon that was hovered, avoiding the loop scope issue.
  • Used getBBox(): This Raphael method gives us accurate coordinates for the polygon's top edge (bbox.y) relative to the SVG canvas.
  • Added container offset calculation: containerRect.top gets the SVG's position on the page, so adding bbox.y gives us the absolute top position for the tooltip.
  • Defined box variable: Fixed the missing variable reference by grabbing the tooltip element at the start of the handler.

This should make your tooltip align perfectly with the top of each polygon, and eliminate that undefined error!

内容的提问来源于stack exchange,提问作者Vinny

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:49:10