react-digraph icon indicating copy to clipboard operation
react-digraph copied to clipboard

Example on how to render custom nodes

Open davified opened this issue 5 years ago • 5 comments

First of all, thanks for the great work on this library!

Is your feature request related to a problem? Please describe. I would like to render custom nodes (my own React component, which is just a simple rectangle with some basic styles). I can't use the default rendering of the nodes because my text gets cut off, and I'd like to render them as rectangles instead of circles (screenshot attached below)

I see in #36 that I could use renderNode or renderNodeText. However, it's not clear what the contract for these 2 props are, and how I could use it to render my own component.

It would be great if you could provide a sample code on how to render nodes using our custom React components.Thanks!

image

davified avatar Aug 26 '19 07:08 davified

Not sure of your exact requirements, but playing around with renderNodeText I've managed to format my text like this:

 renderNodeText={data => {
            console.log(data)
            return (
              <foreignObject x='-100' y='-30' width='200' height='50'>
                <div className='node'>
                  <p className='job-title'>{data.title}</p>
                  <p className='company'>{data.company}</p>
                  <p className='name'>{data.name}</p>
                </div>
              </foreignObject>
            )
          }}

I'm pretty new to SVG so I can't say if this would be considered best practice or not, and I would assume it isn't considering most browsers don't fully support foreignObject, but maybe it'll help you find a better path

hshelbur avatar Sep 03 '19 16:09 hshelbur

You can checkout the source code for the Node and Node Text components. They should give you a good indication of what to do...

And in case you were curios... Here's where the function you pass through gets executed:

iChaosren avatar Sep 03 '19 19:09 iChaosren

Hi @davified. You can render any type of node but it must contain a width and height on the symbol.

For example, here's a custom SVG that we use in a project. We use defs and use statements to improve rendering speed, because it's faster to reference an existing element than to render a new element.

return (
    <g>
      <use
        className="node"
        height={props.height}
        width={props.width}
        x={-props.width / 2}
        xlinkHref={nodeXlinkHref}
        y={-props.height / 2}
      />
<symbol height="24" id="tagRemoveIcon" viewBox="0 0 24 24" width="24">
      <path
        d="M12.928 7.624l-5.355 5.322a.779.779 0 0 0-.24.541c0 .22.07.449.24.62l3.654 3.653c.17.171.4.24.62.24a.774.774 0 0 0 .54-.24l5.322-5.355A1 1 0 0 0 18 11.7V8.333a1 1 0 0 0-1-1h-3.367a1 1 0 0 0-.705.291zm1.79 2.17a.82.82 0 1 1 1.642.001.82.82 0 0 1-1.642 0zm-4.385-2.127a.667.667 0 0 1-.666.666H6.333a.667.667 0 1 1 0-1.333h3.334c.368 0 .666.298.666.667z"
        fill="currentColor"
        fillRule="evenodd"
      />
    </symbol>
    ...

ajbogh avatar Jan 22 '20 19:01 ajbogh

Can I ask why the renderNode and renderNodeText are executing, like crazy? They render each Node in the array 5 Times? I only have 5 Nodes, which mean 25 re-renders, but I have examples, with 600 Nodes. Does that mean, it will render them 3000 Times? Can you explain why that happens? I went line by line in the debugger and the stack. And I don't see a good reason why.

EfstathiadisD avatar Jul 02 '20 13:07 EfstathiadisD

Were you able to figure out what was happening @EfstathiadisD?

Also, which one of the solutions worked? Can I use a custom

or <Component/> as a node?

Aditya94A avatar Aug 27 '20 04:08 Aditya94A