|
@@ -11,7 +11,7 @@
|
|
|
>
|
|
|
<path d="M 0 0 L 5 2 L 0 4 z" class="trangle" />
|
|
|
</marker>
|
|
|
- <line
|
|
|
+ <path
|
|
|
v-for="i in linesAttr"
|
|
|
:key="i.id"
|
|
|
v-bind="i"
|
|
@@ -26,21 +26,205 @@ import { defineProps, computed } from "vue";
|
|
|
import { countPointByPos } from "../utils/index";
|
|
|
const props = defineProps(["nodes", "lines"]);
|
|
|
|
|
|
+function getTransitPoint(pos, point) {
|
|
|
+ const transitSpace = 20;
|
|
|
+ switch (pos) {
|
|
|
+ case "left":
|
|
|
+ return {
|
|
|
+ cx: point.cx - transitSpace,
|
|
|
+ cy: point.cy,
|
|
|
+ };
|
|
|
+ case "top":
|
|
|
+ return {
|
|
|
+ cx: point.cx,
|
|
|
+ cy: point.cy - transitSpace,
|
|
|
+ };
|
|
|
+ case "right":
|
|
|
+ return {
|
|
|
+ cx: point.cx + transitSpace,
|
|
|
+ cy: point.cy,
|
|
|
+ };
|
|
|
+ case "bottom":
|
|
|
+ return {
|
|
|
+ cx: point.cx,
|
|
|
+ cy: point.cy + transitSpace,
|
|
|
+ };
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+function getAnchor(start, end) {
|
|
|
+ const { point: startPoint, node: startNode, pos: startPos } = start;
|
|
|
+ const { point: endPoint, node: endNode, pos: endPos } = end;
|
|
|
+
|
|
|
+ let p1, p2;
|
|
|
+ const space = 20;
|
|
|
+ if (["left", "right"].includes(startPos)) {
|
|
|
+ p1 = {
|
|
|
+ cx: startPoint.cx,
|
|
|
+ cy:
|
|
|
+ startPoint.cy +
|
|
|
+ (endPoint.cy > startPoint.cy
|
|
|
+ ? startNode.size.height / 2 + 20
|
|
|
+ : -(startNode.size.height / 2 + 20)),
|
|
|
+ };
|
|
|
+ } else {
|
|
|
+ p1 = {
|
|
|
+ cx:
|
|
|
+ startPoint.cx +
|
|
|
+ (endPoint.cx > startPoint.cx
|
|
|
+ ? startNode.size.width / 2 + 20
|
|
|
+ : -(startNode.size.width / 2 + 20)),
|
|
|
+ cy: startPoint.cy,
|
|
|
+ };
|
|
|
+ }
|
|
|
+ if (["left", "right"].includes(endPos)) {
|
|
|
+ p2 = {
|
|
|
+ cx: endPoint.cx,
|
|
|
+ cy:
|
|
|
+ endPoint.cy +
|
|
|
+ (endPoint.cy > startPoint.cy
|
|
|
+ ? -(endNode.size.height / 2 + 20)
|
|
|
+ : endNode.size.height / 2 + 20),
|
|
|
+ };
|
|
|
+ } else {
|
|
|
+ p2 = {
|
|
|
+ cx:
|
|
|
+ endPoint.cx +
|
|
|
+ (endPoint.cx > startPoint.cx
|
|
|
+ ? -(endNode.size.width / 2 + 20)
|
|
|
+ : endNode.size.width / 2 + 20),
|
|
|
+ cy: endPoint.cy,
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ return [p1, p2];
|
|
|
+}
|
|
|
+
|
|
|
+function getCenterPoint(start, end) {
|
|
|
+ const { point: startPoint, node: startNode, pos: startPos } = start;
|
|
|
+ const { point: endPoint, node: endNode, pos: endPos } = end;
|
|
|
+ // const [p1, p2] = getAnchor(start, end);
|
|
|
+ // const points = [
|
|
|
+ // startPoint,
|
|
|
+ // p1,
|
|
|
+ // {
|
|
|
+ // cx: p1.cx,
|
|
|
+ // cy: p2.cy,
|
|
|
+ // },
|
|
|
+ // p2,
|
|
|
+ // endPoint,
|
|
|
+ // ];
|
|
|
+
|
|
|
+ // points.forEach((p, index) => {
|
|
|
+ // if (index >= 2) {
|
|
|
+ // const preP1 = points[index - 1];
|
|
|
+ // const preP2 = points[index - 2];
|
|
|
+ // if (preP1.cx === preP2.cx && preP1.cx === p.cx) {
|
|
|
+ // preP2.cy = preP1.cy = Math.min(preP2.cy, preP1.cy, p.cy);
|
|
|
+ // }
|
|
|
+ // if (preP1.cy === preP2.cy && preP1.cy === p.cy) {
|
|
|
+ // preP2.cx = preP1.cx = Math.min(preP2.cx, preP1.cx, p.cx);
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+ // });
|
|
|
+ // return points;
|
|
|
+ return [startPoint, { cx: startPoint.cx, cy: endPoint.cy }, endPoint];
|
|
|
+ // const points = [];
|
|
|
+ // let p1, p2;
|
|
|
+ // if (["left", "right"].includes(startNode.pos)) {
|
|
|
+ // p1 = {
|
|
|
+ // cx: start.cx,
|
|
|
+ // cy: end.cy,
|
|
|
+ // };
|
|
|
+ // } else {
|
|
|
+ // p1 = {
|
|
|
+ // cx: end.cx,
|
|
|
+ // cy: start.cy,
|
|
|
+ // };
|
|
|
+ // }
|
|
|
+ // if (["left", "right"].includes(endNode.pos)) {
|
|
|
+ // p2 = {
|
|
|
+ // cx: end.cx,
|
|
|
+ // cy: p1.cy,
|
|
|
+ // };
|
|
|
+ // } else {
|
|
|
+ // p2 = {
|
|
|
+ // cx: p1.cx,
|
|
|
+ // cy: end.cy,
|
|
|
+ // };
|
|
|
+ // }
|
|
|
+ // if (start.cx < end.cx && endNode.pos === "right") {
|
|
|
+ // const topSpace = Math.min(startNode.node.pos.y, endNode.node.pos.y) - 20;
|
|
|
+ // return [
|
|
|
+ // {
|
|
|
+ // cx: start.cx,
|
|
|
+ // cy: startNode.node.pos.cy + (end.cy - start.cy) / 2,
|
|
|
+ // },
|
|
|
+ // {
|
|
|
+ // cx: end.cx,
|
|
|
+ // cy: start.cy + (end.cy - start.cy) / 2,
|
|
|
+ // },
|
|
|
+ // ];
|
|
|
+ // }
|
|
|
+ // if (start.cy > end.cy) {
|
|
|
+ // const endWidth = endNode.size.width / 2 + 20;
|
|
|
+ // return [
|
|
|
+ // {
|
|
|
+ // cx: start.cx - endWidth,
|
|
|
+ // cy: end.cy,
|
|
|
+ // },
|
|
|
+ // {
|
|
|
+ // cx: end.cx - endWidth,
|
|
|
+ // cy: end.cy,
|
|
|
+ // },
|
|
|
+ // ];
|
|
|
+ // }
|
|
|
+ // return [p1, p2];
|
|
|
+ // return [
|
|
|
+ // {
|
|
|
+ // cx: start.cx,
|
|
|
+ // cy: end.cy,
|
|
|
+ // },
|
|
|
+ // {
|
|
|
+ // cx: start.cx,
|
|
|
+ // cy: end.cy,
|
|
|
+ // },
|
|
|
+ // ];
|
|
|
+}
|
|
|
+
|
|
|
const linesAttr = computed(() =>
|
|
|
props.lines.map((line) => {
|
|
|
const { targetId: startTargetId, pos: startPos } = line.start;
|
|
|
const { targetId: endTargetId, pos: endPos } = line.end;
|
|
|
const startNode = props.nodes.find((i) => i.id === startTargetId);
|
|
|
const endNode = props.nodes.find((i) => i.id === endTargetId);
|
|
|
- const endPoint = countPointByPos(endPos, endNode.pos, endNode.size);
|
|
|
const startPoint = countPointByPos(startPos, startNode.pos, startNode.size);
|
|
|
+ const endPoint = countPointByPos(endPos, endNode.pos, endNode.size);
|
|
|
+
|
|
|
+ const startTransitPoint = getTransitPoint(startPos, startPoint);
|
|
|
+ const endTransitPoint = getTransitPoint(endPos, endPoint);
|
|
|
+ const centerPoints = getCenterPoint(
|
|
|
+ { node: startNode, pos: startPos, point: startTransitPoint },
|
|
|
+ { node: endNode, pos: endPos, point: endTransitPoint }
|
|
|
+ );
|
|
|
+
|
|
|
return {
|
|
|
id: `${startTargetId}-${startPos}-${endTargetId}-${endPos}`,
|
|
|
- x1: startPoint.cx,
|
|
|
- y1: startPoint.cy,
|
|
|
- x2: endPoint.cx,
|
|
|
- y2: endPoint.cy,
|
|
|
+ d: [
|
|
|
+ `M${startPoint.cx} ${startPoint.cy}`,
|
|
|
+ ...centerPoints.map((i) => `L${i.cx} ${i.cy}`),
|
|
|
+ `L${endPoint.cx} ${endPoint.cy}`,
|
|
|
+ ].join(" "),
|
|
|
};
|
|
|
+ // return {
|
|
|
+ // id: `${startTargetId}-${startPos}-${endTargetId}-${endPos}`,
|
|
|
+ // x1: startPoint.cx,
|
|
|
+ // y1: startPoint.cy,
|
|
|
+ // x2: endPoint.cx,
|
|
|
+ // y2: endPoint.cy,
|
|
|
+ // };
|
|
|
})
|
|
|
);
|
|
|
</script>
|
|
@@ -50,6 +234,7 @@ const linesAttr = computed(() =>
|
|
|
.line {
|
|
|
stroke: #5ba8ff;
|
|
|
stroke-width: 2;
|
|
|
+ fill: transparent;
|
|
|
}
|
|
|
|
|
|
.trangle {
|