Converting D3 Blocks to Enyo Component

183 views Asked by At

I am basically trying to encapsulate the functionality from rkirsling's blocks inside an Enyo object so that I can reuse it. I started by removing global variables and switching them out for published attributes. I am able to get the balls to show, but they are all rendered in one spot and there are no other functionalities. I can't add more balls or draw lines from one to the other.

My thoughts are that I am doing something incorrectly in restart(). I left the majority of the code in jsfiddle since I don't want a massive wall of code, but I've copied what I believe to be the important parts.

http://jsfiddle.net/jtPvU/

Edit: It looks like tick() is the issue. The way I am referencing path and circle seems to be the issue.

enyo.kind({
  name: "D3Block",
  published: {
    // mouse event vars
    selected_node: null,
    selected_link: null,
    mousedown_link: null,
    mousedown_node: null,
    mouseup_node: null,
    svg: "",
    path: "",
    circle: "",
    links: [],
    nodes: [],
    colors: null,
    force: null,
    drag_line: null,
    lastNodeId: 0
  },
  initialize: function(clientContainer){
    this.inherited(arguments);
    var width  = 500,
        height = 500;
    this.colors = d3.scale.category10();
    this.svg = d3.select(clientContainer)
      .append('svg')
      .attr('width', width)
      .attr('height', height);

    // set up initial nodes and links
    //  - nodes are known by 'id', not by index in array.
    //  - reflexive edges are indicated on the node (as a bold black circle).
    //  - links are always source < target; edge directions are set by 'left' and 'right'.
    this.nodes = [
        {id: 0, reflexive: false},
        {id: 1, reflexive: true },
        {id: 2, reflexive: false}
      ]
    this.lastNodeId = 2;

      this.links = [
        {source: this.nodes[0], target: this.nodes[1], left: false, right: true },
        {source: this.nodes[1], target: this.nodes[2], left: false, right: true }
      ];

    // init D3 force layout
    this.force = d3.layout.force()
        .nodes(this.nodes)
        .links(this.links)
        .size([width, height])
        .linkDistance(150)
        .charge(-500)
        .on('tick', this.tick())

    // define arrow markers for graph links
    this.svg.append('svg:defs').append('svg:marker')
        .attr('id', 'end-arrow')
        .attr('viewBox', '0 -5 10 10')
        .attr('refX', 6)
        .attr('markerWidth', 3)
        .attr('markerHeight', 3)
        .attr('orient', 'auto')
      .append('svg:path')
        .attr('d', 'M0,-5L10,0L0,5')
        .attr('fill', '#000');

    this.svg.append('svg:defs').append('svg:marker')
        .attr('id', 'start-arrow')
        .attr('viewBox', '0 -5 10 10')
        .attr('refX', 4)
        .attr('markerWidth', 3)
        .attr('markerHeight', 3)
        .attr('orient', 'auto')
      .append('svg:path')
        .attr('d', 'M10,-5L0,0L10,5')
        .attr('fill', '#000');
    // line displayed when dragging new nodes
    this.drag_line = this.svg.append('svg:path')
      .attr('class', 'link dragline hidden')
      .attr('d', 'M0,0L0,0');

    // handles to link and node element groups
    this.path = this.svg.append('svg:g').selectAll('path');
    this.circle = this.svg.append('svg:g').selectAll('g');


    // app starts here
    this.svg.on('mousedown', this.mousedown())
      .on('mousemove', this.mousemove())
      .on('mouseup', this.mouseup());
    // d3.select(window)
    //   .on('keydown', this.keydown())
    //   .on('keyup', this.keyup());
    this.restart();
  },
  tick: function() {
    console.log("TICK TICK");
    var svg = d3.select(this.clientContainer.hasNode());
    console.log(svg);
    var path = this.path;
    var circle = this.circle;
    // if(!path || !circle){return};


    path.attr('d', function(d) {
      var deltaX = d.target.x - d.source.x,
          deltaY = d.target.y - d.source.y,
          dist = Math.sqrt(deltaX * deltaX + deltaY * deltaY),
          normX = deltaX / dist,
          normY = deltaY / dist,
          sourcePadding = d.left ? 17 : 12,
          targetPadding = d.right ? 17 : 12,
          sourceX = d.source.x + (sourcePadding * normX),
          sourceY = d.source.y + (sourcePadding * normY),
          targetX = d.target.x - (targetPadding * normX),
          targetY = d.target.y - (targetPadding * normY);
      return 'M' + sourceX + ',' + sourceY + 'L' + targetX + ',' + targetY;
    });

    circle.attr('transform', function(d) {
      return 'translate(' + d.x + ',' + d.y + ')';
    });
  }
});
1

There are 1 answers

3
Pre101 On BEST ANSWER

I suspect that your use of tick is supposed to be as a callback. You probably want to use enyo.bind(). Right now, you're passing the return value of tick to the 'on' event.