I am trying to render some SVG with AngularJS but I can't dynamically change the viewbox of the svg element.
Angular renders a 'viewbox' attribute, but browsers expect a 'viewBox' attribute. So the result is:
<svg height="151px" width="1366px" viewBox="{{ mapViewbox }}" viewbox="-183 425 1366 151">
How can I get the result I expect:
<svg height="151px" width="1366px" viewBox="-183 425 1366 151">
Thanks.
See if this directive works:
app.directive('vbox', function() {
return {
link: function(scope, element, attrs) {
attrs.$observe('vbox', function(value) {
element.attr('viewBox', value);
})
}
};
});
HTML:
<svg height="151px" width="1366px" vbox="{{ mapViewbox }}">
Plnkr. You'll need to "Inspect element" or "View source" to see the svg tag.
Update: If your app includes jQuery, see Does the attr() in jQuery force lowercase?
@Niahoo found that this worked if jQuery is included (he made an edit to this post, but for some reason, other SO moderators rejected it... I liked it though, so here it is):
element.get(0).setAttribute("viewBox", value);
The proposed solution didn't work. I'm no javascript pro but this did.
app.directive('vbox', function () {
return {
link: function (scope, element, attrs) {
attrs.$observe('vbox', function (value) {
element.context.setAttribute('viewBox', value);
})
}
};
});
Something like this in a directive linking function (imagine a scope with the variables used):
var svg = $compile(
$interpolate('<svg width="{{w}}" height="{{h}}" class="vis-sample" id="vis-sample-{{$id}}" viewBox="0 0 {{w}} {{h}}" preserveAspectRatio="xMidYMid meet"></svg>')( scope )
)( scope );
The key is using $interpolate before $compile. There has to be a better solution but this is the most direct option I know of for single-pass templates where the variables are all available initially.