Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use `this` and `_this` (fat arrow) using coffeescript?

I'm using the D3 function each, which accepts a callback function and calls it passing this as argument, but I need to access both this and _this. This is the coffeescript code:

@x = d3.scale.ordinal().domain(d3.range(@model.geneExpressions[0].length)).rangeBands([0, width])    

getRow = (row) =>
    cell = d3.select(this).selectAll(".cell")
        .data(row)
      .enter().append("rect")
        .attr("x", (d,i) => @x(i))    

rows = @heatmap.selectAll(".row")
    .data(@model.geneExpressions)
  .enter().append("g")
    .each(getRow)                    

and the javascript that it generates:

    var _this = this;    

this.x = d3.scale.ordinal().domain(d3.range(this.model.geneExpressions[0].length)).rangeBands([0, width]);    

getRow = function(row) {
        var cell;
        return cell = d3.select(_this).selectAll(".cell").data(row).enter().append("rect").attr("x", function(d, i) {
          return _this.x(i);
        })
      };    

rows = this.heatmap.selectAll(".row").data(this.model.geneExpressions).enter().append("g").attr("class", "row").each(getRow);

How can I get coffeescript to use this instead in this line and leave everything the same?:

return cell = d3.select(this) ...

The problem is that I can't pass @x as an argument to each and use the thin arrow instead of the fat arrow (because then I couldn't access @x), unless I rewrite the D3 function, which seems overkill.

like image 353
nachocab Avatar asked Jun 07 '12 23:06

nachocab


1 Answers

So you have this structure:

@x = ...
getRow = (row) =>
    d3.select(@)...attr('x', (d, i) => @x(i))
rows = ...each(getRow)

But you need getRow to be a normal -> function so that it gets the DOM element as @ and you need the attr callback to be a bound => function so @x works, right?

Two possibilities immediately come to mind:

  1. Use the CoffeeScript form of the usual JavaScript var that = this; trick.
  2. Use a named bound function for the attr callback.

The first one looks something like this:

that   = @
getRow = (row) ->
    cell = d3.select(@)
        .selectAll(".cell")
        .data(row)
        .enter().append("rect")
        .attr("x", (d,i) -> that.x(i))    

The second goes like this:

x_at_i = (d, i) => @x(i)
getRow = (row) ->
    cell = d3.select(@)
        .selectAll(".cell")
        .data(row)
        .enter().append("rect")
        .attr("x", x_at_i)
like image 131
mu is too short Avatar answered Sep 27 '22 17:09

mu is too short