Chartjs监听mouseup打破传说点击

y0u0uwnf  于 2023-05-17  发布在  Chart.js
关注(0)|答案(2)|浏览(138)

我有一个Chart.js的自定义插件,它必须监听mouseup事件。当我想添加一个通过点击图例来禁用信号的功能时,图例点击不起作用,无论是默认的还是自定义的onClick。使用自定义onClick,我发现每次单击都会运行两次,第一次禁用,第二次立即再次启用信号。如果我从事件中删除mouseup,图例单击只运行一次。无法将事件列表传递给图例并停止其侦听mouseup。
我能够通过在自定义插件事件处理程序中返回false来规避这个问题。

{
      id: 'customPlugin',
      beforeEvent(chart, args) {
        if (args.event.type === 'mouseup') {
          console.log('mouse up');
          this.isDragging = false;
          return false; // if doesnt return false, legend click is run twice
        }
      },

https://stackblitz.com/edit/angular-chart-js-xkhcjv?file=src%2Fapp%2Fapp.component.ts
但我想知道,这真的是预期的用法吗?如果我有另一个插件也听mouseup?

bxfogqkk

bxfogqkk1#

所有插件都可以使用events选项配置为要捕获的事件类型数组。
对于您的用例,我认为它可能是:

options: {
   // mouseup must be add to chart
   events: ['mousemove', 'mouseout', 'click', 'touchstart', 'touchmove', 'mouseup'],
   plugins: {
     legend: {
       events: ['mouseup'] // only mouseup is caught and managed by legend as click
     }
   }      
}

如果你只想抓住点击图例(并忽略mouseup):

options: {
   // mouseup must be add to chart
   events: ['mousemove', 'mouseout', 'click', 'touchstart', 'touchmove', 'mouseup'],
   plugins: {
     legend: {
       events: ['click'] // only click is caught and managed by legend as click
     }
   }      
}
vof42yt1

vof42yt12#

@user2057925是正确的,应该按照他的说法配置events属性。特别是,如果没有这些事件中的一些,将丢失工具提示。事实上,我认为你发现了一个bug。就简短的解释而言,您的代码暴露了两个不同的问题

问题1(异常行为)

如果定义了options.plugins.legend.onClick,那么默认的“点击”行为不会被触发(这是合理的),也没有一个文档化的方法来这样做(不那么合理)。
解决方案是在Chart对象中搜索原始的onClick方法,使用源代码:

onClick: (...args) => {
    console.log('legend click');
    
    // if using modules, import Legend with Chart
    // import {Chart, registrables, Legend} from './chart.js'
    Legend.defaults.onClick(...args);
    // // if using standard script tag with the chartjs umd just:
    // Chart.Legend.defaults.onClick(...args);
}

jsFiddle

问题二(bug)

如果图表的options.events同时包含mouseupclick,则单击事件会在图表的任何位置触发两次,而不管是否存在插件(可以在OP的代码中注解整个插件部分)。
这对于图例很明显,其默认行为是第二次单击取消第一次单击的效果(隐藏然后显示单击的数据集)jsFiddle
这是一个bug,在我看来也是如此。
这是由于函数_isClickEvent(e)返回true,如果e.type === 'mouseup'。该函数在方法Chart#_handleEvent中被调用,尽管这是chart.js主代码中唯一调用它的地方,但这种行为可能有很好的理由;但是_handleEvent应该考虑到用户在options.events中声明了两种事件类型。
此行为与插件无关,但OP已经找到最佳解决方案:如果插件处理程序返回false,则保存该情况;这 * 是 * 记录的行为,请参见Plugin#beforeEvent
如果任何插件返回false,该事件将被丢弃。
尽管这看起来有点武断--一个插件在全局范围内取消一个事件可能会影响另一个插件,扰乱设计中急需的分离(插件实现者不可能知道用户添加了什么其他插件)。
我不推荐另一个显而易见的解决方案,即在已经有mouseup的情况下,从options.events中排除click(因为无论如何,单击都会被mouseup触发)--很难考虑到与库的所有组件的所有可能的交互。

相关问题