pagraphcontrol/components/graph/base.js
2018-11-09 14:43:07 +03:00

117 lines
2.8 KiB
JavaScript

const r = require('r-dom');
const {
GraphView: GraphViewBase,
Edge: EdgeBase,
GraphUtils,
} = require('react-digraph');
const math = require('mathjs');
class GraphView extends GraphViewBase {
constructor(props) {
super(props);
Object.assign(this, {
_super_handleNodeMove: this.handleNodeMove,
handleNodeMove: this.constructor.prototype.handleNodeMove.bind(this),
_super_getEdgeComponent: this.handleNodeMove,
getEdgeComponent: this.constructor.prototype.getEdgeComponent.bind(this),
});
}
handleNodeMove(position, nodeId, shiftKey) {
this._super_handleNodeMove(position, nodeId, shiftKey);
if (this.props.onNodeMove) {
this.props.onNodeMove(position, nodeId, shiftKey);
}
}
getEdgeComponent(edge) {
if (!this.props.renderEdge) {
return this._super_getEdgeComponent(edge);
}
const sourceNodeMapNode = this.getNodeById(edge.source);
const sourceNode = sourceNodeMapNode ? sourceNodeMapNode.node : null;
const targetNodeMapNode = this.getNodeById(edge.target);
const targetNode = targetNodeMapNode ? targetNodeMapNode.node : null;
const { targetPosition } = edge;
const { edgeTypes, edgeHandleSize, nodeSize, nodeKey, renderEdgeText } = this.props;
const selected = this.isEdgeSelected(edge);
return r(this.props.renderEdge || Edge, {
data: edge,
edgeTypes,
edgeHandleSize,
nodeSize,
sourceNode,
targetNode: targetNode || targetPosition,
nodeKey,
isSelected: selected,
renderEdgeText,
});
}
}
const size = 120;
EdgeBase.calculateOffset = function (nodeSize, source, target) {
const arrowVector = math.matrix([ target.x - source.x, target.y - source.y ]);
const offsetLength = Math.max(0, Math.min((0.75 * size), (math.norm(arrowVector) / 2) - 40));
const offsetVector = math.dotMultiply(arrowVector, (offsetLength / math.norm(arrowVector)) || 0);
return {
xOff: offsetVector.get([ 0 ]),
yOff: offsetVector.get([ 1 ]),
};
};
class Edge extends EdgeBase {
render() {
const { data } = this.props;
const id = `${data.source || ''}_${data.target}`;
const className = GraphUtils.classNames('edge', {
selected: this.props.isSelected,
});
return r.g({
className: 'edge-container',
'data-source': data.source,
'data-target': data.target,
}, [
r.g({
className,
}, [
r.path({
className: 'edge-path',
d: this.getPathDescription(data) || undefined,
}),
this.props.renderEdgeText && r(this.props.renderEdgeText, {
data,
transform: this.getEdgeHandleTranslation(),
}),
]),
r.g({
className: 'edge-mouse-handler',
}, [
r.path({
className: 'edge-overlay-path',
ref: this.edgeOverlayRef,
id,
'data-source': data.source,
'data-target': data.target,
d: this.getPathDescription(data) || undefined,
}),
]),
]);
}
}
module.exports = {
GraphView,
Edge,
};