我的 Angular 应用程序中有一个使用 d3.js 库的图表指令。
该指令的一部分将鼠标事件处理程序添加到某些 svg 元素,如下所示
svg.selectAll('g rect')
.on('click', function(d) {
scope.clickHandler(d, scope.data);
})
.on('mouseover', function () {
d3.select(this).classed('data-item-hover', true);
})
.on('mouseout', function () {
d3.select(this).classed('data-item-hover', false);
});
我想在一些单元测试中涵盖这些处理程序,但正在努力解决如何实际动态调用这些事件的问题。
我正在我的测试规范中尝试这样做
describe('scope.clickHandler', function() {
var rect;
beforeEach(function(){
spyOn(scope, 'clickHandler');
rect = svg.select('g rect')[0][0];
rect.on('click')();
});
it('should call scope.render after a window resize event occurs', function () {
expect(scope.clickHandler).toHaveBeenCalled();
});
});
但是这会引发错误
TypeError: undefined is not a constructor (evaluating 'rect.on('click')'
我遇到了这个SO How to invoke "click" event programmatically in d3?第二个答案是促使我尝试这种技术的原因。
如何在 d3.js 中注册事件的 svg 元素上调用鼠标事件?
谢谢
最佳答案
主要问题是 svg.select('g rect')[0][0]
是一个 DOM 元素,而不是正确的 D3 选择,这就是为什么你得到 undefined
错误。来自文档:
Selections are arrays of elements—literally (maybe not literally...). D3 binds additional methods to the array so that you can apply operators to the selected elements...
您实际上可以检查,因为 DOM 元素实现了 Element
接口(interface):
(svg.select('g rect')[0][0] instanceof Element) // true
因此,为了在某个元素上触发某些事件,您可以执行以下操作:
var rect = svg.select('g rect') // first rect element found is assumed
rect.on('click').call(rect.node(), rect.datum()); // as commented in above link
你可以找到一个简单的工作 fiddle here .
关于angularjs - d3.js - Jasmine 测试调用 svg 元素上的单击,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36313898/