ANN: Forked version of jquery tipsy that works with embedded svg content

2,523 views
Skip to first unread message

Justin Donaldson

unread,
Sep 2, 2011, 8:57:01 PM9/2/11
to d3...@googlegroups.com
Followed Mike et. al's advice and info about svg positioning, and came up with a forked version of tipsy. 
This should work interchangeably with normal html elements.

Let me know if this works for others, and I'll send a pull request to the author:
https://github.com/bigmlcom/tipsy

Best,
-Justin

--
Justin Donaldson, BigML, Inc.
o: 313-31BIGML | c: 919-BUZZJJD

Ricardo

unread,
Sep 3, 2011, 12:53:52 PM9/3/11
to d3-js
I'm going to take close look at it and give you feedback. I was
actually working on something similar that didn't depend on tipsy to
do exactly the same thing (started calling it woozy...). I'm also
creating a behavior called 'nearby', similar to d3.behavior.zoom, that
is called to label elements in an svg scene. Let's see how they all
play together.

- Ricardo

Ricardo

unread,
Sep 3, 2011, 2:07:37 PM9/3/11
to d3-js
I just did a quick test and it works great. Congratulations! You can
see my test here:

http://bl.ocks.org/1191530

There is a very quick way to translate all svg elements with titles to
use this tipsy implementation using:

$(document).ready(function() {
$('svg title').parent().tipsy({
gravity: 'sw',
html: true,
title: function() { return $(this).find('title').text(); }
});
});

Two comments:

1. The sw gravity does not seem to be working.
2. What would happen if we had links or something clickable on the
tooltip? This might be a tipsy problem but nevertheless it seems as
something very useful to have.

- Ricardo

On Sep 2, 8:57 pm, Justin Donaldson <donald...@bigml.com> wrote:

Justin Donaldson

unread,
Sep 3, 2011, 10:11:52 PM9/3/11
to d3...@googlegroups.com
Thanks very much for the feedback, quick translation, and demo.

I'll take a look at the sw issue.  There were some other minor issues involving embedding svgs in tables, and with viewports.  I'll try to sort those as well.

I'm pretty sure that tipsy can handle arbitrary html content.  Set the "html" option to true, and you should be good to go:
http://onehackoranother.com/projects/jquery/tipsy/#example-html

Best,
-Justin

Justin Donaldson

unread,
Sep 3, 2011, 10:16:36 PM9/3/11
to d3...@googlegroups.com
Ah... clickable links... now i get it.  The tip disappears too quickly. :)

It looks like you'd have to modify the way that tipsy works.  One approach would be to set delayOut to something like 1-2 seconds.  Then, cancel the timer on hover, and hide the tip on mouseout.  I'll see if I can work that in as some sort of option.

-Justin

Ricardo

unread,
Sep 4, 2011, 4:53:22 PM9/4/11
to d3-js
Labeling is something that everyone will want. Sometimes it can be as
simple as a tooltip, sometimes it will have links, forms or tables.
It would be great to have a one way in which all the labeling code
could be plugged in and everyone can develop their own way to show
them. Tipsy for some, perhaps new ones will emerge. It is like the
newly introduced scale. A great abstraction that simplifies things a
lot. A labeler should be something along the same line as an axis.

- R

On Sep 3, 10:16 pm, Justin Donaldson <donald...@bigml.com> wrote:
> Ah... clickable links... now i get it.  The tip disappears too quickly. :)
>
> It looks like you'd have to modify the way that tipsy works.  One approach
> would be to set delayOut to something like 1-2 seconds.  Then, cancel the
> timer on hover, and hide the tip on mouseout.  I'll see if I can work that
> in as some sort of option.
>
> -Justin
>

Justin Donaldson

unread,
Sep 4, 2011, 8:17:56 PM9/4/11
to d3...@googlegroups.com
Hi Ricardo,

I modified your earlier example to show the changes:
http://bl.ocks.org/1193712

Another set of changes:
  1. Improved the bounding box model. This should fix the minor positioning issues.  Wasn't a problem in your demo, but it would be eventually.
  2. Fixed the js/css that dealt with the nw/sw/etc orientation.
  3. Added a 'hoverlock' option that will prevent the popup from disappearing if it is hovered.  This should let you embed arbitrary interactive html content.  You can click your links now.
I want to make your translation function for title elements the default once svg is detected... still need to straighten that out.

Finally, I'm also noticing that the version of tipsy on git is much different than the one demoed on the website.  I'm worried that the project is in some sort of major  transition.  However, there doesn't seem to be much recent activity, and a ton of open pull requests.  Perhaps the author got interrupted, or had to drop the project for a while.

-Justin





