angular - 将 d3 事件从 Javascript 转换为 Typescript(Angular2)
我刚接触 Typescript 和 Angular 2。我正在尝试做的是创建一个包含 d3js 工具的 Angular2 组件,不管怎样,我在将其重写为 Typescript 时遇到了一些问题。
例如,这是一种重写这段代码的好方法吗?
来自 d3js:
var GraphCreator = function(svg, nodes, edges){
var thisGraph = this;
thisGraph.idct = 0;
thisGraph.nodes = nodes || [];
thisGraph.edges = edges || [];
thisGraph.state = {
selectedNode: null,
selectedEdge: null,
mouseDownNode: null,
mouseDownLink: null,
justDragged: false,
justScaleTransGraph: false,
lastKeyDown: -1,
shiftNodeDrag: false,
selectedText: null
};
thisGraph.svg = svg;
thisGraph.svgG = svg.append("g")
.classed(thisGraph.consts.graphClass, true);
var svgG = thisGraph.svgG;
thisGraph.dragLine = svgG.append('svg:path')
.attr('class', 'link dragline hidden')
.attr('d', 'M0,0L0,0')
.style('marker-end', 'url(#mark-end-arrow)');
// svg nodes and edges
thisGraph.paths = svgG.append("g").selectAll("g");
thisGraph.circles = svgG.append("g").selectAll("g");
thisGraph.drag = d3.behavior.drag()
.origin(function(d){
return {x: d.x, y: d.y};
})
.on("drag", function(args){
thisGraph.state.justDragged = true;
thisGraph.dragmove.call(thisGraph, args);
})
.on("dragend", function() {
// todo check if edge-mode is selected
});
// listen for key events
d3.select(window).on("keydown", function(){
thisGraph.svgKeyDown.call(thisGraph);
})
.on("keyup", function(){
thisGraph.svgKeyUp.call(thisGraph);
转为 Typescript(Angular2):
import * as D3 from 'd3';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
title = 'app works!';
private graphCreator : any;
private defs : any;
ngOnInit() {
this.Init();
}
private initGraph(svg:any,nodes:any,edges:any){
this.graphCreator=this;
this.graphCreator.idct=0;
this.graphCreator.nodes = nodes|| [];
this.graphCreator.edges = edges || [];
this.graphCreator.state = {
selectedNode: null,
selectedEdge: null,
mouseDownNode: null,
mouseDownLink: null,
justDragged: false,
justScaleTransGraph: false,
lastKeyDown: -1,
shiftNodeDrag: false,
selectedText: null
}
this.graphCreator.consts = {
graphClass: null,
activeEditId: null,
selectedClass: null
}
this.graphCreator.svg = svg;
this.graphCreator.svgG = svg.append("g")
.classed(this.graphCreator.consts.graphClass, true);
let svgG = this.graphCreator.svgG;
// svg nodes and edges
this.graphCreator.paths = svgG.append("g").selectAll("g");
this.graphCreator.circles = svgG.append("g").selectAll("g");
this.graphCreator.drag = D3.behavior.drag()
.origin((d)=>{
let data = d as any;
return {x:data.x as number, y:data.y as number};
})
// .origin(function(d){
// return {x: d.x, y: d.y};
// })
.on("drag", function(args){
this.graphCreator.state.justDragged = true;
this.graphCreator.dragmove.call(this.graphCreator, args);
})
.on("dragend", function() {
// todo check if edge-mode is selected
});
// listen for key events
D3.select(window).on("keydown", function(){
this.graphCreator.svgKeyDown.call(this.graphCreator);
})
.on("keyup", function(){
this.graphCreator.svgKeyUp.call(this.graphCreator);
});
private Init() {
let width = window.innerWidth;
let height = window.innerHeight ;
let xLoc = width / 2 - 25,
yLoc = 100;
// initial node data
let nodes = [{title: "new concept", id: 0, x: xLoc, y: yLoc},
{title: "new concept", id: 1, x: xLoc, y: yLoc + 200}];
let edges = [{source: nodes[1], target: nodes[0]}];
/** MAIN SVG **/
let svg = D3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
this.initGraph(svg,nodes,edges);
// this.graphCreator.setIdCt(2);
// this.graphCreator.updateGraph();
}
这段代码既不绘制,也不会生成错误。当我按下键盘按钮触发键盘事件时,会出现这个错误:
EXCEPTION: this.graphCreator is undefined
所以我认为这不是正确的做法。我哪里做错了?
我可以以哪种方式在 TypeScript 中使用这种类型的函数?
svg.on("mousedown", function(d){thisGraph.svgMouseDown.call(thisGraph, d);});
谢谢你,也为所有这些问题道歉。
答案#1
为了在 TypeScript 中绑定事件,你需要将对象与事件绑定,将该行替换为以下代码。
// listen for key events
D3.select(window).on("keydown", function(){
this.graphCreator.svgKeyDown.call(this.graphCreator).bind(this);
})
.on("keyup", function(){
this.graphCreator.svgKeyUp.call(this.graphCreator).bind(this);
});
