diff --git a/simple-mind-map/src/layouts/Base.js b/simple-mind-map/src/layouts/Base.js index c703c12e..93d07fef 100644 --- a/simple-mind-map/src/layouts/Base.js +++ b/simple-mind-map/src/layouts/Base.js @@ -295,6 +295,65 @@ class Base { return `M ${x1},${y1} C ${cx1},${cy1} ${cx2},${cy2} ${x2},${y2}` } + // 根据a,b两个点的位置,计算去除圆角大小后的新的b点 + computeNewPoint(a, b, radius = 0) { + // x坐标相同 + if (a[0] === b[0]) { + // b在a下方 + if (b[1] > a[1]) { + return [b[0], b[1] - radius] + } else { + // b在a上方 + return [b[0], b[1] + radius] + } + } else if (a[1] === b[1]) { + // y坐标相同 + // b在a右边 + if (b[0] > a[0]) { + return [b[0] - radius, b[1]] + } else { + return [b[0] + radius, b[1]] + } + } + } + + // 创建一段折线路径 + // 最后一个拐角支持圆角 + createFoldLine(list) { + const { lineRadius } = this.mindMap.themeConfig + const len = list.length + let path = '' + let radiusPath = '' + if (len >= 3 && lineRadius > 0) { + const start = list[len - 3] + const center = list[len - 2] + const end = list[len - 1] + // 如果三点在一条直线,那么不用处理 + const isOneLine = + (start[0] === center[0] && center[0] === end[0]) || + (start[1] === center[1] && center[1] === end[1]) + if (!isOneLine) { + const cStart = this.computeNewPoint(start, center, lineRadius) + const cEnd = this.computeNewPoint(end, center, lineRadius) + radiusPath = `Q ${center[0]},${center[1]} ${cEnd[0]},${cEnd[1]}` + list.splice(len - 2, 1, cStart, radiusPath) + } + } + list.forEach((item, index) => { + if (typeof item === 'string') { + path += item + } else { + const [x, y] = item + if (index === 0) { + path += `M ${x},${y}` + } else { + path += `L ${x},${y}` + } + } + }) + return path + } + // 获取节点的marginX getMarginX(layerIndex) { const { themeConfig, opt } = this.mindMap diff --git a/simple-mind-map/src/layouts/LogicalStructure.js b/simple-mind-map/src/layouts/LogicalStructure.js index 065402d2..a5043994 100644 --- a/simple-mind-map/src/layouts/LogicalStructure.js +++ b/simple-mind-map/src/layouts/LogicalStructure.js @@ -178,9 +178,12 @@ class LogicalStructure extends Base { let nodeUseLineStyleOffset = nodeUseLineStyle ? item.width : 0 y1 = nodeUseLineStyle && !node.isRoot ? y1 + height / 2 : y1 y2 = nodeUseLineStyle ? y2 + item.height / 2 : y2 - let path = `M ${x1},${y1} L ${x1 + s1},${y1} L ${x1 + s1},${y2} L ${ - x2 + nodeUseLineStyleOffset - },${y2}` + let path = this.createFoldLine([ + [x1, y1], + [x1 + s1, y1], + [x1 + s1, y2], + [x2 + nodeUseLineStyleOffset, y2] + ]) this.setLineStyle(style, lines[index], path, item) }) } diff --git a/simple-mind-map/src/layouts/MindMap.js b/simple-mind-map/src/layouts/MindMap.js index 249f981d..f3f7bfa1 100644 --- a/simple-mind-map/src/layouts/MindMap.js +++ b/simple-mind-map/src/layouts/MindMap.js @@ -240,9 +240,12 @@ class MindMap extends Base { let y2 = item.top + item.height / 2 y1 = nodeUseLineStyle && !node.isRoot ? y1 + height / 2 : y1 y2 = nodeUseLineStyle ? y2 + item.height / 2 : y2 - let path = `M ${x1},${y1} L ${x1 + _s},${y1} L ${x1 + _s},${y2} L ${ - x2 + nodeUseLineStyleOffset - },${y2}` + let path = this.createFoldLine([ + [x1, y1], + [x1 + _s, y1], + [x1 + _s, y2], + [x2 + nodeUseLineStyleOffset, y2] + ]) this.setLineStyle(style, lines[index], path, item) }) } diff --git a/simple-mind-map/src/layouts/VerticalTimeline.js b/simple-mind-map/src/layouts/VerticalTimeline.js index e3352815..c8262de6 100644 --- a/simple-mind-map/src/layouts/VerticalTimeline.js +++ b/simple-mind-map/src/layouts/VerticalTimeline.js @@ -259,11 +259,12 @@ class VerticalTimeline extends Base { node.children.forEach((item, index) => { let itemLeft = item.left let itemYCenter = item.top + item.height / 2 - let path = ` - M ${nodeRight},${nodeYCenter} - L ${nodeRight + offset},${nodeYCenter} - L ${nodeRight + offset},${itemYCenter} - L ${itemLeft},${itemYCenter}` + let path = this.createFoldLine([ + [nodeRight, nodeYCenter], + [nodeRight + offset, nodeYCenter], + [nodeRight + offset, itemYCenter], + [itemLeft, itemYCenter] + ]) this.setLineStyle(style, lines[index], path, item) }) } else { @@ -274,11 +275,12 @@ class VerticalTimeline extends Base { node.children.forEach((item, index) => { let itemRight = item.left + item.width let itemYCenter = item.top + item.height / 2 - let path = ` - M ${nodeLeft},${nodeYCenter} - L ${nodeLeft - offset},${nodeYCenter} - L ${nodeLeft - offset},${itemYCenter} - L ${itemRight},${itemYCenter}` + let path = this.createFoldLine([ + [nodeLeft, nodeYCenter], + [nodeLeft - offset, nodeYCenter], + [nodeLeft - offset, itemYCenter], + [itemRight, itemYCenter] + ]) this.setLineStyle(style, lines[index], path, item) }) } diff --git a/simple-mind-map/src/themes/default.js b/simple-mind-map/src/themes/default.js index 53f5f2f0..27123e85 100644 --- a/simple-mind-map/src/themes/default.js +++ b/simple-mind-map/src/themes/default.js @@ -20,6 +20,8 @@ export default { lineStyle: 'straight', // 针对logicalStructure、mindMap两种结构。曲线(curve)、直线(straight)、直连(direct) // 曲线连接时,根节点和其他节点的连接线样式保持统一,默认根节点为 ( 型,其他节点为 { 型,设为true后,都为 { 型 rootLineKeepSameInCurve: true, + // 直线连接时,连线的圆角大小,设置为0代表没有圆角,仅支持logicalStructure、mindMap、verticalTimeline三种结构 + lineRadius: 5, // 连线尾部是否显示标记,目前只支持箭头 showLineMarker: false, // 概要连线的粗细