On Sun, Sep 4, 2011 at 1:53 PM, Ricardo <rmarimon%stanforda...@gtempaccount.com> wrote:
Labeling is something that everyone will want.  Sometimes it can be as
simple as a tooltip, sometimes it will have links, forms or tables.
It would be great to have a one way in which all the labeling code
could be plugged in and everyone can develop their own way to show
them.  Tipsy for some, perhaps new ones will emerge.  It is like the
newly introduced scale.  A great abstraction that simplifies things a
lot.  A labeler should be something along the same line as an axis.



Benjamin West

unread,
Sep 5, 2011, 2:14:57 PM9/5/11
to d3...@googlegroups.com
It'd be kind of neat if you could declare a link to the content to
display, rather than procedurally specify a string representing what
should be in the document. The link could be to a document fragment
of the current document, or to some other document. This way,
arbitrary content is provided by HTML/SVG content already in the
document.
-bewest

Ricardo

unread,
Sep 5, 2011, 4:39:44 PM9/5/11
to d3-js
Justin. The example looks great. As for the whole tipsy being out of
sync, I've also noticed it. In fact the tipsy implementation I have
in one of my projects has a tipsy.gif to draw the arrows. From a
conceptual point I'm struggling on wether to do labels the 'tipsy'
way, in which one overrides the effect of the 'title' attribute (html
or svg), or making up something that is more tailored to d3. For now,
I'm gonna go with the tipsy structure, even though I will embed html
in the tooltip sometimes. Let's see how that turns out.

- R

On Sep 4, 8:17 pm, Justin Donaldson <donald...@bigml.com> wrote:
> Hi Ricardo,
>
> I modified your earlier example to show the changes:http://bl.ocks.org/1193712
>
> Another set of changes:
>
>    1. Improved the bounding box model. This should fix the minor positioning
>    issues.  Wasn't a problem in your demo, but it would be eventually.
>    2. Fixed the js/css that dealt with the nw/sw/etc orientation.
>    3. Added a 'hoverlock' option that will prevent the popup from
>    disappearing if it is hovered.  This should let you embed arbitrary
>    interactive html content.  You can click your links now.
>
> I want to make your translation function for title elements the default once
> svg is detected... still need to straighten that out.
>
> Finally, I'm also noticing that the version of tipsy on git is much
> different than the one demoed on the website.  I'm worried that the project
> is in some sort of major  transition.  However, there doesn't seem to be
> much recent activity, and a ton of open pull requests.  Perhaps the author
> got interrupted, or had to drop the project for a while.
>
> -Justin
>
> On Sun, Sep 4, 2011 at 1:53 PM, Ricardo <
>

Ricardo

unread,
Sep 5, 2011, 4:43:04 PM9/5/11
to d3-js
Benjamim you can can create the tooltip based on the d3 data model.
The relevant code would be:

.append("svg:title")
.text(function(d) { return "Bar value: " + d.v; });

But you can certainly do something like

.append("svg:title")
.text(d3.select("#the-element").html());

Which would copy the html content into the title so that it can later
be rendered with the tipsy implementation. Not the most elegant of
solutions, but simple, and easy to change down the road.

- Ricardo

Justin Donaldson

unread,
Sep 5, 2011, 6:31:55 PM9/5/11
to d3...@googlegroups.com
Ok, I had some weirdness with my local copy of the repo when I forked originally.  Not really sure what happened.  I decided to nuke it and manually remerge my changes.  This seems much more up to date now.  A new clone is probably in order.
https://github.com/bigmlcom/tipsy

The latest version should use a tipsy-esque handling of svg titles (i.e. as long as the element has a title child, tipsy will use that, and move the title content to an "original-title" node in order to prevent a double popup).
http://bl.ocks.org/1193712

There's a few wrinkles.  Most browsers will treat svg title attributes the same as title nodes, even though it isn't in the spec.  This can cause further problems if they're both present on the node at the same time.  I'm basically only handling the "correct" case for now (svg has title nodes, html has title attributes).  If you're using the wrong form, you're probably in for some nasty surprises anyways.

I haven't tried anything fancier with this yet, but some more interactive html "panels" should be possible now.

Fwiw, I thought about trying a "more d3 approach" to interactive tooltips and decided against it.   I haven't come up with a use case where you would need d3-style selectors and data mapping for either the tooltip interaction or content.  It didn't make sense adding a d3 dependency where it wasn't really needed.  Jquery, on the other hand, probably is needed for this sort of thing. 

Good luck with your projects, and thanks again,

-Justin

Ricardo

unread,
Sep 5, 2011, 7:52:35 PM9/5/11
to d3-js
I agree that the "d3 approach" is going to be more of a problem than
anything else. Particularly since tipsy will be used on svg and the
rest of the DOM. One tipsy for all of the dom, html, and svg, seems
like a better approach. The fallback to the default title behavior
also has its advantages. Thanks for your help.

- Ricardo

