UNPKG

@gravity-ui/graph

Version:

Modern graph editor component

79 lines (78 loc) 3.11 kB
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; } }