Eliav2 / react-xarrows

Draw arrows (or lines) between components in React!
https://codesandbox.io/embed/github/Eliav2/react-xarrows/tree/master/examples?fontsize=14&hidenavigation=1&theme=dark
MIT License
584 stars 75 forks source link

Feature request: Stepped line support #19

Closed cole-robertson closed 4 years ago

cole-robertson commented 4 years ago

There is a use case I have where I would like the lines drawn stepped. Currently in Xarrows: image

I would like it to be like: image

I can currently get this result from react-archer: image Which is closer to what I'm looking for, but I really would like the starting anchor point to be on the bottom instead of the right side which is not possible with their current version.

Could fix this by putting perpendicular dummy elements that act as a proxy to make the 90 degree lines, but that would add unnecessary elements to the DOM. Maybe there is a way to do this with strictly SVG?

Thank you!

Eliav2 commented 4 years ago

I'm currently busy on other tasks - but soon as a will get some free time I will work to add this feature. thanks!

cole-robertson commented 4 years ago

I tried to look into it to submit a PR, I couldn't quite get the development environment going and follow the variable/math logic in index.tsx. It looks like this feature can be accomplished with something like :

/* If the property stepped line is true,, 
 * then set the path at the starting point, draw a relative line between 
 *  the difference in y values, then draw a relative line between the
 * difference in x values. 
 */
if(props.steppedLine){
    const yDiff = st.y2 - st.y1;
    const xDiff = st.x2 - st.x1;
    arrowPath = `M ${st.x1} ${st.y1} l 0, ${yDiff} l ${xDiff}, 0`  
  } else {
   /* normal SVG path */
   arrowPath = `M ${st.x1} ${st.y1} C ${st.cpx1} ${st.cpy1}, ${st.cpx2} ${st.cpy2}, ${st.x2} ${st.y2}`;
}

This would obviously not support the curveness property and it is assumes the start point is above and to the left of the end point, (like my example).

You'll know a lot better than I do if they is a viable solution and the implication if used with the various other properties of xArrows.

Eliav2 commented 4 years ago

Hey friend. Tomorrow evening I will have some time and will work on this new feature.(I think I will add property named path and and let the user choose either 'smooth' or 'grid' )

Eliav2 commented 4 years ago

hello friend. i added the feature you requested to the development branch. please pull the current changes(from 'development' branch) and check if this satisfies you, if not please provide a detailed explanation why not. if it does answer you requirements i will release is as v1.4.0 after few extra improvements. just add path={"grid"} to the properties.

cole-robertson commented 4 years ago

Hey, thank you for doing that! I have pulled down dev and the grid changes look good! I can get feature parity when I have anchor settings from startAnchor={"right"} and endAnchor={"left"} yielding result like: image

The only thing that I am missing is that I really want to be able to do: startAnchor={"bottom"} and endAnchor={"left"} in my case. When I do this currently with the dev build path={"grid"} and startAnchor={"bottom"}, I still get result: image

Eliav2 commented 4 years ago

you are absolutely right! it was a small mistake it one line of code, thank you for showing me this. it is now fixed and you can pull the latest version from the development branch, please let me know if its answers your needs.

now question: do you think it's nice to add a feature to the grid path option that will let the user choose where the line can break? i mean for example: path={{path:"grid",gridBreak: 0.3}}. when gridBreak is 0 the line will break really close to start anchor and when 1 really close to end anchor, or maybe even make this option by pixels offset(or maybe both). or maybe its just overkill?

cole-robertson commented 4 years ago

Great work! It works perfectly now, this is exactly what I'm looking for. Thank you for working this!

I think that in an API is is always better to have flexibility. Eventually, someone is going to want to break closer or further from the line, so I think that adding overloaded options to the path property would be really great for customization! Make it so someone can just have a string like "grid", but they can also have an object that specifies gridBreak in percentage or pixels. Then the user can decide how fine in the details they want to get!

Eliav2 commented 4 years ago

Thank you friend. v1.4.0 which includes this new feature has released.