123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245 |
- <template>
- <g class="lines-wrap">
- <marker
- id="markerArrow"
- markerUnits="strokeWidth"
- markerWidth="5"
- markerHeight="4"
- refX="6"
- refY="2"
- orient="auto"
- >
- <path d="M 0 0 L 5 2 L 0 4 z" class="trangle" />
- </marker>
- <path
- v-for="i in linesAttr"
- :key="i.id"
- v-bind="i"
- class="line"
- marker-end="url(#markerArrow)"
- />
- </g>
- </template>
- <script setup>
- import { 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 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}`,
- 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>
- <style lang="less" scoped>
- .lines-wrap {
- .line {
- stroke: #5ba8ff;
- stroke-width: 2;
- fill: transparent;
- }
- .trangle {
- stroke: #5ba8ff;
- fill: #5ba8ff;
- }
- }
- </style>
|