href on d3 objects

6,955 views
Skip to first unread message

drohrlick

unread,
Feb 23, 2012, 4:35:15 PM2/23/12
to d3-js
Hello,

D3 noob here. I'm trying to assign a rectangle with a href link.

Here's what I have so far:

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>HrefTest</title>
<script type="text/javascript" src="http://mbostock.github.com/d3/
d3.js?2.6.0"></script>
</head>

<body>
<div id="Section1"></div>
<script type="text/javascript">
var w = 500,
h = 400;

var MyCanvas = d3.select("#Section1")
.append("svg")
.attr("width", w)
.attr("height", h)
.style("background-color", "gray");

var MyLink = MyCanvas.selectAll("foreignObject")
.data([0])
.enter().append("foreignObject")
.attr("width", w)
.attr("height", h)
.append("xhtml:body")
.html("<a href='http://www.google.com'>My awesome link!</a>");

var RectGroup = MyCanvas.selectAll("g")
.data([0])
.enter().append("g");

var MyRect = RectGroup.append("rect")
.attr("class", "Button")
.attr("id", "Button1")
.attr("fill", "blue")
.attr("stroke", "white")
.attr("stroke-width", 1)
.attr("x", 200)
.attr("y", 100)
.attr("width", 50)
.attr("height", 50)
.on("click", function(d,i)
{
HandleClick(d3.select(this));
});

function HandleClick(selection)
{
console.log("clicked");
}
</script>
</body>
</html>

Woohoo! I created a simple link in my d3 object. And look! There's a
rectangle that does nothing!

I'm not sure how to assign the href to the rectangle. And even once
it's assigned, I'm not sure how to handle the "on click" event. I've
tried doing:

.html("<a href='http://www.google.com'>#Button1</a>");

I was hoping that it would assign itself to the Button1 object.
Instead the link becomes "#Button1". Any ideas would be much
appreciated!

P.S.
Also is "foreignObject" a keyword for when you need to gain access
to html objects? I found this keyword from this helpful sample:
http://bl.ocks.org/1424037

Bob Monteverde

unread,
Feb 23, 2012, 6:12:08 PM2/23/12
to d3-js
I usually just add a click event to the object and have it follow a
link. But I suppose there are benefits to this technique... hopefully
ctrl/shift + click opens new tab/window.

Andy Wilson

unread,
Feb 23, 2012, 6:31:38 PM2/23/12
to d3...@googlegroups.com
SVG supports linking through its own <a> element. Try wrapping your
rectangle in an 'svg:a' element and setting .attr('xlink:href',
"http://example.com")

more info here: http://www.w3.org/TR/SVG/linking.html#Links

Guerino1

unread,
Mar 22, 2012, 11:52:10 PM3/22/12
to d3...@googlegroups.com
May I please ask, what's the syntax for doing so?  In other words, how do you wrap the rectangle in the <a> element and then assign the link to it?

I've been trying to find a working example with clear syntax and have yet to find one anywhere.

Thanks,

Frank

Mike Bostock

unread,
Mar 23, 2012, 1:10:00 AM3/23/12
to d3...@googlegroups.com
> how do you wrap the rectangle in the <a> element and then assign the link to it?

In tag form, it's <a href="link.html"><rect/></a>.

In JavaScript, it's append("a").attr("xlink:href", "link.html").append("rect").

Mike

Frank Guerino

unread,
Mar 23, 2012, 8:00:31 AM3/23/12
to d3...@googlegroups.com
Thank you!

I struggled over this for hours and your one line explanation helped me get it to work in seconds.  It's clear that I did not understand the syntax for sub-chaining of elements.

For the rest of the group, here's how I wrapped text with an HTML hyper link (i.e. an "<a>" element)...

      // Create hyper linked text at right that acts as label key...
      canvas.selectAll("a.legend_link")
          .data(dataSet) // Instruct to bind dataSet to text elements
          .enter().append("svg:a") // Append legend elements
          .attr("xlink:href", function(d) { return d.link; })
              .append("text")
              .attr("text-anchor", "left")
              .attr("x", barsWidthTotal + 50 + 20)
              .attr("y", function(d, i) { return legendOffset + i*20 - 10; })
              .attr("dx", 0)
              .attr("dy", "1em") // Controls padding to place text above bars
              .text(function(d) { return d.xCoordinate;})
              .attr("fill", "Black");

