Quick SVG help

A place to discuss the implementation and style of computer programs.

Moderators: phlip, Moderators General, Prelates

Quick SVG help

Postby EvanED » Thu Apr 26, 2012 11:22 pm UTC

Quick version of question: can I include a bitmapped image in an SVG file somehow? Some equivalent of the <img> tag? I'm not very familiar with the format.


Longer version of question, so you can spot "better way to do this" opportunities: I'm drawing pictures of finite automata using Graphviz Dot, using SVG output. I'd like to modify the output in an automatable way to add mouse hover events to the nodes to display some extra information. This extra information is a normal PNG file right now. (It's *conceivable* that I could output SVG here but that'd take some learning about the format then engineering.) Right now I can hide and display the <text> nodes that Dot puts in there.

Edit: never mind. Found the <image> element. (That's really hard to Google for, in my defense.)
EvanED
 
Posts: 3767
Joined: Mon Aug 07, 2006 6:28 am UTC
Location: Madison, WI

Re: Quick SVG help

Postby EvanED » Fri Apr 27, 2012 4:28 am UTC

[Double-posting to mark this is new because I have another question, but don't want to start a new thread. I could probably figure out how do do this with some more work, but I'm not very knowledgeable in web technologies and I know there are people here who know Javascript and the DOM and such much better, so I figured I'd ask.]

OK, so I need a little more help. I decided to take a slightly different approach, which is to write an HTML page that uses <object> to include the SVG file, then run the script from that. The HTML page is responsible for displaying the tooltip-style popup. (A huge attraction to this is no changes to the SVG should be needed, not counting DOM modifications by the Javascript.)

Here's a quick demo of something that works now. (In Firefox. See below for caveats.) Note that as you mouse over the nodes, the node label becomes visible as well as a grey-backgrounded "This is a tooltip" message at the top. (Ignore the fact that the latter starts visible for now.) The tooltip message is from the HTML, not SVG.

Each node corresponds to a group (<g>) in the SVG file; the page sets onmouseover and onmouseout events on that group node. They set the style.visibility flag of both SVG elements and the HTML-based tooltip.

However, if I try to change the location of the tooltip by using style.pageX and style.pageY, as the mouse moves the tooltip and node label flicker a lot, and when the mouse stops they are usually not visible even if the cursor is over a node. Here is a demo of that.

The only change between them is the addition of the
Code: Select all
                              label.style.top=e.pageY + 'px';
                              label.style.left=e.pageX + 'px';

lines.

I put an alert in onmouseout and saw it was firing a lot in both versions when the cursor is not leaving the element. I discovered that the events were being fired for both the text and ellipse and that was causing the problem, so I tried just putting the event on the ellipse. This works rather better, but if the user mouses over the text then that triggers the mouseout event for the ellipse and so basically the same problem persists.

First, how can I fix this? Second, what can I do to get this to work in other browsers? It doesn't work at all in Chrome or IE.

Edit: Hah, figured out the problem again: the tooltip pops up under the mouse -- so then the mouseout event fires and kills it, then it pops back up, etc. I offset the popup again and it worked.

Still, my second question applies as well as any "wtf why did you do that" comments. :-)
EvanED
 
Posts: 3767
Joined: Mon Aug 07, 2006 6:28 am UTC
Location: Madison, WI

Re: Quick SVG help

Postby Jplus » Fri Apr 27, 2012 9:28 am UTC

You should probably have a look at Inkscape (which allows you to embed bitmaps in your svg) and Raphaël (which does the kind of thing you're trying to achieve in a much more convenient and much more portable way).
Hey, like coding? Perhaps you should check out the red spider project.
Feel free to call me Julian. J+ is just an abbreviation.
User avatar
Jplus
 
Posts: 1091
Joined: Wed Apr 21, 2010 12:29 pm UTC

Re: Quick SVG help

Postby headprogrammingczar » Fri Apr 27, 2012 12:25 pm UTC

The SVG spec is remarkably readable. You should bookmark it.
<quintopia> You're not crazy. you're the goddamn headprogrammingspock!
<Weeks> You're the goddamn headprogrammingspock!
<Cheese> I love you
User avatar
headprogrammingczar
 
Posts: 2953
Joined: Mon Oct 22, 2007 5:28 pm UTC
Location: Beaming you up

Re: Quick SVG help

Postby EvanED » Fri Apr 27, 2012 2:18 pm UTC

Jplus wrote:You should probably have a look at Inkscape (which allows you to embed bitmaps in your svg) and Raphaël (which does the kind of thing you're trying to achieve in a much more convenient and much more portable way).

The SVG component is "non-negotiable" as the non-popup part is produced from a Dot file. (If Dot has another useful output option I'd listen to that as well.) The key point is that it's automatable -- e.g., I don't want to have to load up Inkscape to do it (unless that too can be done completely automatically, though learning yet another scripting language is not so appealing).

For a similar reason, Raphael, nice as it looks, also won't work for generating the base image (though maybe I could use it for the popups). Doing something like walking the SVG DOM to create Raphael components is also not so appealing.

Anyway, I've got something that works-ish. I think this could be a somewhat generally-useful tool though, so I might try to wrap it up and ask for further comments after it's more presentable.
EvanED
 
Posts: 3767
Joined: Mon Aug 07, 2006 6:28 am UTC
Location: Madison, WI

Re: Quick SVG help

Postby Xanthir » Fri Apr 27, 2012 5:25 pm UTC

First, mouseout happens *all the fucking time*. You'll get a mouseout event if you go from your element to a *child*, which is really annoying. mouseout is basically useless. (Same with mousein - it fires if you go from a child to the element.) IE got it right with their mouseenter/mouseleave events, which take the tree into account. Those are being specced and copied now.

To do mouseout right, always check event.relatedTarget. (It's useful for a bunch more events, too.) This still isn't trivial, as if the mouse moves fast enough it can "skip" elements, and so you have to handle some unexpected transitions as well. You could have used this, with some logic, to make your original popup situation work, by tracking when you mouseout into the popup and leaving it up then.

When possible, I try to just use CSS and the :hover pseudo, putting things that I want to "pop up" as children of a useful container. That way the browser handles all the bullshit for me. If you can do that, go for it - it's less fragile and a lot simpler.


Tangent: rather than using <object> to include an SVG in an HTML file, try one of these:
  • use <iframe> - that's basically what <object> does in this situation, except the behavior is generally a touch saner.
  • just include the <svg> directly in the HTML - all the modern browsers support this.
  • just use a plain SVG file, running the <script> inside of it. Being "real" XML, you've gotta use a little more incantation to include a <script> (the @type is required, as is the CDATA thing, I believe.), but otherwise there's not a lot of difference between running JS in an SVG file versus an HTML file.


If you want a good, cross-browser way to determine an event's mouse coords, see PPK's event properties overview. Only screenX/Y are fully interoperable, but depending on what you're doing with those coords, you may have to massage the information slightly to get what you need out of it. The page shows you the compat story for all 6 of the coord pairs, though, so if you have lesser compat requirements you may be able to use something else.
(defun fibs (n &optional (a 1) (b 1)) (take n (unfold '+ a b)))
User avatar
Xanthir
My HERO!!!
 
Posts: 4002
Joined: Tue Feb 20, 2007 12:49 am UTC
Location: The Googleplex

Re: Quick SVG help

Postby Robert'); DROP TABLE *; » Fri Apr 27, 2012 6:00 pm UTC

EvanED wrote:The SVG component is "non-negotiable" as the non-popup part is produced from a Dot file. (If Dot has another useful output option I'd listen to that as well.)

This dot?
http://graphviz.org/content/output-formats
...And that is how we know the Earth to be banana-shaped.
User avatar
Robert'); DROP TABLE *;
 
Posts: 633
Joined: Mon Sep 08, 2008 6:46 pm UTC
Location: in ur fieldz

Re: Quick SVG help

Postby EvanED » Fri Apr 27, 2012 7:13 pm UTC

Xanthir wrote:First, mouseout happens *all the fucking time*. You'll get a mouseout event if you go from your element to a *child*, which is really annoying. mouseout is basically useless. (Same with mousein - it fires if you go from a child to the element.) IE got it right with their mouseenter/mouseleave events, which take the tree into account. Those are being specced and copied now.

To do mouseout right, always check event.relatedTarget. (It's useful for a bunch more events, too.) This still isn't trivial, as if the mouse moves fast enough it can "skip" elements, and so you have to handle some unexpected transitions as well. You could have used this, with some logic, to make your original popup situation work, by tracking when you mouseout into the popup and leaving it up then.

When possible, I try to just use CSS and the :hover pseudo, putting things that I want to "pop up" as children of a useful container. That way the browser handles all the bullshit for me. If you can do that, go for it - it's less fragile and a lot simpler.

I'll look into it. Thanks for the suggestions.

Tangent: rather than using <object> to include an SVG in an HTML file, try one of these:
  • use <iframe> - that's basically what <object> does in this situation, except the behavior is generally a touch saner.
  • just include the <svg> directly in the HTML - all the modern browsers support this.
  • just use a plain SVG file, running the <script> inside of it. Being "real" XML, you've gotta use a little more incantation to include a <script> (the @type is required, as is the CDATA thing, I believe.), but otherwise there's not a lot of difference between running JS in an SVG file versus an HTML file.

I discovered the second one later. I would eventually like to make everything one file, so that or the third are attractive longer term. For now, I don't want to modify the SVG so that rules out #3.

My eventual goal though is to use pydot or something (I haven't actually done more than look at pydot's Google Code page) to write a program that takes a Dot description with extensions (e.g. an additional 'popup' attribute for nodes and edges) and uses dot behind the scenes and outputs one single file that you can load up in a web browser and have it do cool stuff.

If you want a good, cross-browser way to determine an event's mouse coords, see PPK's event properties overview. Only screenX/Y are fully interoperable, but depending on what you're doing with those coords, you may have to massage the information slightly to get what you need out of it. The page shows you the compat story for all 6 of the coord pairs, though, so if you have lesser compat requirements you may be able to use something else.

I'll check that out too, though right now I'm mostly just interested in "works in something that I have", and I'm there. :-)

Robert'); DROP TABLE *; wrote:
EvanED wrote:The SVG component is "non-negotiable" as the non-popup part is produced from a Dot file. (If Dot has another useful output option I'd listen to that as well.)

This dot?
http://graphviz.org/content/output-formats

Yes.
EvanED
 
Posts: 3767
Joined: Mon Aug 07, 2006 6:28 am UTC
Location: Madison, WI

Re: Quick SVG help

Postby PM 2Ring » Sat Apr 28, 2012 5:57 am UTC

EvanED wrote:I'm drawing pictures of finite automata using Graphviz Dot, using SVG output. I'd like to modify the output in an automatable way to add mouse hover events to the nodes to display some extra information. This extra information is a normal PNG file right now. (It's *conceivable* that I could output SVG here but that'd take some learning about the format then engineering.)

I suggest doing a search on SVG animation, there seems to be a fair amount of info on it floating around the Net. Sorry I don't have more concrete info to give you as I haven't played with SVG animation yet myself, although I have written a few programs (in awk and Python) to generate Graphviz Dot files and I've also written Python and JavaScript programs that generate simple SVG files.

It's a pity that the extra info has to be an image; text tooltips in SVG are easy to do. :)

If you embed the SVG into HTML, you could possibly use HTML5 Canvas to display the extra info, but I guess a pure SVG approach would be neater and more sensible.
User avatar
PM 2Ring
 
Posts: 2593
Joined: Mon Jan 26, 2009 3:19 pm UTC
Location: Mid north coast, NSW, Australia


Return to Coding

Who is online

Users browsing this forum: No registered users and 10 guests