Search code examples
javascriptd3.jsstrict

getBBox error when "use strict"


When
"use strict";

is active for my D3JS force network graph, I am unable to use this.getBBox(); to rotate the edge label text in a force network graph using the code:

edgelabels.attr('transform',function(d,i){
  if (d.target.x<d.source.x){
    bbox = this.getBBox();
    rx = bbox.x+bbox.width/2;
    ry = bbox.y+bbox.height/2;
    return 'rotate(180 '+rx+' '+ry+')';
  }
  else { return 'rotate(0)'; }
});

If I disable "use strict;" my code runs without error and the label is rotated correctly. Fiddle: https://jsfiddle.net/NovasTaylor/cnaqaxnh/

I based my original code on this block: http://bl.ocks.org/jhb/5955887

How can my code be fixed to run using "use strict;" either with getBBox() or an alternative to getBBox()?


Solution

  • The problem here is not getBBox(), but the lack of var: in non-strict mode, the assignment to an undeclared variable considers that variable to be global. However, that won't work in strict mode.

    If you look at the MDN page about strict mode:

    First, strict mode makes it impossible to accidentally create global variables. In normal JavaScript mistyping a variable in an assignment creates a new property on the global object and continues to "work" (although future failure is possible: likely, in modern JavaScript). Assignments which would accidentally create global variables instead throw in strict mode. (emphasis mine)

    So, instead of:

    edgelabels.attr('transform', function(d, i) {
        if (d.target.x < d.source.x) {
            bbox = this.getBBox();
            rx = bbox.x + bbox.width / 2;
            ry = bbox.y + bbox.height / 2;
            return 'rotate(180 ' + rx + ' ' + ry + ')';
        } else {
            return 'rotate(0)';
        }
    });
    

    It should be:

    edgelabels.attr('transform', function(d, i) {
        if (d.target.x < d.source.x) {
            var bbox = this.getBBox();
            var rx = bbox.x + bbox.width / 2;
            var ry = bbox.y + bbox.height / 2;
            return 'rotate(180 ' + rx + ' ' + ry + ')';
        } else {
            return 'rotate(0)';
        }
    });
    

    Here is the updated fiddle: https://jsfiddle.net/onnoqyp4/