【发布时间】:2020-09-15 20:41:54
【问题描述】:
我是 TypeScript 的新手,正在尝试使用 D3.js 创建一个带有两个句柄的简单范围滑块。
我为滑块对象创建了一个基本类:
export class VerticalRangeSlider{
private sliderContainer: d3.Selection<SVGGElement, any, HTMLDivElement, any>;
private scale: d3.ScaleLinear<number, number>;
private sliderTopBound: number;
private sliderBottomBound: number;
private handleTopY: number;
private handleBottomY: number;
private handleTop: d3.Selection<SVGCircleElement, any, HTMLDivElement, any>;
private handleBottom: d3.Selection<SVGCircleElement, any, HTMLDivElement, any>;
constructor(slContainer: d3.Selection<SVGGElement, any, HTMLDivElement, any>, scl: d3.ScaleLinear<number, number>){
this.sliderContainer = slContainer;
this.scale = scl;
this.sliderTopBound = 0;
this.sliderBottomBound = scl.range()[0];
this.handleTopY = this.sliderTopBound;
this.handleBottomY = this.sliderBottomBound;
this.initSlider();
}
这两个句柄是在 initSlider 方法中创建的。我有一个匿名函数被调用来处理拖动事件,它调用 moveHandle 方法来重新渲染圆圈。
因为我发现 this. 在匿名函数中有不同的上下文,所以我在 initSlider 中声明了一个变量来保存指向父对象的指针:var parentObject = this;。
this.handleTop = this.sliderContainer.insert("circle", ".track-overlay")
.attr("class", "handle")
.attr("r", 9)
.attr("cy", this.handleTopY)
.attr("desc", this.handleTopY)
.call(d3.drag()
.on('drag', function(){
parentObject.moveHandle(parentObject.handleTop, parentObject.handleTopY, d3.event.dy, parentObject.sliderTopBound, parentObject.handleBottomY);
}));
this.handleBottom = this.sliderContainer.insert("circle", ".track-overlay")
.attr("class", "handle")
.attr("r", 9)
.attr("cy", this.handleBottomY)
.attr("desc", this.handleBottomY)
.call(d3.drag()
.on('drag', function(){
parentObject.moveHandle(parentObject.handleBottom, parentObject.handleBottomY, d3.event.dy, parentObject.handleTopY, parentObject.sliderBottomBound);
}));
我遇到了 moveHandle 方法的问题:
private moveHandle(handle: d3.Selection<SVGCircleElement, any, HTMLDivElement, any>, currentPosition: number, increment: number, topBound: number, bottomBound:number): void {
var legalIncrement: number;
//upward movement
if(Math.sign(increment) === -1){
legalIncrement = increment <= (currentPosition - topBound) ? increment : (currentPosition - topBound);
console.log("allowed increment: "+legalIncrement);
}
//downward movement
else {
legalIncrement = increment <= (bottomBound - currentPosition) ? increment : (bottomBound - currentPosition);
console.log("allowed increment: "+legalIncrement);
}
if(legalIncrement !== 0){
currentPosition = (currentPosition + legalIncrement)
handle.attr("transform", "translate(0," + currentPosition + ")");
}
}
当我尝试拖动圆圈时,它们会按预期短暂呈现,但随后会立即恢复到原来的位置。
但是,当我将指向父对象的指针直接传递给 moveHandle 时,一切正常:parentObject: VerticalRangeSlider): void {
parentObject.handleBottomY = parentObject.handleBottomY + increment; parentObject.handleBottom.attr("cy", parentObject.handleBottomY);
我最初的假设是我将指向父对象属性的指针传递到我的方法中,但看起来情况并非如此。我最好的理论是正在创建新对象。
我非常感谢对此行为的任何见解(以及任何反馈以更好地构建我的 JS/TS 代码)。
谢谢!
【问题讨论】:
标签: javascript typescript d3.js