dstyle
dstyle

Reputation: 68

Convert d3 event from Javascript to Typescript (Angular2)

I'm new to Typescript and Angular 2. What I'm trying to do is create an Angular2 component that includes a d3js tool click here, anyway I am having some problems rewriting to Typescript.

For example, is this a good way to rewrite this piece of code?

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

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

This code doesn't draw and doesn't generate error. When I push a keyboard button for the keyboardevent, this error appears:

EXCEPTION: this.graphCreator is undefined

So I think that isn't right way to do this. Where did I go wrong?

In which way can I use this type of function in Typescript?

 svg.on("mousedown", function(d){thisGraph.svgMouseDown.call(thisGraph, d);});

Thank you and sorry for all these questions.

Upvotes: 2

Views: 985

Answers (1)

Rohit  Sthapit
Rohit Sthapit

Reputation: 474

In order to bind the event in typescript u need to bind the object with the event replace the line with the following code.

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

Upvotes: 1

Related Questions