Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

D3 Integration with Angular: "Error: Invalid value for <rect> attribute x"

I'm attempting to bind SVG attributes using AngularJS. I have the following code for a resize handle of a shape:

// S handle.
var s_handle = d3.select(document.createElementNS("http://www.w3.org/2000/svg", "rect"))
    .attr("id", "s-resize")
    .attr("x", "{{(objects['" + id + "'].w - (scope.dragHandle.width / 2))}}")
    .attr("y", "{{(objects['" + id + "'].h - (scope.dragHandle.width / 2))}}")
    .attr(scope.dragHandle)
    .attr("cursor", "s-resize")
    .call(sresize);              

$compile(s_handle.node())(scope);
element.append(s_handle);

When I run this code, I get the following error:

Error: Invalid value for <rect> attribute x="{{(objects['9b320170-6365-4f40-801d-a7a5c6b936f9'].w - (scope.dragHandle.width / 2))}}" d3.min.js:1
Error: Invalid value for <rect> attribute y="{{(objects['9b320170-6365-4f40-801d-a7a5c6b936f9'].h - (scope.dragHandle.width / 2))}}" d3.min.js:1

I tried removing the append step to isolate the issue - and it looks like the issue actually happens when I set the x and y attributes, even before the Angular compile stage.

Note that I have this method working with another SVG object using the transform attribute, which natively accepts a string.

Has anyone run into this problem before? Are there any solutions? Thank you.

Edit: Been stepping through and it looks like $compile` isn't actually changing the element at all. Could this be because the element is invalid?


1 Answers

Looks like this was related to this issue: https://github.com/angular/angular.js/pull/2061

It was solved in that issue as well.

SVG elements use an XML-based schema, and are namespaced, and as such have validation rules. Certain attributes can't take an Angular interpolated directive because they expect a numeric value, and the browser validates this before Angular ever has a chance to catch it (even if the element is created and not appended to the DOM yet).

If anyone runs into this issue, hopefully this answer will help.