Thanks, again, Mike.  Have a great day!

Frank

Roydon D'Souza

unread,
May 19, 2015, 12:36:26 PM5/19/15
to d3...@googlegroups.com
Mike is there a way in d3 to do an action like this on a click event bound to a rectangle
- I need to open link in new tab when I hold CMD and then click. But normal click will be in this tab. 

What way we can check if a key is down when a click event is fired? Do I need to follow normal JS or d3 has some different way to do this?

Curran

unread,
May 20, 2015, 3:12:31 PM5/20/15
to d3...@googlegroups.com
Using the <a href="... pattern on SVG elements will give you the behavior you describe. There is no need to implement checking for the CMD key yourself if you want to add links to SVG elements.

Here is a complete working example of href on D3 objects that shows this. Try it out - if you open the example in a new window, clicking the link will open it in the current tab, and holding CMD then clicking the link will open it in a new tab.

Best regards,
Curran

roydo....@gmail.com

unread,
May 20, 2015, 3:27:26 PM5/20/15
to d3...@googlegroups.com
Hi Curran

Thank you very much. I didn't realise making it a link itself would achieve the functionality I was looking for. 

I went ahead and used d3.event.metaKey and ctrlKey (for windows) to detect if the CMD key was down when someone clicked on a rectangle. 


.on("click", function(d) {
                            //on ^ + click / ⌘ + click 
                            if (d3.event.ctrlKey || d3.event.metaKey) {
                                  //on supported key combination and click open in new tab
                                  //since i use angularJS
                                  $window.open('/campaigns/' + d.id);
                          }
});

After reading your email, 
I went a head and wrapped around the rectangle with anchor tag. Does the job for me. Thank you very much. 




Regards,

Roydon D' Souza

--
You received this message because you are subscribed to a topic in the Google Groups "d3-js" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/d3-js/3g-NfeUbSLQ/unsubscribe.
To unsubscribe from this group and all its topics, send an email to d3-js+un...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Curran

unread,
May 21, 2015, 2:28:27 PM5/21/15
to d3...@googlegroups.com
Great! I'm glad that you worked it out.

It's cool to see your code example of how you would get the ctrl and metaKey if you had to, I didn't know about d3.event.ctrlKey and d3.event.metaKey, thank you for that.

roydo....@gmail.com

unread,
May 21, 2015, 4:58:57 PM5/21/15
to d3...@googlegroups.com
Thanks Curran, since I didn't have enough time, I had to go ahead and come up with some work arounds. 

Today i was also searching something about drag, I had an issue: when I right click on a link inside d3, then click outside the svg area, the drag was activated, I found out about d3.event.sourceEvent.which simple but powerful stuff :) Stack overflow link here

One more issue, in the example you shared : complete working example of href on D3 objects 

Chrome works as expected: (Screenshot below with right click's context menu)

But Mozilla has issues: (on a normal link it works fine.. but somehow inspect element picks up rectangle on mouseover. as if the anchor tag was never there)

Any work around to solve this will be highly appreciated. Its something to do with mozilla and svg's rendering techniques and conventions I believe.

Chrome:
Inline image 1



Mozilla: I need the context menu that appears for a link "open in new tab" etc


Inline image 2





Regards,
Roydon D' Souza



On Thu, May 21, 2015 at 11:58 PM, Curran <curran....@gmail.com> wrote:
Great! I'm glad that you worked it out.

It's cool to see your code example of how you would get the ctrl and metaKey if you had to, I didn't know about d3.event.ctrlKey and d3.event.metaKey, thank you for that.

On Wednesday, May 20, 2015 at 12:27:26 PM UTC-7, Roydon D'Souza wrote:
Hi Curran

Thank you very much. I didn't realise making it a link itself would achieve the functionality I was looking for. 

I went ahead and used d3.event.metaKey and ctrlKey (for windows) to detect if the CMD key was down when someone clicked on a rectangle. 


.on("click", function(d) {
                            //on ^ + click / ⌘ + click 
                            if (d3.event.ctrlKey || d3.event.metaKey) {
                                  //on supported key combination and click open in new tab
                                  //since i use angularJS
                                  $window.open('/campaigns/' + d.id);
                          }
});

After reading your email, 
I went a head and wrapped around the rectangle with anchor tag. Does the job for me. Thank you very much. 




Regards,

Roydon D' Souza


Reply all
Reply to author
Forward
0 new messages