@libs-ui/components-draw-line 0.2.356-38 → 0.2.356-40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/draw-line.directive.d.ts +3 -2
- package/draw-line.interface.d.ts +1 -1
- package/esm2022/draw-line.directive.mjs +41 -7
- package/esm2022/draw-line.interface.mjs +1 -1
- package/esm2022/util/calculator-diretion-element.until.mjs +10 -12
- package/esm2022/util/connect-navigation-new-element.util.mjs +2 -3
- package/esm2022/util/line-connect-bottom-left.until.mjs +1 -2
- package/fesm2022/libs-ui-components-draw-line.mjs +50 -20
- package/fesm2022/libs-ui-components-draw-line.mjs.map +1 -1
- package/package.json +2 -2
|
@@ -178,32 +178,32 @@ class MoCanvasCalculatorDirectionElementUtil {
|
|
|
178
178
|
}
|
|
179
179
|
return false;
|
|
180
180
|
});
|
|
181
|
-
if (!elementBlockRoad
|
|
181
|
+
if (!elementBlockRoad?.length) {
|
|
182
182
|
return undefined;
|
|
183
183
|
}
|
|
184
184
|
if (returnAllElementBlockRoad) {
|
|
185
185
|
return elementBlockRoad;
|
|
186
186
|
}
|
|
187
187
|
if (direction === 'y') {
|
|
188
|
-
return elementBlockRoad.reduce((a, b) => (Math.abs((a.y ?? 0) - start) < Math.abs((b.y ?? 0) - start) ? a : b));
|
|
188
|
+
return elementBlockRoad.reduce((a, b) => (Math.abs((a.y ?? 0) - start) < Math.abs((b.y ?? 0) - start) ? a : b), elementBlockRoad[0]);
|
|
189
189
|
}
|
|
190
|
-
return elementBlockRoad.reduce((a, b) => (Math.abs((a.x ?? 0) - start) < Math.abs((b.x ?? 0) - start) ? a : b));
|
|
190
|
+
return elementBlockRoad.reduce((a, b) => (Math.abs((a.x ?? 0) - start) < Math.abs((b.x ?? 0) - start) ? a : b), elementBlockRoad[0]);
|
|
191
191
|
}
|
|
192
192
|
// kiểm tra hướng thẳng vẽ về điểm end xem có bị chắn bởi khối nào không, nếu có thì phải lùi lại điểm end nhé.
|
|
193
193
|
static checkBlocksElementStraightY(startX, startY, endPosition, obstacleRect) {
|
|
194
194
|
const elementBlockRoad = this.checkLinePassBlockHorizontal(startY, endPosition.y, startX, 'y', obstacleRect, true);
|
|
195
|
-
if (!elementBlockRoad
|
|
195
|
+
if (!elementBlockRoad?.length) {
|
|
196
196
|
return;
|
|
197
197
|
}
|
|
198
|
-
return elementBlockRoad.reduce((a, b) => (Math.abs(a.x ?? 0 - startX) < Math.abs(b.x ?? 0 - startX) ? a : b));
|
|
198
|
+
return elementBlockRoad.reduce((a, b) => (Math.abs(a.x ?? 0 - startX) < Math.abs(b.x ?? 0 - startX) ? a : b), elementBlockRoad[0]);
|
|
199
199
|
}
|
|
200
200
|
// kiểm tra hướng ngang vẽ về điểm end xem có bị chắn bởi khối nào không, nếu có thì phải lùi lại điểm end nhé.
|
|
201
201
|
static checkBlocksElementX(startX, startY, endPosition, obstacleRect) {
|
|
202
202
|
const elementBlockRoad = this.checkLinePassBlockHorizontal(startX, endPosition.x, startY, 'x', obstacleRect, true);
|
|
203
|
-
if (!elementBlockRoad
|
|
203
|
+
if (!elementBlockRoad?.length) {
|
|
204
204
|
return;
|
|
205
205
|
}
|
|
206
|
-
return elementBlockRoad.reduce((a, b) => (Math.abs((a.y ?? 0) - startY) < Math.abs((b.y ?? 0) - startY) ? a : b));
|
|
206
|
+
return elementBlockRoad.reduce((a, b) => (Math.abs((a.y ?? 0) - startY) < Math.abs((b.y ?? 0) - startY) ? a : b), elementBlockRoad[0]);
|
|
207
207
|
}
|
|
208
208
|
// kiểm tra hướng sang phải là tránh khối
|
|
209
209
|
static checkAndAvoidBlocksLeft(startX, startY, lineCurve, endPosition, obstacleRect, separatedPoints) {
|
|
@@ -258,7 +258,7 @@ class MoCanvasCalculatorDirectionElementUtil {
|
|
|
258
258
|
}
|
|
259
259
|
const directionX = MoCanvasCalculatorDirectionElementUtil.checkUpDownLeftRight(startX, endPosition.x, 'x');
|
|
260
260
|
coordLX.x = (elementBlockRoad.x ?? 0) - MoCanvasConnectNavigationNewElementUtil.ELEMENT_MARGIN_BETWEEN_BRANCH_DEFAULT / 2 - lineCurve / 2;
|
|
261
|
-
|
|
261
|
+
const separatedPointsByPassElementOnRightSide = [];
|
|
262
262
|
const { pathByPassQ, endPath } = MoCanvasCalculatorDirectionElementUtil.byPassElementOnRightSide(coordLX.x, coordLX.y ?? 0, endPosition.y, lineCurve, elementBlockRoad, directionX, separatedPointsByPassElementOnRightSide, 'checkAndAvoidBlocks', coordLX.x);
|
|
263
263
|
let line = pathPre ? `${pathPre} L ${coordLX.x} ${coordLX.y} ${pathByPassQ}` : `L ${coordLX.x} ${coordLX.y} ${pathByPassQ}`;
|
|
264
264
|
// tính trước trường hợp sau để lùi line
|
|
@@ -268,7 +268,6 @@ class MoCanvasCalculatorDirectionElementUtil {
|
|
|
268
268
|
if (elementBlockRoadStraightLineY) {
|
|
269
269
|
const XNew = (elementBlockRoadStraightLineY.x ?? 0) - MoCanvasConnectNavigationNewElementUtil.ELEMENT_MARGIN_BETWEEN_BRANCH_DEFAULT / 2 - lineCurve / 2;
|
|
270
270
|
if (XNew < (endPath.x ?? 0)) {
|
|
271
|
-
separatedPointsByPassElementOnRightSide = [];
|
|
272
271
|
separatedPoints.push({ start: { x: startX, y: startY }, end: coordLX, mode: 'horizontal', id: 'checkAndAvoidBlocks', name: 'u' });
|
|
273
272
|
line = pathPre ? `${pathPre} L ${coordLX.x} ${coordLX.y}` : `L ${coordLX.x} ${coordLX.y}`;
|
|
274
273
|
return {
|
|
@@ -345,13 +344,12 @@ class MoCanvasCalculatorDirectionElementUtil {
|
|
|
345
344
|
ignoreBypassElement = true;
|
|
346
345
|
}
|
|
347
346
|
coordLX.y = MoCanvasCalculatorBranchUtil.mathOperatorsCalculation(directionY, y, lineCurve * 2);
|
|
348
|
-
|
|
347
|
+
const separatedPointsByPassElementOnRightSide = [];
|
|
349
348
|
const { pathByPassQ, endPath } = MoCanvasCalculatorDirectionElementUtil.byPassElementOnTopBottomSide(coordLX.x ?? 0, coordLX.y ?? 0, endPosition.x, lineCurve, elementBlockRoad, directionY, separatedPointsByPassElementOnRightSide, key);
|
|
350
349
|
let end = coordLX;
|
|
351
350
|
let line = pathPre ? `${pathPre} L ${coordLX.x} ${coordLX.y}` : `L ${coordLX.x} ${coordLX.y}`;
|
|
352
351
|
separatedPoints.push({ start: { x: startX, y: startY }, end: coordLX, mode: 'horizontal', id: key, name: 'b' });
|
|
353
352
|
if (ignoreBypassElement) {
|
|
354
|
-
separatedPointsByPassElementOnRightSide = [];
|
|
355
353
|
separatedPoints.push({ start: coordLX, end, mode: 'horizontal', id: key, name: 'c' });
|
|
356
354
|
return {
|
|
357
355
|
path: line,
|
|
@@ -518,7 +516,6 @@ class MoCanvasConnectNavigationBottomLeftElementUtil {
|
|
|
518
516
|
}
|
|
519
517
|
separatedPoints.push(...avoidBlocksYLine);
|
|
520
518
|
separatedPoints.push({ start: { x: straightLine.endPath.x ?? 0, y: straightLine.endPath.y ?? 0 }, end: endPosition, mode: 'vertical-single-curve', id: '4' });
|
|
521
|
-
return;
|
|
522
519
|
}
|
|
523
520
|
}
|
|
524
521
|
|
|
@@ -594,9 +591,8 @@ class MoCanvasConnectNavigationNewElementUtil {
|
|
|
594
591
|
endPath: LEnd,
|
|
595
592
|
};
|
|
596
593
|
}
|
|
597
|
-
let lineCurveSubY = lineCurve;
|
|
598
594
|
if (Math.abs((endPath.y ?? 0) - endPosition.y) < lineCurve * 2) {
|
|
599
|
-
lineCurveSubY = Math.abs((endPath.y ?? 0) - endPosition.y) / 2;
|
|
595
|
+
const lineCurveSubY = Math.abs((endPath.y ?? 0) - endPosition.y) / 2;
|
|
600
596
|
const coordQ1 = MoCanvasCalculatorDirectionElementUtil.drawLineQ({ x: endPath.x ?? 0, y: endPath.y ?? 0 }, `right-${directionY === 'above' ? 'above' : 'under'}`, lineCurveSubY * 2, lineCurveSubY); // tính đoạn cong từ đường ngang sang đường thẳng
|
|
601
597
|
const pathQ1 = `Q ${coordQ1.x1},${coordQ1.y1} ${coordQ1.x},${coordQ1.y}`; // từ ngang sang thẳng phải có đường cong
|
|
602
598
|
const coordQ2 = MoCanvasCalculatorDirectionElementUtil.drawLineQ({ x: coordQ1.x ?? 0, y: coordQ1.y ?? 0 }, `${directionY === 'above' ? 'above' : 'under'}-right`, lineCurveSubY * 2, lineCurveSubY); // tính đoạn cong từ đường thẳng sang ngang
|
|
@@ -991,7 +987,6 @@ class LibsUiComponentsDrawLineDirective {
|
|
|
991
987
|
});
|
|
992
988
|
}
|
|
993
989
|
startProcessDataRow(dataDraw) {
|
|
994
|
-
console.log('12121212dataDraw', dataDraw);
|
|
995
990
|
this.zone.runOutsideAngular(() => {
|
|
996
991
|
dataDraw.forEach((item) => {
|
|
997
992
|
const { pathElement, arrowElement, circleStartElement, circleEndElement } = this.createPathAndArrowElement(item.id);
|
|
@@ -1083,7 +1078,7 @@ class LibsUiComponentsDrawLineDirective {
|
|
|
1083
1078
|
points.separatedPoints.forEach((separatedPoints) => {
|
|
1084
1079
|
path += this.buildPathAndDrawSeparatedPoints(data, separatedPoints, separatedPoints.mode || mode);
|
|
1085
1080
|
});
|
|
1086
|
-
if (!points.pathElement
|
|
1081
|
+
if (!points.pathElement?.parentNode) {
|
|
1087
1082
|
const pathElement = document.createElementNS('http://www.w3.org/2000/svg', 'path');
|
|
1088
1083
|
this.svgElement.append(pathElement);
|
|
1089
1084
|
points.pathElement = pathElement;
|
|
@@ -1121,6 +1116,12 @@ class LibsUiComponentsDrawLineDirective {
|
|
|
1121
1116
|
this.dataDraw?.forEach((item) => {
|
|
1122
1117
|
const points = item.points;
|
|
1123
1118
|
addPoints(points);
|
|
1119
|
+
// Nếu mode là s-line, thêm offset cho control points để viewBox đủ rộng cho curve vòng ra ngoài
|
|
1120
|
+
if (item.mode === 's-line') {
|
|
1121
|
+
const offsetDistance = 1000;
|
|
1122
|
+
xPoints.add(points.start.x + offsetDistance);
|
|
1123
|
+
xPoints.add(points.end.x - offsetDistance);
|
|
1124
|
+
}
|
|
1124
1125
|
points.separatedPoints?.forEach((separatedPoints) => addPoints(separatedPoints));
|
|
1125
1126
|
points.obstacleRect?.forEach((obstacleRect) => {
|
|
1126
1127
|
addPoints({
|
|
@@ -1129,8 +1130,8 @@ class LibsUiComponentsDrawLineDirective {
|
|
|
1129
1130
|
});
|
|
1130
1131
|
});
|
|
1131
1132
|
});
|
|
1132
|
-
const xMax = this.viewBoxConfig?.width ?? (
|
|
1133
|
-
const yMax = this.viewBoxConfig?.height ?? (
|
|
1133
|
+
const xMax = this.viewBoxConfig?.width ?? (xPoints.size ? Math.max(...xPoints) : 0) + 14;
|
|
1134
|
+
const yMax = this.viewBoxConfig?.height ?? (yPoints.size ? Math.max(...yPoints) : 0) + 14;
|
|
1134
1135
|
if (!this.viewBoxConfig?.ignoreViewBox) {
|
|
1135
1136
|
const rectSvgElement = this.svgElement.getBoundingClientRect();
|
|
1136
1137
|
this.svgElement?.setAttribute('viewBox', `${this.viewBoxConfig?.minX ?? rectSvgElement.x} ${this.viewBoxConfig?.minY ?? rectSvgElement.y} ${xMax} ${yMax}`);
|
|
@@ -1176,12 +1177,17 @@ class LibsUiComponentsDrawLineDirective {
|
|
|
1176
1177
|
curve = curve ?? 10;
|
|
1177
1178
|
distancePoint = distancePoint ?? 10;
|
|
1178
1179
|
}
|
|
1179
|
-
if (mode === 'quart-in' || points.start.x === points.end.x || points.start.y === points.end.y) {
|
|
1180
|
-
|
|
1180
|
+
if (mode === 'quart-in' || mode === 's-line' || points.start.x === points.end.x || points.start.y === points.end.y) {
|
|
1181
|
+
if (mode !== 's-line') {
|
|
1182
|
+
this.drawBalancedCurve(dPath, points);
|
|
1183
|
+
}
|
|
1181
1184
|
if (mode === 'quart-in') {
|
|
1182
1185
|
dPath = {};
|
|
1183
1186
|
this.drawBendBothEndsCurve(dPath, points);
|
|
1184
1187
|
}
|
|
1188
|
+
if (mode === 's-line') {
|
|
1189
|
+
this.drawBendBothEndsCurveSLine(dPath, points);
|
|
1190
|
+
}
|
|
1185
1191
|
points.pathElement?.setAttribute('d', this.builDAttributeToString(dPath));
|
|
1186
1192
|
this.drawRectAndInitEvent(data, mode);
|
|
1187
1193
|
return;
|
|
@@ -1253,6 +1259,22 @@ class LibsUiComponentsDrawLineDirective {
|
|
|
1253
1259
|
{ x: points.end.x, y: points.end.y },
|
|
1254
1260
|
];
|
|
1255
1261
|
}
|
|
1262
|
+
drawBendBothEndsCurveSLine(dPath, points) {
|
|
1263
|
+
// Khi X gần nhau → giảm offset để tránh cong quá; khi X xa nhau → offset lớn hơn để tạo S-curve rõ ràng
|
|
1264
|
+
const deltaX = points.end.x - points.start.x;
|
|
1265
|
+
const offsetDistance = Math.min(180, Math.max(80, Math.abs(deltaX)));
|
|
1266
|
+
const deltaY = points.end.y - points.start.y;
|
|
1267
|
+
// LUÔN ĐI RA PHẢI từ start, VÀO TỪ TRÁI của end (hoặc giữ tại end nếu start ở trên end)
|
|
1268
|
+
const rightX = points.start.x + offsetDistance;
|
|
1269
|
+
const leftX = deltaY > 0 ? points.end.x : points.end.x - offsetDistance;
|
|
1270
|
+
dPath.M = { x: points.start.x, y: points.start.y };
|
|
1271
|
+
// Cubic bezier curve duy nhất với control points tính toán để tạo S-curve mượt
|
|
1272
|
+
dPath.C = [
|
|
1273
|
+
{ x: rightX, y: points.start.y + deltaY * (deltaY < 0 || deltaX < 0 ? 0.5 : 0.1) },
|
|
1274
|
+
{ x: leftX, y: points.end.y - deltaY * 0.5 },
|
|
1275
|
+
{ x: points.end.x, y: points.end.y },
|
|
1276
|
+
];
|
|
1277
|
+
}
|
|
1256
1278
|
buildDAttributeByPointEndModeHorizontal(dPath, points, distancePoint, curve, mode) {
|
|
1257
1279
|
if (!mode.includes('horizontal')) {
|
|
1258
1280
|
return;
|
|
@@ -1389,6 +1411,14 @@ class LibsUiComponentsDrawLineDirective {
|
|
|
1389
1411
|
}
|
|
1390
1412
|
const modeHorizontal = pointStart.x < points.end.x ? 'right' : 'left';
|
|
1391
1413
|
const modeVertical = pointStart.y < points.end.y ? 'bottom' : 'top';
|
|
1414
|
+
// Mode s-line: nếu end ở dưới start → mũi tên chỉ xuống (bottom); ngược lại → mũi tên chỉ ngang (right)
|
|
1415
|
+
if (mode === 's-line') {
|
|
1416
|
+
const deltaY = points.end.y - points.start.y;
|
|
1417
|
+
if (deltaY > 0) {
|
|
1418
|
+
return 'bottom';
|
|
1419
|
+
}
|
|
1420
|
+
return 'right';
|
|
1421
|
+
}
|
|
1392
1422
|
if (mode?.includes('vertical') && !mode.includes('single-curve')) {
|
|
1393
1423
|
return modeVertical;
|
|
1394
1424
|
}
|