Injecting SVG with directives

5,809 views
Skip to first unread message

Jorek

unread,
Aug 17, 2012, 7:02:04 AM8/17/12
to ang...@googlegroups.com
Hello,
Thank you for this great framework.
I'm trying to build an SVG-based GUI with AngularJS.
Please see a simplified example with inlined SVG: http://jsfiddle.net/jorek/afnjB/
It appears to render a valid HTML+SVG code which I can see in the Inspector. I can copy this code, paste into "raw" HTML file and it renders fine (three black rectangles).
However, when managed by Angular, nothing is visible. Am I missing something?

Greetings,
Piotr J.

Boris Gurvich

unread,
Aug 17, 2012, 8:35:19 AM8/17/12
to ang...@googlegroups.com
Interesting, it appears that using directive template does not render SVG
contents.

Is this acceptable for your purposes?
http://jsfiddle.net/afnjB/41/

Jorek

unread,
Aug 17, 2012, 8:59:28 AM8/17/12
to ang...@googlegroups.com
Thanks for reply. This is what I also suspect: rendering of new SVG content is problematic. Whereas manipulation of existing SVG nodes is not. I can bind them, repeat, filter etc. but not append new ones.
I'm going to build a complicated, recursive structure for rendering tree-like data. I started from a code like your one (and it worked), but that won't do for the entire project; I need reusable blocks.
Other things that I tried with similar effect:
- Templates embedded in <script>
- <ng-include>.

There is one ugly hack that worked somehow, building a DOM like this: <hml> <svg> (SVG tags) <foreignObject> <svg> <ng-include> (more SVG tags)
Unfortunately, foreignObject is an SVG tag not widely implemented (i.e. IE :). Not to mention that it "escapes" from SVG here only to "dive" into it again.
But judging from this hack, I suspect that there is some problem in the content types, HTML vs. SVG, when it comes to embedding DOM elements by Angular.

Peter Hart

unread,
Aug 18, 2012, 9:24:16 PM8/18/12
to ang...@googlegroups.com
Jorek, I've recently started playing with angular, and I've been looking at SVG as well. What I've seen, looking in the chrome dev tools, is that the created node is not an SVG node, but a plain HTML node. I tried a number of different things, and came up with the following, which is appears to work for the limited case I have:


Basically, it is replacing the 'template' object in the compile function for another object. Part of the problem, I think, is that the HTML5 handling of SVG means that outside of an SVG object, the rect is just a 'normal' HTML object.

I also tried setting the template to a pre-built angular.element object, but it tried to convert it to a string, and that failed miserably....

I also tried adding an 'XML' prolog to the template, but angular complained because the template had too many roots. 

Finally, I tried wrapping the svg elements inside an SVG element, and in the compile method 'transforming' the DOM to remove the parent. However, that didn't really work, as the values of attributes weren't being updated (but debugging does at least show that the 'right' node types were being created).


