nivo icon indicating copy to clipboard operation
nivo copied to clipboard

Sankey gradient broken on safari if space in ID

Open gantu opened this issue 3 years ago • 7 comments

Describe/explain the bug Sankey gradient is not working if there is a space in ID

To Reproduce Sandbox for reproduction https://codesandbox.io/s/nivo-sankey-total-inside-donut-434-forked-ncb3tf

**Steps to reproduce the behavior: Put space in ID

Expected behavior Gradient should work.

Screenshots

Desktop (please complete the following information):

  • OS: MacOS
  • Browser: safari
  • Version: 15.1

gantu avatar Jun 15 '22 07:06 gantu

Same thing

DimaDP avatar Sep 30 '22 12:09 DimaDP

Same thing. Anybody have a workaround?

outlawpractice avatar Jan 11 '23 15:01 outlawpractice

This issue is still outstanding. The problem is that the node id's are also being used as element id's in the gradient elements, and the HTML spec does not allow whitespace in the id attribute. Seems like most browsers are pretty relaxed about it, but Safari is not. As a result, the Sankey gradients don't look great on Macs and iPhones. Ideally, id's would be decoupled from the labels.

The fix is to do this decoupling manually. Node IDs are stripped of spaces and a new name property is added that can be retrieved within the Sankey component:

// Create new Sankey links
function addLink(nodes, links, source, target) {
    // These are used as element IDs and spaces are not allowed (and don't work well in Safari)
    let sourceId = source.replaceAll(" ", "-");
    let targetId = target.replaceAll(" ", "-");

    if (!nodes.find(obj => obj["id"] == sourceId)) nodes.push({ "id": sourceId, "name": source });
    if (!nodes.find(obj => obj["id"] == targetId)) nodes.push({ "id": targetId, "name": target });

    let link = links.find(obj => obj["source"] == sourceId && obj["target"] == targetId);
    if (link) {
        link["value"]++;
    } else {
        links.push({
            "source": sourceId,
            "target": targetId,
            "value": 1
        })
    }
}

...

<ResponsiveSankey
    ...
    label={d => `${d.name}: ${d.value}`}
    linkTooltip={({ link }) => {
        return <BasicTooltip
            id={
                <span>
                    <Chip color={link.source.color} style={{ marginRight: 7 }} />
                    {link.source.name} &rarr; {link.target.name}
                    <Chip color={link.target.color} style={{ marginRight: 7, marginLeft: 7 }} />
                    {link.formattedValue}
                </span>
            }
        />;
    }}
/>

rshekhtm avatar Jan 26 '23 08:01 rshekhtm

it works fine on safari 17.0

nsdevaraj avatar Oct 11 '23 06:10 nsdevaraj

Running Safari 17 on Mac OS Sonoma, and it's still an issue here.

outlawpractice avatar Oct 12 '23 15:10 outlawpractice

Just tested it with the latest Safari Technical Preview (17.4) using the code sandbox above, and Safari is still messing it up.

Would be nice to have this fixed, but I have given up on Safari and set enableLinkGradient to false if I detect it. Doesn't look nearly as nice, but it's better than seeing gray.

outlawpractice avatar Oct 13 '23 15:10 outlawpractice