Skip to content

add optional text on Sankey links #4746

Open

Description

@emmanuelle

At the moment Sankey nodes display their labels as text, but for the links one can only have text on hover. It would be great to have an option to display text inside (or just above) the links.

Related issue: add optional text to histogram and to heatmap traces (which would remove the need for annotated heatmap figure factory).

Activity

  1. antoinerg commented on Apr 9, 2020

    @antoinerg
    Contributor

    Do you have any suggestions about how the users would specify this? Do we need a new attribute?

    cc @nicolaskruchten

  2. emmanuelle commented on Apr 9, 2020

    @emmanuelle
    ContributorAuthor

    maybe just a texttemplate which would be empty by default? And/or textinfo as in pie or funnel?

  3. kenakofer commented on Nov 10, 2022

    @kenakofer

    Yes please. It's strange that in the case of Sankey links, specifying a label is actually just specifying a hovertemplate.

  4. wattcommunity commented on Apr 22, 2024

    @wattcommunity

    OK a Sankey is a visualisation tool, but come on, seeing the magnitude of the pipes in a png export is like, why wouldn't you make this doable! Sorry to gripe; but other Sankey tools are pants and so plotly's offer is a last gasp saloon.

  5. fc-esja commented on Apr 24, 2024

    @fc-esja

    I can see that there is a label attribute for link, but adding labels to it does nothing. And agreed being able to specify texttemplate would also be great.

  6. self-assigned this
    on Jul 8, 2024
  7. removed their assignment
    on Aug 2, 2024
  8. changed the title [-][FEAT] Optional text on Sankey links[/-] [+]add optional text on Sankey links[/+] on Aug 9, 2024
  9. iyliahutta commented on Sep 5, 2024

    @iyliahutta

    is this in development or will be anytime soon? would really love to have this feature and i doubt i'm the only one.

  10. juanyaohuang commented on May 25, 2025

    @juanyaohuang

    I create a piece of js code to permanently add link values, I tested it in R Shiny it works great:

    htmlwidgets::onRender(x=p, jsCode='
    function(el) {
    //reference code: https://stackoverflow.com/questions/67291003/add-text-to-svg-path-dynamically
    //reference code: https://stackoverflow.com/questions/9281199/adding-text-to-svg-document-in-javascript
    //reference code: https://stackoverflow.com/questions/52335837/event-when-clicking-a-name-in-the-legend-of-a-plotlys-graph-in-r-shiny
    //reference code: https://stackoverflow.com/questions/42280913/troubleshoot-javascript-code-in-onrender-function-of-htmlwidgets
    function addLabelText(bgPath, labelText) {
    let bbox = bgPath.getBBox();
    let x = bbox.x + bbox.width / 2;
    let y = bbox.y + bbox.height / 2;

         let textElem = document.createElementNS("http://www.w3.org/2000/svg", "text");
         textElem.setAttribute("x", x);
         textElem.setAttribute("y", y);
         textElem.setAttribute("text-anchor", "middle");
         textElem.setAttribute("font-size", "10px");
         textElem.setAttribute("fill", "black");
         textElem.textContent = labelText;
    
         bgPath.parentNode.appendChild(textElem);
         console.log(bgPath.parentNode)
       }
    
       let myGraph = document.getElementById(el.id);
       let nodes = document.querySelectorAll("g.sankey-node");
       let links = document.querySelectorAll(".sankey-link");
       console.log(myGraph)
       console.log(nodes[1])
       console.log(links[1])      
    
       for (let i = 0; i < links.length; i++) {
         addLabelText(links[i], links[i].__data__.link.value)           
       }
    

    }')

  11. fstricker commented on Nov 11, 2025

    @fstricker

    Is there any news on this issue? I find it strange that there is no way of showing persistent link texts regardless of hover states.

  12. wf-r commented on Jul 2, 2026

    @wf-r

    I would be willing to work on a PR for this, if there is interest.

    Motivation

    Sankey links currently expose their information (name via link.label, plus value) only through the hover tooltip. There is no way to display link text permanently on the diagram, the way node labels are always drawn. This forces users to either accept hover-only interaction (useless for static export/PNG/print) or build fragile client-side SVG overlays.

    There is some community interest in exactly this - see this issue.

    Implementation options

    Option A — reuse link.label as the on/off switch

    Render link.label when it is set.

    This would need no new attributes, however one would only be able to show the label string, no value or custom text. It would also silently change behavior for existing figures that set link.label purely for hover - i.e. not backward compatible.

    Option B — introduce link.textinfo

    A flaglist string: any combination of "label", "value" or other flags joined with "+", or "none".

    • Pro: explicit opt-in (default "none" → no behavior change); users choose which pieces of information to show; consistent with the textinfo pattern already established in traces such as funnel and pie, so the attribute semantics are familiar to users and reusable in code.
    • Con: fixed formatting/ordering; no full control over the rendered string.

    Option C — link.textinfo (as in B) plus link.texttemplate

    texttemplate is a string or array of strings: a template for the rendered text (e.g. "%{label}: %{value}"), overriding textinfo when set; supports the same variables as the link hovertemplate (value, label, source, target, customdata, …).

    • Pro: full control, per-link templating, and still a clean opt-in. The textinfo + texttemplate duo is exactly the pattern funnel and pie already implement (see pie.texttemplate and funnel.texttemplate), so we can follow — and largely reuse — their template machinery rather than inventing anything new.
    • Con: the most code (template parsing, array handling), but reuses existing template machinery.

    Backward compatibility

    • Option A: not backward compatible — existing figures that set link.label for hover would suddenly render on-diagram text.
    • Options B/C: fully backward compatible. New attributes default to textinfo: "none" (and texttemplate: ""), so existing figures render identically; link text is strictly opt-in. No changes to node labels, hover, or existing baselines.

    Key implementation points

    • Render one <text> per link inside the .sankey group at the link midpoint ((source.x1 + target.x0) / 2, (y0 + y1) / 2), so the existing group-level orientation transform applies.
    • Apply the same counter-transform as node labels (flipText) so text stays upright in all orientations (h/v).
    • Reposition the labels in updateShapes so they follow live node drags (the underlying y0/y1 are already recomputed there).
    • For circular links the analytic midpoint is inaccurate; use path.getPointAtLength(totalLength / 2) for a robust anchor.
    • Respect a new link.textfont (mirroring node/trace textfont) and valueformat/valuesuffix for the value component.
  13. wf-r commented on Jul 2, 2026

    @wf-r

    An example for link labels with link.textinfo and link.texttemplate would be this:

    Image

    An example for the configuration with link.valueformat, link.valuesuffix and link.textfont would be this:

    Image
  14. robertclaus commented on Aug 4, 2026

    @robertclaus

    Thanks for the PR @wf-r ! @camdecoster had a chance to review if you are still looking into this!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3backlogfeaturesomething new

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions