0

I'm trying to create a Sankey diagram based off the example shown here: https://bost.ocks.org/mike/sankey/

While I am able to recreate the diagram, I'd like to write the tooltip text directly onto the links themselves (so they can be read as a static image). I've attempted to add a .append("text") call to the links just like I saw done for the nodes, but it doesn't seem to be working. Below is the code I added to the example above:

link.append("text")
    .attr("x", 25)
    .attr("y", function(d) { return d.dy / 2; })
    .attr("dy", ".35em")
    .attr("text-anchor", "end")
    .attr("transform", null)
    .text(function(d) { return d.source.name + " → " + d.target.name + "\n" + format(d.value); });
    .attr("text-anchor", "start");

Yet this doesn't show display anything in the diagram.

UPDATE: I pasted Mike Bostock's code into a gist to make recreating the issue easier: http://bl.ocks.org/almsuarez/50eab68a645d7fc12183384000ea8c82

Al S
  • 355
  • 2
  • 17
  • can you put it on fiddle? – eko Apr 28 '16 at 13:44
  • The most likely culprit is that `link` is created by `svg.append("g").selectAll(".link")` which then has `.append("path") .attr("class", "link")`. What this means is that `link` is a selection of `paths`, and you cannot append a `text` element to a path (which is what your code does). What you would need to do instead is append a `g` and then add both the `path` and `text` to the `g`. – JSBob Apr 28 '16 at 14:02
  • I see what you're saying and I've updated the linked gist to try and take that into account. However, now I don't know how to track the x & y positions of the link paths to properly overlay the text. – Al S Apr 28 '16 at 14:49

1 Answers1

1

As was said in the comments you can't append text to SVG elements. So say at the moment you append your link to a container. For example :

var link = container.append('path')....//and so on

You have to do the same for text. So, for example :

var linkText = container.append('text')

You say you can't keep track of the x and y positions ?

Basically as your link is in between two points, you need to find the centre. Here is how I would do it :

.attr("x", function(d) { console.log(d); return d.source.x + (d.target.x - d.source.x) / 2; })
      .attr("y", function(d) { return d.source.y + (d.target.y - d.source.y) / 2; })

So you get the source' x position then add half the difference of targetX - sourceX and do the same for y.

I have put this in a fiddle for you to see : https://jsfiddle.net/thatOneGuy/8ayq5nwa/2/

You can hover over the links to see the title that way you can check it's all correct :)

thatOneGuy
  • 9,977
  • 7
  • 48
  • 90
  • If I understand you correclty, you mean making a container with the `svg.append("g").selectAll(".link").data(energy.links).enter()` and have the link text and link paths be subsets of that? This still comes up with the issue of positioning, as sankey.js seems to be doing something in the background for positioning that I can't seem to access. – Al S Apr 28 '16 at 15:23
  • @M_Corn check updated answer :) You already were showing the text it was just a case of positioning it. You can see this isn't exact as you need to make up for the width of the text. But that shouldn't be too difficult :) Also the y position, i.e all the text is at the top of the links. If you wish to have it in the centre you will have to get sourceHeight and targetHeight work out the average center of them and translate the text that much so the text is central in the height aswell as the width – thatOneGuy Apr 28 '16 at 15:23
  • Ah, I see now. The source and target data were what were eluding me. Now on to see if I can get them to move along with the links as they are dragged.... – Al S Apr 28 '16 at 15:32
  • Shouldnt be too difficult just update positions in the dragMove function :) – thatOneGuy Apr 28 '16 at 15:34