UNPKG

@antv/g6

Version:

graph visualization frame work

192 lines (187 loc) 5.67 kB
/** * @fileOverview edge item * @author huangtonger@aliyun.com */ const Util = require('../util/'); const Item = require('./item'); class Edge extends Item { constructor(cfg) { const defaultCfg = { type: 'edge', isEdge: true, zIndex: 2 }; Util.mix(defaultCfg, cfg); super(defaultCfg); } _beforeDraw() { const model = this.model; const itemMap = this.itemMap; if (!Util.isObject(model.source)) { this.source = itemMap[model.source]; } else { this.source = model.source; } if (!Util.isObject(model.target)) { this.target = itemMap[model.target]; } else { this.target = model.target; } super._beforeDraw(); } _afterDraw() { if (!this.linkedItemVisible()) { this.hide(); } this._addArrow(); super._afterDraw(); } _addArrow() { const model = this.model; const keyShape = this.keyShape; const shapeObj = this.shapeObj; const styleEndArrow = keyShape.attr('endArrow'); const styleStartArrow = keyShape.attr('startArrow'); const endArrow = model.endArrow || styleEndArrow; const startArrow = model.startArrow || styleStartArrow; styleStartArrow && keyShape.attr('startArrow', false); styleEndArrow && keyShape.attr('endArrow', false); endArrow && this._drawArrow(shapeObj.endArrow, 'end'); startArrow && this._drawArrow(shapeObj.startArrow, 'start'); } _drawArrow({ path, dindent, tangent, ratio, style }, type) { tangent = tangent(this); dindent = dindent(this); path = path(this); style = style(this); ratio = ratio(); const group = this.group; const keyShape = this.keyShape; const point = keyShape.getPoint(ratio); if (!point) { return; } const keyShapePath = Util.cloneDeep(keyShape.attr('path')); const marker = group.addShape('marker', { attrs: { symbol: () => { return path; }, ...style } }); const x = tangent[1][0] - tangent[0][0]; const y = tangent[1][1] - tangent[0][1]; const tangentLength = Math.sqrt(x * x + y * y); const dindentRatio = dindent / tangentLength; const vDindent = [ -x * dindentRatio, -y * dindentRatio ]; let deg = 0; const tan = Math.atan(x / y); if (y === 0 && x < 0) { deg = Math.PI; } else if (x > 0 && y > 0) { deg = Math.PI / 2 - tan; } else if (x < 0 && y < 0) { deg = -Math.PI / 2 - tan; } else if (x >= 0 && y < 0) { deg = -tan - Math.PI / 2; } else if (x <= 0 && y > 0) { deg = Math.PI / 2 - tan; } marker.rotate(deg); marker.translate(point.x, point.y); if (type === 'end') { const lastSegment = keyShapePath[keyShapePath.length - 1]; lastSegment[lastSegment.length - 1] = vDindent[1] + point.y; lastSegment[lastSegment.length - 2] = vDindent[0] + point.x; } else { const startSegment = keyShapePath[0]; startSegment[startSegment.length - 1] = vDindent[1] + point.y; startSegment[startSegment.length - 2] = vDindent[0] + point.x; } keyShape.attr('path', keyShapePath); } _getControlPoints() { const controlPoints = this.model.controlPoints; if (Util.isArray(controlPoints)) { return controlPoints; } return []; } _shouldDraw() { return super._shouldDraw() && this.linkedItemVisible(); } _getPoint(point) { if (point.linkable) { const box = point.getBBox(); return { x: box.centerX, y: box.centerY }; } return { x: point.x, y: point.y }; } // layoutUpdate() { // const group = this.getGraphicGroup(); // const children = group.get('children'); // this._beforeDraw(); // if (children.length === 1) { // const keyShape = this.keyShape; // const shapeObj = this.shapeObj; // keyShape.attr('path', shapeObj.getPath(this)); // } else { // this.draw(); // } // this._afterDraw(); // } linkedItemVisible() { const source = this.source; const target = this.target; return Util.isPlainObject(source) || Util.isPlainObject(target) || source.isVisible() || target.isVisible() || (source.collapsedParent !== target.collapsedParent); } getSource() { const source = this.source; const collapsedParent = source.collapsedParent; const itemMap = this.itemMap; if (collapsedParent) { return itemMap[collapsedParent.id]; } return source; } getTarget() { const target = this.target; const collapsedParent = target.collapsedParent; const itemMap = this.itemMap; if (collapsedParent) { return itemMap[collapsedParent.id]; } return target; } getPoints() { const source = this.getSource(); const target = this.getTarget(); const model = this.model; const controlPoints = this._getControlPoints(); const sourcePoint = this._getPoint(source); const targetPoint = this._getPoint(target); const points = [ sourcePoint ].concat(controlPoints).concat([ targetPoint ]); const psl = points.length; if (source.linkable) { const point = (Util.isNumber(this.model.sourceAnchor) && source.id === model.source) ? this.model.sourceAnchor : points[1]; const interPoint = source.getLinkPoints(point); points[0] = interPoint[0]; } if (target.linkable) { const point = (Util.isNumber(this.model.targetAnchor) && target.id === model.target) ? this.model.targetAnchor : points[psl - 2]; const interPoint = target.getLinkPoints(point); points[psl - 1] = interPoint[0]; } return points; } } module.exports = Edge;