1

In D3, when making hyperlinked nodes (circle pack layout) is there a way to use a base URL pattern and then employ the {d.url} to specify each given webpage. I'm using Drupal for my website which I want the nodes to link back to. Drupal uses a URL structure of www.drupal.org/blogpost/[post_id]. I can get the post_id's from the database ok, I'm just not sure how to wire it up to the "xlink:href" part? I'm think it might be something like...

node.append("a") .attr("xlink:href", function(d) {return "http://www.example.com/blogentry/..." + d.url}) .append("circle") .attr("r", function(d) { return d.r; });

Combining the base URL and and the individual blog entry IDs has me stumped. Any help or leads would be much appreciated.

Colman McMahon
  • 175
  • 1
  • 17

1 Answers1

3

There are no issues with the method you are using to construct the URL. Perhaps the value you are trying to access is not defined on objects in the data array? For example, make sure that d.url is defined.

Here is a small working example that shows links working using the same method you are using (also hosted on bl.ocks.org):

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>D3 Links Example</title>
    <script src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
  </head>
  <body>
    <script>
      var data = ["JavaScript", "Document_Object_Model", "Ajax_(programming)"];

      d3.select("body").append("svg")
          .attr("width", 960)
          .attr("height", 500)
        .selectAll("a").data(data)
          .enter()
            .append("a")
              .attr("xlink:href", function (d){
                return "http://en.wikipedia.org/wiki/" + d;
              })
            .append("rect")
              .attr("x", function (d, i){
                return 140 + i * 240;
              })
              .attr("y", 150)
              .attr("width", 200)
              .attr("height", 200);
    </script>
  </body>
</html>

Update 6/10/2015 re: updated fiddle:

When your code computes "submissionsByCountry = d3.nest()...", you are losing the entityid property, because it is being aggregated away.

If you inspect the values you have for "d" where you are adding the link, you can see that they look like this

Object {key: "OrgUU", values: 1, parent: Object, depth: 2, value: 1…}

because these objects are the result from the circle packing layout, not elements in the original data array.

If there is a 1-1 mapping between Organization and id (which looks to be true in your example data), you can look up the id from the organization. First you can build the lookup table like this:

var idByOrg = {};
data.forEach(function (d) {
    idByOrg[d.Organisation] = d.entityid;
});

Then later access it like this:

//Create nodes/circles
node.append("svg:a")
    .attr("xlink:href", function (d) {
        console.log(d); // Shows {key: "OrgUU", values: 1, parent: Object, depth: 2, value: 1…}
        var entityid = idByOrg[d.key];
        return "http://www.example.com/entityform/" + entityid;
    })
    .append("circle")
    .attr("r", function (d) {
        return d.r;
    });

Now if you inspect the generated URLs, you see things like "http://www.example.com/entityform/10" and "http://www.example.com/entityform/3".

Here's a working fiddle that does this.

Note that the links only work on leaf nodes in the circle tree. I suppose the next step would be to only include links on the leaf nodes, and not the outer circles.

curran
  • 1,261
  • 13
  • 8
  • Hi! Thank you for the example and also your answer in the D3 forum. Much appreciated! I cleaned up my fiddle (a few bleary-eyed mistakes in there). Looking at your example I noticed your `.data(data)` within the code. When I put that in I get correct values passed to `entityid` but I lose the text lables (`undefined`). Your observation about `d.entity` not being defined as an object feels correct. Any chance you could elaborate a bit further? This post seems helpful: http://stackoverflow.com/questions/2241875/how-to-create-an-object-property-from-a-variable-value-in-javascript. Thanks again. – Colman McMahon May 28 '15 at 15:57
  • Glad it was helpful. I'm not sure what you mean by "I lose the text lables (undefined)". What text labels are you referring to? I don't see any text labels in your original example that creates circles, maybe I am missing something. Also, could you please post a link to your updated fiddle that demonstrates the issue? The fiddle link on your original post is the same code as before. – curran May 29 '15 at 21:25
  • Sorry about that, here's an updated fiddle: http://jsfiddle.net/4fpoqv4n/54/. It shows each node/circle labelled with the organisation's name. I'm going to see if I can figure out defining `d.entity` as an object and see if it eliminates the `undefined` message. – Colman McMahon Jun 04 '15 at 10:05
  • Addding `.data(data)` returns the correct `entityid` value but prevents the circles from appearing: `node.append("svg:a") .data(data) .attr("xlink:href", function(d) { return "http://www.example.com/entityform/" + d.entityid; })...` etc. Shown in fiddle: http://jsfiddle.net/4fpoqv4n/55/ – Colman McMahon Jun 04 '15 at 12:53
  • Using a `for-in` loop to define `entityID` returns correct ID values (in console), but not passing them to the xhref function. `for (var key in data) { if (data.hasOwnProperty(key)) { var entityID = data[key]["entityid"]; console.log(entityID); } }` Updated fiddle: http://jsfiddle.net/cajmcmahon/4fpoqv4n/59/. Onward... – Colman McMahon Jun 09 '15 at 15:34
  • Updated answer. Kudos for pushing on! These things can be tricky. – curran Jun 10 '15 at 21:34
  • Success!! Thank you very much. The `lookup table` was key (no pun intended!). I wouldn't have thought of that. Weeks of struggle over. Now to restrict to just the leaf nodes for styling perfection. Thanks again... – Colman McMahon Jun 11 '15 at 13:29
  • 1
    In case anyone's looking for a way, I just used a filter to remove parent labels and only show on children/leaf nodes: `node.append("text") .filter(function (d) { return !d.children; })`. Updated fiddle: http://jsfiddle.net/cajmcmahon/4fpoqv4n/69/ – Colman McMahon Jun 16 '15 at 10:49