I was actually interested in trying to create some directives that could generate either SVG or equivalent VML structures (as for a project at work I'd need to be able to support IE 8 for most users), but my initial investigation makes it seem more difficult than I was hoping - I know I could just use Raphael, but pulling in another library to support a couple of simple diagrams seems like overkill, particularly when angular looks like it supports all the other functionality I'd like.

Note that this approach doesn't copy any child elements, but in principle it could be extended to do handle this, and even convert them appropriately. I was actually about to post a question to the list about how to handle inserting 'namespaced' elements from within a template - so far this is the only approach that I've found that sort of worked, but it seems to be fighting the framework rather than using it :-(. If anyone has a better solution, I'd love to hear it....

    -Peter

Jorek

unread,
Aug 20, 2012, 3:42:57 PM8/20/12
to ang...@googlegroups.com
Thanks, that gives more insight. But still, as you said, it's like fighting the framework...

Are there more Angular Ninjas to speak about this? :-)

Sharif Ghazzawi

unread,
Mar 20, 2013, 1:06:35 PM3/20/13
to ang...@googlegroups.com, jo...@brainmapper.net
Has anyone found a cleaner way of doing this?

Leo Shmuylovich

unread,
May 3, 2013, 11:24:04 PM5/3/13
to ang...@googlegroups.com, cinp...@gmail.com
Hi Peter, 

Thanks for your post. I tried something off of your idea, where the template of the directive has an svg wrapper, and the linker function of the directive replaces the element with the child node. Check it out here:
I think the issue of the SVG element showing up as a simple HTML element without these gymnastics is not an angular issue, but an SVG/HTML issue, and would arise if we were going to try to use jQuery alone to inject svg elements in. 

Do you see any reason why this has to be done in the compile phase? I got it to work in the linker function alone but I may be missing something!

Best, 
Leo

Leo Shmuylovich

unread,
May 3, 2013, 11:25:37 PM5/3/13
to ang...@googlegroups.com, cinp...@gmail.com
Also, with a newer version of angular, the attributes in the template should be ng-attr-height= and ng-attr-width=
Check out this github issue for details: https://github.com/angular/angular.js/pull/2061

Marcus

unread,
May 4, 2013, 4:28:47 AM5/4/13
to ang...@googlegroups.com, cinp...@gmail.com
Hi,

I'm not sure what I am doing here, but please take a look at:


You will notice I removed the use of variable {{size}} from the "square" directive, but I added new variables that affect the SVG "rect" drawing.

What is interesting is that you can change these numbers and the RED box changes with it (size and position)

I don't know enough about directives to even make one, but here I see that I could control a SVG object just by changing the numbers.  Probably your directive is driving this change, just by updating the screen ?

THIS IS AWESOME -- BECAUSE ITS SO EASY TO DRAW WITH ANY DATA CHANGES.

Marcus

Marcus

unread,
May 4, 2013, 4:35:14 AM5/4/13
to ang...@googlegroups.com, cinp...@gmail.com
Hi again,

I just realized that the directive doesn't have any influence.  

I deleted the .(directive...) and the SVG "rect" changes with manual changes on the variables.


Marcus

Jason More

unread,
Jun 13, 2013, 5:20:36 PM6/13/13
to ang...@googlegroups.com, jo...@brainmapper.net
For anyone who comes across this, I have a working example with SVG and angular templates. Its based on the conversations in this thread.

Scott MacDonald

unread,
Jun 22, 2013, 11:48:49 PM6/22/13
to ang...@googlegroups.com, jo...@brainmapper.net
Would a project member be able to comment on this?  I seem to be running into the same problem.  

Thanks!
Scott
Message has been deleted

Evan Zamir

unread,
Jun 23, 2013, 3:09:35 PM6/23/13
to ang...@googlegroups.com, jo...@brainmapper.net
Sorry I meant to post this fiddle:


Using D3, this is fairly easy.


On Friday, August 17, 2012 4:02:04 AM UTC-7, Jorek wrote:

Scott MacDonald

unread,
Jun 24, 2013, 2:25:21 PM6/24/13
to ang...@googlegroups.com, jo...@brainmapper.net
That fiddle does not address the question.  The problem is having nested directives which contain SVG elements.  Also your solution depends on d3 which is a rather large dependency.

Tom Skinner

unread,
Jun 27, 2013, 11:07:55 AM6/27/13
to ang...@googlegroups.com, jo...@brainmapper.net
awesome angular-svg service. just what I was looking for. Thanks!

ste...@activitystream.com

unread,
Aug 30, 2013, 9:43:22 AM8/30/13
to ang...@googlegroups.com, jo...@brainmapper.net
Thank you!

I think you just about saved my sanity :)

john.tiger

unread,
Aug 30, 2013, 12:00:57 PM8/30/13
to ang...@googlegroups.com
plunkr does not display on debian chromium - I hope people working on it can fix this - it does display okay on debian firefox (iceweasel). 
--
You received this message because you are subscribed to the Google Groups "AngularJS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to angular+u...@googlegroups.com.
To post to this group, send email to ang...@googlegroups.com.
Visit this group at http://groups.google.com/group/angular.
For more options, visit https://groups.google.com/groups/opt_out.

pur...@gmail.com

unread,
Sep 20, 2013, 5:44:59 AM9/20/13
to ang...@googlegroups.com, jo...@brainmapper.net
I have a slighty different use-case where this SVG Service doesn't seem to work.

There are two SVG directives and one is used within the other. Both are compiled with the SVG Service, but the nodes are still HTMLElements...

Do you have any idea what I could do to fix this?

Thanks.

Jason More

unread,
Sep 20, 2013, 8:56:21 AM9/20/13
to ang...@googlegroups.com, jo...@brainmapper.net
Sorry, I don't see what the problem is. I've actually abandoned this train of thought and now use angular.js with jquery.svg.js. 

http://plnkr.co/edit/Xk8wM3?p=preview

Its been working pretty good for me, but eventually I'd like to go back to a stricter compile method.


--
You received this message because you are subscribed to a topic in the Google Groups "AngularJS" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/angular/nP5JSuRuBMw/unsubscribe.
To unsubscribe from this group and all its topics, send an email to angular+u...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages