uladkasach / react-simple-arrows

react components which make it simple to draw svg arrows in a react app
9 stars 3 forks source link

Creating arrows dynamically in JS #4

Closed brabbit61 closed 4 years ago

brabbit61 commented 4 years ago

Hey, I'm new to React and require some assistance to incorporate your component.

I'm trying to create these arrows dynamically in a function but have problem setting the attributes for the tag.

My current approach is:

  1. Extending the HTMLElement class.
  2. Define custom element.
  3. Create element.
  4. Set attributes.

This is the snippet for the same.

import {ArrowBetweenDivs, ArrowSvg, LineOrientation,ArrowAnchorPlacement} from 'react-simple-arrows';

class ArrowBetweenDivs extends HTMLElement {}; customElements.define('arrow-divs',ArrowBetweenDivs); class ArrowSvg extends HTMLElement {}; customElements.define('arrow-svg',ArrowSvg);

var arrow = document.createElement('arrow-svg');

Now my question is how to set the attributes for start, end and the orientation (In case of ArrowSvg). I have tried the following but neither for the approaches work.

a.setAttribute('start',[{x:40,y:100}]); //doesn't work

var rect1 = element.getClientRects(); a.start.x = rect1.x; a.start.y = rect1.y;

Any help would be appreciated.

uladkasach commented 4 years ago

Hey there!

You shouldn't need to extend classes to be able to use this w/ React. (Actually, these components are regular functions - so they can't be extended anyway)

To render an arrow in your react app, you should be able to just define the arrow component:

For example:

import { ArrowSvg, LineOrientation } from 'react-simple-arrows';

const App = () => {
  return (
    <ArrowSvg start={{ x: 200, y: 300 }} end={{ x: 600, y: 600 }} orientation={LineOrientation.HORIZONTAL} />
  )
}

And if you want to have them drawn between two different divs, you'll need to use the context component - which will track the positions of your divs as they are rendered and update the arrows to follow them:

import { ArrowBetweenDivs, ArrowSvg, LineOrientation, ArrowAnchorPlacement } from 'react-simple-arrows';

const App = () => {
  return (
  <ArrowsBetweenDivsContextProvider debug>
    {({ registerDivToArrowsContext }) => (
      <>
        <ArrowBetweenDivs
          from={{ id: 'div-a', placement: ArrowAnchorPlacement.TOP }}
          to={{ id: 'div-b', placement: ArrowAnchorPlacement.BOTTOM }}
          orientation={LineOrientation.VERTICAL}
        />
        <div ref={(div) => registerDivToArrowsContext({ id: 'div-a', div })}> A </div>
       <div style={{ height: 300 }} />
        <div ref={(div) => registerDivToArrowsContext({ id: 'div-b', div })}> B </div>
      </>
    </ArrowsBetweenDivsContextProvider>
  )
}

The above uses the context component ArrowsBetweenDivsContextProvider to track the position of your divs. The ArrowBetweenDivs then uses that context to figure out how to position your arrow, without you having to do a thing.

The way the context provider knows where the divs are and which divs to track is by the ref={(div) => registerDivToArrowsContext({ id: 'div-a', div })} definition. In this definition, we're telling the context to "register this div", which tells it to track its position under the name div-a, in this example.

Does that help?