我正在使用D3.js、TypeScript和Vue属性装饰器进行Vue项目。我想画一个热图,但当我想调用x()
或y()
函数来返回热图中每个单元格的计算位置时,我遇到了一个错误。它抛出错误
类型"SVG最小长度";没有呼叫签名。
这就是我初始化图表变量的方式
private svg: d3.Selection<SVGGElement, any, HTMLElement, any>
private x: d3.ScaleBand<string>
private xAxis: d3.Selection<SVGGElement, any, HTMLElement, any>
private y: d3.ScaleBand<string>
private yAxis: d3.Selection<SVGGElement, any, HTMLElement, any>
这就是导致错误的地方
this.svg.selectAll()
.data(this.getData().filter((datum: HeatmapData) => this.betweenTwoDates(datum)))
.enter()
.append('rect')
.attr('x', function(d: HeatmapData) {
return this.x(d.dayNumber)
})
.attr('y', function(d: HeatmapData) {
return this.y(d.timeOfDay)
})
.attr('cx', 1)
.attr('cy', 1)
.attr('width', this.x.bandwidth())
.attr('height', this.y.bandwidth())
在
.attr('x', function(d: HeatmapData) {
return this.x(d.dayNumber)
})
则错误发生在声明CCD_ 4的CCD_。.attr('y', ...)
也是如此。
在this.x()
处的this
具有SVGRectElement
的类型。
这是一个很好的例子,说明了何时实际使用箭头函数来支持正则函数!因为常规函数(如代码中的函数)建立了自己的this
作用域,所以您不再能够访问您感兴趣的this
作用域,即您的代理类的作用域。
许多D3方法都是在this
设置为当前DOM元素时调用的:
this作为当前DOM元素(nodes[i])
为了能够通过使用this
引用类实例的方法来使用它们,您可以只使用一个箭头函数,该函数没有自己的作用域,而是捕获其周围上下文(即您的类/实例)的作用域。因此,您的方法应该如下所示:
.attr('x', d => this.x(d.dayNumber))
this
具有SVGRectElement类型,因为它位于常规匿名函数内部。在D3中,用于操作节点的方法将this
上下文替换为正在被操作的自己的DOM元素,在本例中为<rect>
。<rect>
节点没有x或y方法,因此出现类型错误。
用箭头函数替换匿名函数可以保护this
不受外部影响:
.attr('x', (d: HeatmapData) => {
return this.x(d.dayNumber)
})
.attr('y', (d: HeatmapData) => {
return this.y(d.timeOfDay)
})
现在,函数内部的this
与外部的this
相同,在本例中,它是包含svg、x、xAxis、y和yAxis的类。