From afbc5440b7a80557d4b772bb369de054b20e8cbf Mon Sep 17 00:00:00 2001 From: "shiwu.wyy" Date: Wed, 7 Aug 2019 20:08:06 +0800 Subject: [PATCH] arc edge --- demos/test.html | 30 +++++++++++----------- src/shape/edge.js | 63 +++++++++++++++++++++++++++++++++-------------- 2 files changed, 60 insertions(+), 33 deletions(-) diff --git a/demos/test.html b/demos/test.html index 51c53677fa..2879447dda 100644 --- a/demos/test.html +++ b/demos/test.html @@ -26,13 +26,13 @@ const data = { nodes: [{ id: 'node5', x: 100, - y: 100, + y: 180, label: '5', size: 80 },{ id: 'node6', x: 400, - y: 50, + y: 150, label: '6', size: 50 },{ @@ -47,26 +47,28 @@ const data = { source: 'node6', target: 'node5', shape: 'arc', - edgeOffset: -50 + curveOffset: -150 + }, + { + source: 'node6', + target: 'node5', + shape: 'arc', + curveOffset: 50 }, { source: 'node5', target: 'node6', shape: 'arc', - edgeOffset: 50 + curveOffset: 50 }, { - source: 'node5', - target: 'node6', + source: 'node7', + target: 'node5', shape: 'arc', - edgeOffset: -50 - }, - { - source: 'node5', - target: 'node7', - shape: 'arc', - edgeOffset: 50 - }] + controlPoints: [{ x: 200, y: 315 }] + // controlPoints: [{ x: 350, y: 315 }] + } +] }; const graph = new G6.Graph({ container: 'mountNode', diff --git a/src/shape/edge.js b/src/shape/edge.js index bb8aca76b0..d4098df9d2 100644 --- a/src/shape/edge.js +++ b/src/shape/edge.js @@ -178,34 +178,59 @@ Shape.registerEdge('spline', { }, 'single-line'); Shape.registerEdge('arc', { - curveOffset: 30, + curveOffset: 20, + clockwise: 1, getControlPoints(cfg) { - const startPoint = cfg.sourceNode.getModel().x; - const endPoint = cfg.sourceNode.getModel().y; - const midPoint = { - x: (startPoint.x + endPoint.x) / 2, - y: (startPoint.y + endPoint.y) / 2 - }; - const vec = { - x: endPoint.x - startPoint.x, - y: endPoint.y - startPoint.y - }; - const edgeAngle = Math.atan2(vec.y, vec.x); - const arcPoint = { - x: this.curveOffset * Math.cos((-Math.PI / 2 + edgeAngle)) + midPoint.x, - y: this.curveOffset * Math.sin((-Math.PI / 2 + edgeAngle)) + midPoint.y - }; + const startPoint = { x: cfg.sourceNode.getModel().x, y: cfg.sourceNode.getModel().y }; + const endPoint = { x: cfg.targetNode.getModel().x, y: cfg.targetNode.getModel().y }; + let arcPoint; + // 根据给定点计算圆弧 + if (cfg.controlPoints !== undefined) { + arcPoint = cfg.controlPoints[0]; + // 根据控制点和直线关系决定 clockwise值 + // 若给定点和两端点共线,无法生成圆弧,绘制直线 + if ((arcPoint.x - startPoint.x) / (arcPoint.y - startPoint.y) + === (endPoint.x - startPoint.x) / (endPoint.y - startPoint.y)) { + return []; + } + } else { // 根据直线连线中点的的偏移计算圆弧 + // 若用户给定偏移量则根据其计算,否则按照默认偏移值计算 + if (cfg.curveOffset !== undefined) { + this.curveOffset = cfg.curveOffset; + } + if (this.curveOffset < 0) this.clockwise = 0; + else this.clockwise = 1; + const midPoint = { + x: (startPoint.x + endPoint.x) / 2, + y: (startPoint.y + endPoint.y) / 2 + }; + const vec = { + x: endPoint.x - startPoint.x, + y: endPoint.y - startPoint.y + }; + const edgeAngle = Math.atan2(vec.y, vec.x); + arcPoint = { + x: this.curveOffset * Math.cos((-Math.PI / 2 + edgeAngle)) + midPoint.x, + y: this.curveOffset * Math.sin((-Math.PI / 2 + edgeAngle)) + midPoint.y + }; + } const center = Util.getCircleCenterByPoints(startPoint, arcPoint, endPoint); + console.log('distance center controlpoint', Util.distance(center, arcPoint)); const radius = Util.distance(startPoint, center); - const controlPoints = [ startPoint, { x: radius, y: radius }, endPoint ]; + console.log('radius', radius); + const controlPoints = [{ x: radius, y: radius }]; return controlPoints; }, getPath(points) { - console.log(points); const path = []; path.push([ 'M', points[0].x, points[0].y ]); - path.push([ 'A', points[1].x, points[1].y, 0, 0, 0, points[2].x, points[2].y ]); + // 控制点与端点共线 + if (points.length === 2) { + path.push([ 'L', points[1].x, points[1].y ]); + } else { + path.push([ 'A', points[1].x, points[1].y, 0, 0, this.clockwise, points[2].x, points[2].y ]); + } return path; } }, 'single-line');