@gravity-ui/graph
Version:
Modern graph editor component
79 lines (78 loc) • 3.11 kB
JavaScript
import { selectConnectionById } from "../../../store/connection/selectors";
import { GraphComponent } from "../GraphComponent";
export class BaseConnection extends GraphComponent {
get sourceBlock() {
return this.connectedState.$sourceBlock.value?.getViewComponent();
}
get targetBlock() {
return this.connectedState.$targetBlock.value?.getViewComponent();
}
get sourceAnchor() {
return this.sourceBlock.connectedState.getAnchorById(this.connectedState.sourceAnchorId)?.asTAnchor();
}
get targetAnchor() {
return this.targetBlock.connectedState.getAnchorById(this.connectedState.targetAnchorId)?.asTAnchor();
}
constructor(props, parent) {
super(props, parent);
this.updateHitBox = () => {
const [x1, y1, x2, y2] = this.getBBox();
const threshold = this.context.constants.connection.THRESHOLD_LINE_HIT;
this.setHitBox(Math.min(x1, x2) - threshold, Math.min(y1, y2) - threshold, Math.max(x1, x2) + threshold, Math.max(y1, y2) + threshold);
};
this.connectedState = selectConnectionById(this.context.graph, this.props.id);
this.setState({ ...this.connectedState.$state.value, hovered: false });
}
willMount() {
this.subscribeSignal(this.connectedState.$state, (state) => {
this.setState({ ...state });
});
this.subscribeSignal(this.connectedState.$geometry, () => {
this.updatePoints();
});
this.listenEvents(["mouseenter", "mouseleave"]);
}
handleEvent(event) {
event.stopPropagation();
super.handleEvent(event);
switch (event.type) {
case "mouseenter":
this.setState({ hovered: true });
break;
case "mouseleave":
this.setState({ hovered: false });
break;
}
}
updatePoints() {
if (!this.sourceBlock || !this.targetBlock)
return;
this.connectionPoints = [this.sourceBlock.getConnectionPoint("out"), this.targetBlock.getConnectionPoint("in")];
if (this.sourceAnchor && this.targetAnchor) {
this.anchorsPoints = [
this.sourceBlock.getConnectionAnchorPosition(this.sourceAnchor),
this.targetBlock.getConnectionAnchorPosition(this.targetAnchor),
];
}
else {
this.anchorsPoints = undefined;
}
const x = [
this.connectionPoints[0].x,
this.connectionPoints[1].x,
this.anchorsPoints?.[0].x || Infinity,
this.anchorsPoints?.[1].x || Infinity,
].filter(Number.isFinite);
const y = [
this.connectionPoints[0].y,
this.connectionPoints[1].y,
this.anchorsPoints?.[0].y || Infinity,
this.anchorsPoints?.[1].y || Infinity,
].filter(Number.isFinite);
this.bBox = [Math.min(...x), Math.min(...y), Math.max(...x), Math.max(...y)];
this.updateHitBox();
}
getBBox() {
return this.bBox;
}
}