Open sillydan1 opened 3 years ago
Problem
(emulated) Desired Outcome
please refer to custom svg it the repo docs.
type headShapeType<T extends svgElemType> = {
svgElem: SVGElementTagNameMap[T];
offsetForward?: number;
};
try:
import { arrowShapes } from 'react-xarrows';
const customSvg = {
svgElem: arrowShapes.arrow1;
offsetForward: 1; //change
};
then change customSvg.offsetForward and pass it down to xarrow.
does this solves your issue?
Oh! Didn't catch that part of the docs. My bad. This almost fixes the issue. If I set the offsetForward
to some negative value, I get this result. Not excactly the desired effect, but very close. How would I get the arrow head to follow the line?
import Xarrow, {arrowShapes} from "react-xarrows";
const customSvg = {
svgElem: arrowShapes.arrow1.svgElem,
offsetForward: -1
};
you could extend the line using offset option in the anchors. foe example const endAnchor= { position: 'auto'; offset: { x: 20,y:0 }; };
currently, you can only offset only with x and y but soon there will be an option to offset relative to the facing direction.
position 'auto' does not work for me, since I need the arrow to point towards the middle.
currently, you can only offset only with x and y but soon there will be an option to offset relative to the facing direction.
That is excactly what I described and have implemented in the PR. Technically I would be able to calculate the x and y offsets using the same approach in my own application, but it would be nice if it was available as a library feature.
understood, you are right and this is planned for the next release. will leave this issue open as a feature request until the next release that solves this.
For anyone interested, this is how I ended up sidestepping this issue (please excuse the messy code) note that this code is not very performant:
import React, {Component} from "react";
import Xarrow from "react-xarrows";
import * as ReactDOM from "react-dom";
class Edge extends Component {
state = {
startOffset: {},
endOffset: {}
}
dist(a, b) {
return Math.sqrt((a.x - b.x) ** 2 + (a.y - b.y) ** 2);
}
calculateOffset(startId, endId) {
let start_el = document.getElementById(startId);
let end_el = document.getElementById(endId);
if(start_el === null || end_el === null)
return {x:0, y:0};
let start_box = start_el.getBoundingClientRect();
let end_box = end_el.getBoundingClientRect();
let start = {x: start_box.x + start_box.width/2, y: start_box.y + start_box.height/2};
let end = {x: end_box.x + end_box.width/2, y: end_box.y + end_box.height/2};
let radius = end_box.width / 2;
let directionMagnitude = this.dist(start, end);
if(directionMagnitude === 0)
return {x:0, y:0};
let directionNormalized = {
x: (start.x - end.x) / directionMagnitude,
y: (start.y - end.y) / directionMagnitude
};
return {
x: (directionNormalized.x * radius),
y: (directionNormalized.y * radius)
};
}
updateOffsets = () => {
const startOffset = this.props.startAnchor === 'middle' ? this.calculateOffset(this.props.end, this.props.start) : {x: 0, y: 0};
const endOffset = this.props.endAnchor === 'middle' ? this.calculateOffset(this.props.start, this.props.end) : {x: 0, y: 0};
this.setState({
startOffset: startOffset,
endOffset: endOffset
});
}
componentDidMount() {
// TODO: Once react-xarrows supports anchors with offset in facing direction, use that instead.
ReactDOM.findDOMNode(this).addEventListener("DOMAttrModified", this.updateOffsets.bind(this));
}
render() {
const {start, end, id, startAnchor, endAnchor} = this.props;
return (
<Xarrow start={start}
end={end}
path='straight'
startAnchor={{
position: startAnchor,
offset: this.state.startOffset
}}
endAnchor={{
position: endAnchor,
offset: this.state.endOffset
}}
/>
);
}
}
export default Edge;
Is your feature request related to a problem? Please describe. When a
straight
arrow is anchored to a circular/round element, neithermiddle
norauto
is a preferable choice.Describe the solution you'd like It would be nice if there were a variant of
middle
where you could provide aradius
offset where the arrow would point towards the middle of the target element, but isradius
-amount shorter.Of course, this type of anchor would only really be useful on straight arrows.