1

我有一个基于 SVG 的图表。顶部是一个可滚动区域,用户可以在其中浏览图表,如图所示:

滚动区

通过拖动左右任一选项卡,用户可以放大绘图的特定部分,如图所示:

滚动

请注意,只有图形的选定部分是蓝色的,并且具有灰色突出显示。蓝色和高光都没有改变,但使用剪切蒙版进行剪切:

<clippath id="clip_path_scroll">
  <rect id="clip_path_scroll_rect" x="x" y="y" width="w" height="h" stroke-width="0" />
</clippath>

<g clip-path="url(#clip_path_scroll)">
  <rect id="highlighted" width="w" height="h" x="x" y="y" fill="rgba(0, 0, 0, .03)" stroke="none" />
  <path id="blue_plot" d="..." stroke="rgba(26, 171, 219, 1)" stroke-width="2" fill="none"/>
</g>

这一切都很好,花花公子。拖动选项卡时,剪辑路径完美无缺。在这种情况下,它会随着选项卡的滑动而逐渐更改。

但我有一个重置按钮,它调用以下内容:

$('#left_scroll_group').attr('transform', 'translate(0, 0)');
$('#right_scroll_group').attr('transform', 'translate(0, 0)');
$('#clip_path_scroll_rect').attr('width', width).attr('x', x);

当它运行时,结果如下:

复位后

请注意,选项卡组会准确地回到它们应该在的位置,但剪辑路径似乎只是部分回到了其原始宽度和 x 位置。

但事实并非如此

如果我查看页面源,并将鼠标悬停在 clippathrect对象上,它会显示以下内容:

剪辑路径矩形

也就是说,它显示rect对象 DID 调整大小并移动到其原始位置,但无法正常显示。移动任一选项卡会立即使剪辑路径恢复正常工作,如前两个图像中所示。

为什么会这样?无论是移动右侧选项卡,还是左侧选项卡,或两者都移动,都会发生这种情况。如果选项卡仅移动一点,似乎没有太大问题,但随着选项卡进一步移动,明显的故障/错误会增加。

类似的函数对剪辑路径执行相同attr的更改,但它总是缩短路径长度。此故障似乎仅在延长长度时发生。

我对图中的许多其他元素使用相同类型的操作,并且一切正常。所有都用 jQuery 表示法(即$('#element'))引用。

我对使用 d3 或其他库不感兴趣。我只在寻找 jQuery 或纯 JS 解决方案。

编辑 1

我也试过

var steps = Math.floor(scrollPlotWidth - $('#clip_path_scroll_rect').attr('width'));
var curWidth = Math.ceil($('#clip_path_scroll_rect').attr('width'));
var curX = $('#clip_path_scroll_rect').attr('x');

for(var i = 0; i < steps; i++){
    $('#clip_path_scroll_rect').attr('x', curX).attr('width', curWidth);
    curX--;
    curWidth++;
}

没有成功。变化是逐渐发生的,但仍然没有骰子——它看起来和以前一样。此剪辑问题仅在 Safari 中发生,在 FireFox 中似乎很好。没有测试过其他人。

工作解决方案(黑客)

在剪辑路径中定义时rect,我更改了 width 属性。我已将其从上面显示的内容更改为以下内容:

<rect id="highlighted" style="width:w;" height="h" x="x" y="y" fill="rgba(0, 0, 0, .03)" stroke="none" />

然后,如果我应用了这两个操作,则剪辑路径功能可以正常工作:

$('#clip_path_scroll_rect').attr('x', x).css('width', w);

$('#clip_path_scroll_rect').animate(
    {"width": w},
    {duration: 1,
    step: function(){
        this.setAttribute("x", x);
    }
});

删除其中任何一个都会阻止它工作。我不知道为什么,但它必须是一个临时修复,直到出现更好的情况。答案仍然非常受欢迎!

4

0 回答 0