user2085978
user2085978

Reputation: 109

Add hyperlink to node text on a collapsible tree

I would like to add hyperlink on the node text in the collapsible tree example.

How can I do this?

Upvotes: 10

Views: 7350

Answers (3)

emp
emp

Reputation: 5065

If you remove the click handler on the global node and attach 2 different click handlers:

  • One for the circle
  • One for the text

You can have a different behaviour when clicking the text. If you style that element a bit it can look exactly as a hyperlink.

Check out my fiddle here: http://jsfiddle.net/empie/EX83X/

Click Handlers

var nodeEnter = node.enter().append("g")
          .attr("class", "node")
          .attr("transform", function(d) { return "translate(" + source.y0 + "," + source.x0 + ")"; });

      nodeEnter.append("circle")
          .attr("r", 1e-6)
          .style("fill", function(d) { return d._children ? "lightsteelblue" : "#fff"; }).on("click", click);;

      nodeEnter.append("text")
          .attr("x", function(d) { return d.children || d._children ? -10 : 10; })
          .attr("dy", ".35em")
          .attr("text-anchor", function(d) { return d.children || d._children ? "end" : "start"; })
          .text(function(d) { return d.name; })
          .style("fill-opacity", 1e-6)
      .attr("class", "hyper").on("click", clack);

    function clack(d) {
        alert(d.name);
    }

And CSS:

.hyper {
    color: blue;
    text-decoration: underline;
}

.hyper:hover {
    color: yellow;
    text-decoration: none;
}

Upvotes: 5

Steve
Steve

Reputation: 886

I added another line of text to the node with some info about the link, like this:

nodeEnter.append("a")
    .attr("xlink:href", function(d) { return d.path; })
    .append("text")
    .attr("class", "clickable")
    .attr("y", 16)
    .attr("x", function (d) { return d.children || d._children ? -10 : 10; })
    .attr("text-anchor", function(d) { return d.children || d._children ? "end" : "start"; })
    .text(function(d) { return d.label; })

where path and label have the data you want for each node.

Upvotes: 0

Marijn
Marijn

Reputation: 10557

I'm a Javascript/svg/d3js noob, but I "solved" this by placing a hyperlinked transparent rectangle over the text, this workaround is available as a bl.ock.:

nodeEnter
  .append("a")
     .attr("xlink:href", function (d) { return "http://www.example.com/flare/" + d.id; })
  .append("rect")
      .attr("class", "clickable")
      .attr("y", -6)
      .attr("x", function (d) { return d.children || d._children ? -60 : 10; })
      .attr("width", 50) //2*4.5)
      .attr("height", 12)
      .style("fill", "lightsteelblue")
      .style("fill-opacity", .3)        // set to 1e-6 to make transparent          
      ;

I added an additional clickable style and add .on("click", click) to the circle instead of the group (g) element.

This works, but has the drawback that the size of the clickable rect does not size with the text of the label.

I'm really looking forward to a better solution, so +1 for your question!

Upvotes: 7

Related Questions