On Sep 5, 6:31 pm, Justin Donaldson <donald...@bigml.com> wrote:
> Ok, I had some weirdness with my local copy of the repo when I forked
> originally.  Not really sure what happened.  I decided to nuke it and
> manually remerge my changes.  This seems much more up to date now.  A new
> clone is probably in order.https://github.com/bigmlcom/tipsy
>
> The latest version should use a tipsy-esque handling of svg titles (i.e. as
> long as the element has a title child, tipsy will use that, and move the
> title content to an "original-title" node in order to prevent a double
> popup).http://bl.ocks.org/1193712
>
> There's a few wrinkles.  Most browsers will treat svg title *attributes* the
> same as title *nodes, *even though it isn't in the spec.  This can cause

Nelson Minar

unread,
Sep 5, 2011, 8:53:41 PM9/5/11
to d3...@googlegroups.com
Personally I'd love to see a lightweight tooltip implementation entirely native to D3, without a jQuery dependency. Nothing too fancy, just the ability to do something a little more styled than the browser's implementation of the svg:title element.

Kyle Foreman

unread,
Sep 6, 2011, 11:01:54 AM9/6/11
to d3...@googlegroups.com
These look really great, thanks so much for implementing this!

Justin Donaldson

unread,
Sep 10, 2011, 10:54:30 PM9/10/11
to Des, d3...@googlegroups.com
Hi Des,

Thanks for trying out the tipsy fork.

The code you gave me was incomplete, and a bit confusing because I see an error that should prevent it from working at all.

You seem to be having problems because you are selecting the title elements directly.  Instead, select the title element's parent.  I designed this way to emulate how tipsy works on normal html elements.  I also get the feeling that class/id markup is not that common for titles.  If the tipsy fork worked on titles, then in some cases it might be necessary (or at least clearer) to add class/id's to titles in order to distinguish them... as you did in your example.  I'd like to avoid that as possible, so selecting the shapes/containers themselves makes more sense to me.

If you really have a need to select titles directly, I can look into modifying the lib to handle both titles and elements with titles.

I made an attempt to finish out your example, and the data looks like it changes appropriately:
http://bl.ocks.org/1209105

 I'm posting this back to the d3.js group, just in case anyone else has these same questions.

Best,
-Justin

On Fri, Sep 9, 2011 at 7:01 PM, Des <lar...@hotmail.com> wrote:
I have implemented a line chart using Tipsy with transition when new
data are loaded asynchronously. However, a bug occurred after each
transition as the new data loaded are not reflected onto the tipsy
tooltip that you have created.

As above, the mouseover data that gets loaded should be 80% but 70% is
loaded instead after the transition. Why is the wrong value being
displayed?

This is the part where I append the svg:title
   data = [70, 80, 90, 80];

vis.selectAll('.point').data(data).enter().append("svg:circle").attr("class",
function(d, i) {
       if (i === 3) {
           return 'point max';
       } else {
           return 'point';
       }
   }).attr("r", function(d, i) {
       if (d === max) {
           return 6;
       } else {
           return 4;
       }
   }).attr("cx", function(d, i) {
       return x(i);
   }).attr("cy", function(d) {
       return y(d);
   }).on('mouseover', function(d, i) {
       /*
       div
       .transition()
       .duration(500)
       .style("opacity", 1)
       .text("Satisfaction Level: " +d + "%" + " vs " + "Average: " +
avg + "%" );
       */
       d3.select(this)
       .attr('r', 8)
       ;
       return ;
   }).on('mouseout', function() {
       div.transition()
       .duration(500)
       .style("opacity", 1e-6);
       return d3.select(this).attr('r', 4);
   }).on('click', function(d, i) {
       return console.log(d, i);
   })
   .append('svg:title').attr('id','circleText').text(function(d,i) {
       return "Patient Satisfaction: " + d + "%" + "<br/><a href=
\"http://www.google.com\">google</a>";
   });


This is the part which handles the transition:
data3=[80, 80, 90, 80];
vis.selectAll('#circleText').data(data3).text(function(d,i) {
           //alert(JSONdata[i]);
           //try to parse it to an array?

           return "Patient Satisfaction: " + d + "%" + "<br/><a href=
\"http://www.google.com\">google</a>";
       });


I have been testing it and found that the tipsy value being reflected
are wrongly displayed.

On Sep 6, 6:31 am, Justin Donaldson <donald...@bigml.com> wrote:
> Ok, I had some weirdness with my local copy of the repo when I forked
> originally.  Not really sure what happened.  I decided to nuke it and
> manually remerge my changes.  This seems much more up to date now.  A new
> clone is probably in order.https://github.com/bigmlcom/tipsy

>
> The latest version should use a tipsy-esque handling of svg titles (i.e. as
> long as the element has a title child, tipsy will use that, and move the
> title content to an "original-title" node in order to prevent a double

>
> There's a few wrinkles.  Most browsers will treat svg title *attributes* the
> same as title *nodes, *even though it isn't in the spec.  This can cause
Reply all
Reply to author
Forward
0 new messages