Tim Gottgetreu
Tim Gottgetreu

Reputation: 495

Adding hyeperlinks to zoomable d3 circle pack

I've been trying to add clickable hyperlinks to a zoomable d3 circle pack based on this code: http://bl.ocks.org/nilanjenator/4950148, but I just can't get it to work. Ideally I'd link a link under the text label for the circle, but at this point a clickable label would be just as rad.

I'm sure its a misunderstanding of d3 on my part. I've researched several stack topics that should work: (Hyperlinks in d3.js objects) and here are my failed attempts. I've also updated the json data file to include urls, ie.

{
 "name": "data",
 "children": [
  {"name": "Data", "size": 20544, "url":"http://katetempest.co.uk/audio"},
  {"name": "Ellington Willoughby", "size": 19788, "url": "http://wwww.ellingotnwilloughby.com"},
  {"name": "HELP", "size": 10349,"url":"http://en.wikipedia.org/wiki/Help!_%28album%29" },

  {

etc.

First crash and burn..adding a xlink to either the circle or the text, or node as mentioned in the other stack questions. This is where my d3 understanding breaks down.

vis.selectAll(".node")//also tried "cirlce" and "text"
 .append("svg:a").attr("xlink:href", function(d){ return d.url })
  .append("svg:text")
  .text(function(d) { return d.name; })
  .attr("dy", 3.5)
  .attr("dx", 5.5)
  .attr("text-anchor", "bottom");

I've added

<html xmlns:xlink="http://www.w3.org/1999/xlink">

to my html at the beginning of the project. But nothing happends.

Next burn - Adding on "onclick" event to the text such as:

  vis.selectAll("text")
  .data(nodes)
  .enter().append("svg:text")
  .attr("class", function(d) { return d.children ? "parent" : "child"; })
  .attr("x", function(d) { return d.x; })
  .attr("y", function(d) { return d.y; })
  .attr("dy", ".35em")
  .attr("text-anchor", "middle")
  .style("opacity", function(d) { return d.r > 20 ? 1 : 0; })
  .text(function(d) { return d.name; })
  .on("click",function(d){window.location = d.url}); ///<----Party here? Nope!

I'v also made sure to set my css as:

circle.child {
pointer-events: all;
}

Since I've read this gets in the way of tool-tips and general clickable thingamajigs, etc.

So what am I doing wrong? I'm pretty sure its my lack of understanding on which element to select and add the "svg:a" attr, but I'm stuck, which of course is a bummer. Exponential thanks to the stack community for taking a crack at it, and apologizes if I over looked something trivial and wasted everyone's time.

Cheers!

Upvotes: 0

Views: 915

Answers (1)

Tim Gottgetreu
Tim Gottgetreu

Reputation: 495

Thanks to the FernOfTheAndes comment I was able to get this all going. Just thought I'd post if someone else ran into this. I've modified the "onclick" circle event to only allow the link to work if you're at the lowest circle, otherwise its a bit messy...here you go:

vis.selectAll("circle")
  .data(nodes)
  .enter().append("svg:circle")
  .attr("class", function(d) { return d.children ? "parent" : "child"; })
  .attr("cx", function(d) { return d.x; })
  .attr("cy", function(d) { return d.y; })
  .attr("r", function(d) { return d.r; })
  .on("click", function(d) {

    //Enables links when elements have no childern
    if(typeof d.children === 'undefined'){
      vis.selectAll("text")
         .style("pointer-events","all")
    }
    else
    {
      vis.selectAll("text")
         .style("pointer-events","none")
    }

    return zoom(node == d ? root : d); 

    });

and in the css to allow access to childless circles (I think):

circle.child {
pointer-events: all;

}

Thanks again to the stack community!

Upvotes: 0

Related Questions