Ruby on Rails中通过JS为每组图表的Dot元素添加SVG连线问题
解决方案
1. 修正ERB结构(按图表分组生成元素)
当前ERB会为每个匹配项单独生成.result-bar,导致每个点处于独立容器,无法组成完整图表。需要先将数组按3个图表分组(每组4个元素),让同一图表的点归属于同一个容器:
<% # 将数组按每组4个元素拆分,对应3个图表 %> <% ary.in_groups_of(4).each do |chart_points| %> <div class="val" style="height: calc(100% / 3);"> <div class="result-bar"> <% chart_points.each do |x| %> <% if x == val %> <div class="dot"></div> <% end %> <% end %> <svg class="chart-svg"></svg> </div> </div> <% end %> <div class="letter-bar-range"> <%= content_tag(:p, "#{letter}") %> </div>
2. 调整CSS定位与SVG样式
给.result-bar设置相对定位,确保.dot的绝对定位基于当前图表容器;同时给SVG设置宽高,让它覆盖整个图表区域:
.val { width: 100%; position: relative; transform: translateX(70%); z-index: 1; display: flex; align-items: center; border: solid 1px blue; .result-bar { border: solid 1px red; position: relative; /* 作为内部元素的定位父级 */ width: 100%; height: 100%; .dot { position: absolute; width: 10px; height: 10px; border-radius: 100%; background: $soft-blue; /* 可根据需求调整每个点的top/left位置,实现垂直排列 */ } .chart-svg { position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; /* 避免遮挡交互 */ } } p { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); } }
3. 重写JS逻辑:为每个图表单独连线
遍历每个图表容器,收集内部所有点的坐标,用SVG<polyline>一次性连接所有点(比多个<line>更高效):
document.addEventListener('DOMContentLoaded', function() { // 遍历每个图表容器 document.querySelectorAll('.result-bar').forEach(chart => { const dots = chart.querySelectorAll('.dot'); const svg = chart.querySelector('.chart-svg'); if (dots.length < 2) return; // 获取图表容器的位置,用于计算相对坐标 const chartRect = chart.getBoundingClientRect(); // 收集每个点相对于容器的中心坐标 const points = Array.from(dots).map(dot => { const dotRect = dot.getBoundingClientRect(); const x = dotRect.left + dotRect.width/2 - chartRect.left; const y = dotRect.top + dotRect.height/2 - chartRect.top; return `${x},${y}`; }).join(' '); // 创建多段线元素 const polyline = document.createElementNS('http://www.w3.org/2000/svg', 'polyline'); polyline.setAttribute('points', points); polyline.setAttribute('stroke', 'red'); polyline.setAttribute('stroke-width', '1'); polyline.setAttribute('fill', 'none'); svg.appendChild(polyline); }); });
核心问题修正说明
- ID冲突:原代码用固定
id="_svg",多个图表时只会选中第一个SVG,改用class后每个图表对应独立的SVG。 - 容器分组错误:原ERB将每个点放在独立容器,调整后同一图表的点归属于同一个
.result-bar,便于批量处理。 - 坐标基准错误:将
.result-bar设为相对定位,确保点的坐标计算基于当前图表容器,而非整个文档。
内容的提问来源于stack exchange,提问作者Jose Manuel Mendez Benitez
相关产品推荐
相关产品推荐

