🏠 back to Observable

Hyperlinks in label ?

Hi
I wish I modify some labels in a chord diagram like this:


or a sankey diagram like this:

so that they provide links to other pages or files located elsewhere.
Is it possible ?
Thank you for attention and eventual help

In SVG you can wrap elements inside <a> elements to turn them into links.

Be aware that you need to set the attribute xlink:href instead of href, and that the <a> element’s own text (i.e. text nodes) won’t be displayed. Instead you need to put an SVG <text> element (or any other SVG element) inside.

For the Chord example, we can get link labels by modifying the chart cell. Change this piece of code:

  group.append("text")
      .each(d => { d.angle = (d.startAngle + d.endAngle) / 2; })
      .attr("dy", ".35em")
      .attr("transform", d => `
        rotate(${(d.angle * 180 / Math.PI - 90)})
        translate(${innerRadius + 26})
        ${d.angle > Math.PI ? "rotate(180)" : ""}
      `)
      .attr("text-anchor", d => d.angle > Math.PI ? "end" : null)
      .text(d => data.name_by_index.get(d.index));

to this (edit: see my next answer for a correction):

  group.append("a")
      .each(d => { d.angle = (d.startAngle + d.endAngle) / 2; })
      .attr("transform", d => `
        rotate(${(d.angle * 180 / Math.PI - 90)})
        translate(${innerRadius + 26})
        ${d.angle > Math.PI ? "rotate(180)" : ""}
      `)
      // Set your links here:
      .attr("xlink:href", d => "#" + data.name_by_index.get(d.index))
      .append("text")
        .attr("dy", ".35em")
        .attr("text-anchor", d => d.angle > Math.PI ? "end" : null)
        .text(d => data.name_by_index.get(d.index));
2 Likes

Thank you mootari for the advice.
I am not sure I weel understood.
I tried this:

group.append(“a”)
.each(d => { d.angle = (d.startAngle + d.endAngle) / 2; })
.attr(“transform”, d => rotate(${(d.angle * 180 / Math.PI - 90)}) translate(${innerRadius + 26}) ${d.angle > Math.PI ? "rotate(180)" : ""} )
// Set your links here:
.attr(“xlink:href”, d => “https://www.google.com”)
.append(“text”)
.attr(“dy”, “.35em”)
.attr(“text-anchor”, d => d.angle > Math.PI ? “end” : null)
.text(d => data.name_by_index.get(d.index));

I can see that, when I point one of the labels with mouse, the target link appears down left my window. But when click the label, I get a white window and not the expected one.
But if I right click to open link in a new window, it works. Strange.
Is my adaptation correct ?

Whoops, sorry about that.

By default the target attribute for SVG hyperlinks is set to self. So when you click the link, you’re navigating inside the iframe in which your notebook is running. Of course, changing the iframe’s location breaks literally everything.

In order to make your links work, you need to set target to _parent or _top (or, alternatively, to _blank to force a new window). Here is a simplified, complete example for an SVG hyperlink:

html`<svg>
  <a href="https://google.com" target="_top">
    <text y="1.5em">A link</text>
  </a>
</svg>`

or with D3:

{
  const view = d3.create("svg");
  view.append("a")
    .attr("href", "https://google.com")
    .attr("target", "_top")
    .append("text")
      .attr("y", "1.5em")
      .text("A link");
  return view.node();
}

Yes, it’s actually href, because xlink:href is deprecated (as I found out while researching this).

1 Like

Thank you mootari for the added informations and the link toward SVG hyperlinks.
I tried with xlink:href and it worked nice. But I upgraded to simple href as you suggested.
Last question : if I want to apply a different target ling to each label, I suppose I have to define a new constant object welle sized:
const links_list = [‘url1’, ‘url2’, … , ‘url12’]
Yes ?

If so, how to define the application each link <=> each label ?

And I tried to export figure in svg.
Great surprise => the links remains available.
But unfotunately, the highlights are not still avalaible after exportation.
I though svg format allows this. No ?

Can you give a short example? Ideally with a specific notebook link and the cell that you exported, and a description of how the export behaves differently?