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

Plotly.js悬停标记时平移功能失效问题求助

问题:Plotly.js 悬停标记时平移功能异常

悬停在图表标记上时,使用平移工具拖拽图表后,图表会自动恢复到原始位置。

重现步骤

  • 选择平移工具
  • 悬停在标记上
  • 拖拽图表进行平移
  • 图表立即恢复至原始位置

相关代码

JavaScript

var data = [{
      mode: "lines+markers",
      x:["December", "January", "February"],
      y:[4,1,3]
    }]

Plotly.react('myDiv', data).then(gd => {
      gd.on('plotly_hover', d => {
      var width_vals = gd.data.map(x => 5)
      Plotly.restyle(gd, 'line.width', width_vals)
      
      }).on('plotly_unhover', d => {
      var width_vals = gd.data.map(x => 1)
      Plotly.restyle(gd, 'line.width', width_vals)
      })
})

HTML

<head>
    <!-- Load plotly.js into the DOM -->
    <script src='https://cdn.plot.ly/plotly-2.12.1.min.js'></script>
</head>

<body>
    <div id='myDiv'><!-- Plotly chart will be drawn inside this DIV --></div>
</body>

问题演示

悬停平移异常演示


原因分析

每次触发plotly_hover或plotly_unhover事件时调用Plotly.restyle(),会触发Plotly完整的图表重渲染流程,这个过程会重置图表的视图状态(包括平移后的坐标轴范围),导致拖拽平移后图表立刻回到初始位置。

解决方法

方法1:直接操作SVG元素修改线条宽度(推荐)

绕过Plotly的重渲染API,直接定位图表中的线条SVG元素修改样式,不会影响视图状态:

var data = [{
      mode: "lines+markers",
      x:["December", "January", "February"],
      y:[4,1,3]
    }]

Plotly.react('myDiv', data).then(gd => {
      // 预获取所有线条元素
      const lineElements = gd.querySelectorAll('.scatterlayer path.line');
      
      gd.on('plotly_hover', () => {
        lineElements.forEach(el => el.setAttribute('stroke-width', 5));
      }).on('plotly_unhover', () => {
        lineElements.forEach(el => el.setAttribute('stroke-width', 1));
      })
})

方法2:重渲染后恢复视图状态

如果必须使用Plotly.restyle(),可在操作前后保存并恢复当前视图范围:

var data = [{
      mode: "lines+markers",
      x:["December", "January", "February"],
      y:[4,1,3]
    }]

Plotly.react('myDiv', data).then(gd => {
      gd.on('plotly_hover', d => {
        // 保存当前坐标轴范围
        const xRange = gd.layout.xaxis.range;
        const yRange = gd.layout.yaxis.range;
        
        var width_vals = gd.data.map(x => 5)
        Plotly.restyle(gd, 'line.width', width_vals).then(() => {
          // 恢复之前的视图范围
          Plotly.relayout(gd, {
            'xaxis.range': xRange,
            'yaxis.range': yRange
          });
        })
      }).on('plotly_unhover', d => {
        const xRange = gd.layout.xaxis.range;
        const yRange = gd.layout.yaxis.range;
        
        var width_vals = gd.data.map(x => 1)
        Plotly.restyle(gd, 'line.width', width_vals).then(() => {
          Plotly.relayout(gd, {
            'xaxis.range': xRange,
            'yaxis.range': yRange
          });
        })
      })
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 11:03:20