Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

@nivo/sankey turn off node legend text and custom nodes #2624

Open
shellyscheng opened this issue Jul 24, 2024 · 6 comments
Open

@nivo/sankey turn off node legend text and custom nodes #2624

shellyscheng opened this issue Jul 24, 2024 · 6 comments

Comments

@shellyscheng
Copy link

shellyscheng commented Jul 24, 2024

Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

Is there a way to hide node labels on the bottom right corner?
Screenshot 2024-07-23 at 10 39 10 PM

Describe the solution you'd like
A clear and concise description of what you want to happen.

I'm working on a chart which I set the nodeThickness to be 0, so I don't need the legend box at the bottom right corner. Would appreciate it if there's a way to turn it off.

Thanks a lot!

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.

Additional context
Add any other context or screenshots about the feature request here.

@plouc
Copy link
Owner

plouc commented Jul 24, 2024

@shellyscheng, I think you posted before the upload of the screenshot could complete.

@shellyscheng
Copy link
Author

shellyscheng commented Jul 24, 2024

@plouc opps! I just updated it! I figured it out by giving legends={[]}.

But now I have encountered two different questions for labels:

  1. How can I break labels into two lines?

For my use case, I hope the top label to have both source name and % of the total

Category 1
     x %
  1. How do we know the precise position of the node? Or customize node labels to be more complex, such as including images?

For my use case, I'm hoping to add two images at the center of the bottom two nodes

Thank you so much!

Screenshot 2024-07-24 at 1 29 10 AM

@plouc
Copy link
Owner

plouc commented Jul 24, 2024

@shellyscheng, line breaks are not supported (SVG limitation), regarding customization, it's doable if you're familiar with SVG, while not exactly the same, you can have a look at this example: https://codesandbox.io/p/sandbox/sankey-custom-b4iyi?file=%2Fsrc%2FApp.js which uses a custom layer for the nodes, it could be a good start, but you'll have to figure out things by yourself as custom layers aren't documented.

@shellyscheng shellyscheng changed the title @nivo/sankey turn off node legend text @nivo/sankey turn off node legend text and custom nodes Jul 26, 2024
@shellyscheng
Copy link
Author

shellyscheng commented Jul 26, 2024

@plouc, that's super helpful! I have a follow-up question about using Nivo with custom layers. Once I added a custom layer for the nodes, the original labels set within the Nivo config got overwritten (pic 1 is Nivo label settings, pic 2 with CutomNodeLayer).

Is there a way to keep both the original labels and my custom elements? Like what I will for label 1 - 4 in the pic 1, target 1 and 2 below my headshot images in pic 2 if possible. Or is is possible to only use custom nodes for target 1 and 2 (with nodeThickness 100), not using custom nodefor label 1 -4 (with nodeThickness 0)

Additionally, the custom node layer seems to have a very fixed width restriction, which is not ideal for my labels. Would appreciate any insights that I could help improve the look! Thank you!

Here's my code for achieving pic 2:

const StyledImg = styled(Img)`
  width: 100px;
  max-width: 100%;
  position: relative;
  margin: 0 auto;
  display: flex;
  margin-top: 0.5rem;


const Label = styled.div`
  color: ${(props) => props.color};
  margin: 0 auto;
  wrap: nowrap;
`

const CustomNode = ({ node }) => {

  return (
    <g transform={`translate(${node.x0}, ${node.y0})`}>
      {node.id === "target 1" || node.id === "target 2" ? (
        <foreignObject width={node.width} height={node.height}>
          <div
            style={{
              width: node.width,
              height: node.height,
              boxSizing: "border-box",
              color: "black",
              textAlign: "left",
              padding: "9px",
              fontSize: "12px",
              backgroundColor: neutrals.white,
            }}
          >
            <StyledImg
              key={node.id}
              $imgSrc={imgUrl}
            />
          </div>
        </foreignObject>
      ) : (
        <foreignObject width={node.width + 100} height={node.height}>
          <Label
            style={{
              width: 21,
              height: 0,
              boxSizing: "border-box",
              backgroundColor: node.color,
              lineHeight: "1.5rem",
              fontSize: "18px",
              fontStretch: "75%",
              fontWeight: "700",
            }}
          >
            {node.id}
          </Label>
        </foreignObject>
      )}
    </g>
  )
}

Screenshot 2024-07-26 at 11 48 10 AM

Screenshot 2024-07-26 at 11 47 55 AM

@plouc
Copy link
Owner

plouc commented Jul 30, 2024

@shellyscheng, you can pass the following layers: 'links' | 'nodes' | 'labels' | 'legends'.
It's not possible to use a custom layer only for certain elements as it replaces all.
As it's SVG, there are no line breaks, you could also use a custom layer for labels if you wish to customize them.

@shellyscheng
Copy link
Author

shellyscheng commented Jul 30, 2024

Thank you, @plouc! I made it work now!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants