Javascript 与d3可重用模式的交互性

Javascript 与d3可重用模式的交互性,javascript,d3.js,charts,event-handling,dom-events,Javascript,D3.js,Charts,Event Handling,Dom Events,在D3中: 我正在尝试使用实现一个图表,它允许我添加在实际图表之外处理的事件。例如,我有一个简单的条形图,我可以点击每个单独的条形图。现在,我希望能够从创建图表实例的位置处理它,而不仅仅是在图表组件中处理单击事件。例如,我想要编辑与单击的条元素对应的数据,或者我想要根据我单击的条的位置更新其他元素的位置。为了使图表组件尽可能模块化和独立,我不希望在其中完成某些任务 我提出了一个非常直截了当的解决方案,但我觉得一定有更好的解决方案。这样我就必须考虑到外界可能感兴趣的每一个可能的事件 是否有任何标准

在D3中:
我正在尝试使用实现一个图表,它允许我添加在实际图表之外处理的事件。例如,我有一个简单的条形图,我可以点击每个单独的条形图。现在,我希望能够从创建图表实例的位置处理它,而不仅仅是在图表组件中处理单击事件。例如,我想要编辑与单击的条元素对应的数据,或者我想要根据我单击的条的位置更新其他元素的位置。为了使图表组件尽可能模块化和独立,我不希望在其中完成某些任务

我提出了一个非常直截了当的解决方案,但我觉得一定有更好的解决方案。这样我就必须考虑到外界可能感兴趣的每一个可能的事件

是否有任何标准方法/最佳实践来处理此类情况?或者这真的不是一种常见的情况


感谢您的帮助

使其更可重用并适用于任何可能的事件的一个想法是定义
处理程序
数组。这与d3本身类似。这是一个

您可以像使用HTML元素一样使用
图表

chart.on("click", clickHandler);

一个使其更可重用并适用于任何可能事件的想法是定义一个
处理程序
数组。这与d3本身类似。这是一个

您可以像使用HTML元素一样使用
图表

chart.on("click", clickHandler);

您需要的是在核心应用程序代码和可重用代码之间建立一个分离。这是一个好主意,因为它使您的应用程序的代码保持较小,使您更容易更改它并向前推进。在可重用图表中,您希望发送非常通用的事件,例如,
单击
,而在应用程序中,您需要事件非常特定于您的域,例如,
添加糖

你需要两种材料:和。前者帮助您创建清晰的内部API,而后者帮助您向外部世界公开已调度的事件

到这里来找一份这份工作。您要寻找的是三件事:

  • 在可重用图表中,您创建了一个调度程序,其中包含要发布到外部世界的事件:
    var myDispatch=d3.dispatch('myclick','mydrag')
  • 然后在可重用图表的事件处理程序中发布这些事件,如下所示:
    myDispatch.myclick(argumentsyouwanttopass)
  • 最后一步是让这些事件对外可用:
    returnd3.rebind(_chart,myDispatch,“on”)
  • 然后可以在外部绑定到这些事件:
    myChart.on('myclick',function(){})
  • 因此,您的示例重写后可能会如下所示:

    功能图(){
    var dispatch=d3.dispatch('click');
    功能图(选择){
    选择。每个(功能(d,i){
    selection.selectAll('rect')
    .数据(d)
    .输入()
    .append('rect')
    .attr('x',0)
    .attr('y',函数(d,i){返回i*11;})
    .attr('width',函数(d,i){return d;})
    .attr('height',10);
    .on('click',dispatch.click');
    });
    }
    返回d3。重新绑定(_图表,调度,'on');
    }
    

    附加说明:要注册多个事件处理程序,需要为它们命名名称(就像常规d3事件一样),例如
    chart.on('click.foo',handlerFoo)
    chart.on('click.bar',handlerBar)
    等等。

    您需要的是在核心应用程序代码和可重用代码之间建立一种分离。这是一个好主意,因为它使您的应用程序的代码保持较小,使您更容易更改它并向前推进。在可重用图表中,您希望发送非常通用的事件,例如,
    单击
    ,而在应用程序中,您需要事件非常特定于您的域,例如,
    添加糖

    你需要两种材料:和。前者帮助您创建清晰的内部API,而后者帮助您向外部世界公开已调度的事件

    到这里来找一份这份工作。您要寻找的是三件事:

  • 在可重用图表中,您创建了一个调度程序,其中包含要发布到外部世界的事件:
    var myDispatch=d3.dispatch('myclick','mydrag')
  • 然后在可重用图表的事件处理程序中发布这些事件,如下所示:
    myDispatch.myclick(argumentsyouwanttopass)
  • 最后一步是让这些事件对外可用:
    returnd3.rebind(_chart,myDispatch,“on”)
  • 然后可以在外部绑定到这些事件:
    myChart.on('myclick',function(){})
  • 因此,您的示例重写后可能会如下所示:

    功能图(){
    var dispatch=d3.dispatch('click');
    功能图(选择){
    选择。每个(功能(d,i){
    selection.selectAll('rect')
    .数据(d)
    .输入()
    .append('rect')
    .attr('x',0)
    .attr('y',函数(d,i){返回i*11;})
    .attr('width',函数(d,i){return d;})
    .attr('height',10);
    .on('click',dispatch.click');
    });
    }
    返回d3。重新绑定(_图表,调度,'on');
    }
    

    附加说明:要注册多个事件处理程序,您需要给它们命名(就像您必须为常规d3事件命名一样),例如
    chart.on('click.foo',handlerFoo)
    chart.on('click.bar',handlerBar)
    等等。

    是的,这似乎是一个非常好的解决方案!我一定要试试。谢谢这似乎是一个很好的解决方案!我一定要试试。谢谢!我得先想一想,但这听起来正是我想要的。桑克斯<代码>d3.rebind()
    在d3库中不再可用。应使用相关的
    chart.on("click", clickHandler);