网站搜索

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);
                  });