advance.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. "use strict";
  2. var __rest = (this && this.__rest) || function (s, e) {
  3. var t = {};
  4. for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
  5. t[p] = s[p];
  6. if (s != null && typeof Object.getOwnPropertySymbols === "function")
  7. for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
  8. if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
  9. t[p[i]] = s[p[i]];
  10. }
  11. return t;
  12. };
  13. Object.defineProperty(exports, "__esModule", { value: true });
  14. exports.Advance = void 0;
  15. const gui_1 = require("@antv/gui");
  16. const d3_shape_1 = require("d3-shape");
  17. const createElement_1 = require("../../utils/createElement");
  18. const utils_1 = require("../utils");
  19. const helper_1 = require("../../utils/helper");
  20. const selection_1 = require("../../utils/selection");
  21. const vector_1 = require("../../utils/vector");
  22. function getConnectorPoint(shape) {
  23. const { min: [x0, y0], max: [x1, y1], } = shape.getLocalBounds();
  24. let x = 0;
  25. let y = 0;
  26. if (x0 > 0)
  27. x = x0;
  28. if (x1 < 0)
  29. x = x1;
  30. if (y0 > 0)
  31. y = y0;
  32. if (y1 < 0)
  33. y = y1;
  34. return [x, y];
  35. }
  36. function inferBackgroundBounds(textShape, padding = []) {
  37. const [top = 0, right = 0, bottom = top, left = right] = padding;
  38. const container = textShape.parentNode;
  39. const angle = container.getEulerAngles();
  40. container.setEulerAngles(0);
  41. const { min, halfExtents } = textShape.getLocalBounds();
  42. const [x, y] = min;
  43. const [hw, hh] = halfExtents;
  44. container.setEulerAngles(angle);
  45. return {
  46. x: x - left,
  47. y: y - top,
  48. width: hw * 2 + left + right,
  49. height: hh * 2 + top + bottom,
  50. };
  51. }
  52. const cos = (p0, p1, p2) => {
  53. const a = (0, vector_1.dist)(p0, p1);
  54. const b = (0, vector_1.dist)(p1, p2);
  55. const c = (0, vector_1.dist)(p2, p0);
  56. return (Math.pow(a, 2) + Math.pow(b, 2) - Math.pow(c, 2)) / (2 * a * b);
  57. };
  58. function inferConnectorPath(shape, points, controlPoints, coordCenter) {
  59. const [[x0, y0], [x1, y1]] = points;
  60. const [x, y] = getConnectorPoint(shape);
  61. // Straight connector line.
  62. if (x0 === x1 && y0 === y1) {
  63. return (0, d3_shape_1.line)()([
  64. [0, 0],
  65. [x, y],
  66. ]);
  67. }
  68. const P = [[x0 - x1, y0 - y1]].concat(controlPoints.length ? controlPoints : [0, 0]);
  69. const p0 = [coordCenter[0] - x1, coordCenter[1] - y1];
  70. const [p1, p2] = P;
  71. // If angle is smaller than 90, which will cause connector overlap with element.
  72. if (cos(p0, p1, p2) > 0) {
  73. const x2 = (() => {
  74. const { min, max } = shape.getLocalBounds();
  75. // A(x1,y2) perpendicular to B(x2,y2) => x1*x2 + y1*y2 = 0
  76. const vx = p1[0] + ((p1[1] - p0[1]) * (p1[1] - 0)) / (p1[0] - p0[0]);
  77. if (max[0] < p0[0])
  78. return Math.min(max[0], vx);
  79. return Math.max(min[0], vx);
  80. })();
  81. P.splice(1, 1, [x2, 0]);
  82. }
  83. return (0, d3_shape_1.line)()(P);
  84. }
  85. exports.Advance = (0, createElement_1.createElement)((g) => {
  86. const _a = g.attributes, {
  87. // Do not pass className
  88. class: className, transform, rotate, labelTransform, labelTransformOrigin, x, y, x0 = x, y0 = y, background, connector, startMarker, endMarker, coordCenter } = _a, rest = __rest(_a, ["class", "transform", "rotate", "labelTransform", "labelTransformOrigin", "x", "y", "x0", "y0", "background", "connector", "startMarker", "endMarker", "coordCenter"]);
  89. const _b = (0, helper_1.subObject)(rest, 'background'), { padding } = _b, backgroundStyle = __rest(_b, ["padding"]);
  90. const _c = (0, helper_1.subObject)(rest, 'connector'), { points = [] } = _c, connectorStyle = __rest(_c, ["points"]);
  91. const endPoints = [
  92. [+x0, +y0],
  93. [+x, +y],
  94. ];
  95. const shape1 = (0, selection_1.select)(g)
  96. .maybeAppend('text', 'text')
  97. .style('zIndex', 0)
  98. .call(utils_1.applyStyle, Object.assign({ textBaseline: 'middle', transform: labelTransform, transformOrigin: labelTransformOrigin }, rest))
  99. .node();
  100. const shape2 = (0, selection_1.select)(g)
  101. .maybeAppend('background', 'rect')
  102. .style('zIndex', -1)
  103. .call(utils_1.applyStyle, inferBackgroundBounds(shape1, padding))
  104. .call(utils_1.applyStyle, background ? backgroundStyle : {})
  105. .node();
  106. const connectorPath = inferConnectorPath(shape2, endPoints, points, coordCenter);
  107. const markerStart = startMarker &&
  108. new gui_1.Marker({
  109. id: 'startMarker',
  110. style: Object.assign({ x: 0, y: 0 }, (0, helper_1.subObject)(rest, 'startMarker')),
  111. });
  112. const markerEnd = endMarker &&
  113. new gui_1.Marker({
  114. id: 'endMarker',
  115. style: Object.assign({ x: 0, y: 0 }, (0, helper_1.subObject)(rest, 'endMarker')),
  116. });
  117. (0, selection_1.select)(g)
  118. .maybeAppend('connector', 'path')
  119. .style('zIndex', 0)
  120. .style('path', connectorPath)
  121. .style('markerStart', markerStart)
  122. .style('markerEnd', markerEnd)
  123. .call(utils_1.applyStyle, connector ? connectorStyle : {});
  124. });
  125. //# sourceMappingURL=advance.js.map