utils.js 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.getOrigin = exports.getTransform = exports.toOpacityKey = exports.getConnectStyle = exports.getShapeTheme = exports.getArcObject = exports.reorder = exports.computeGradient = exports.appendArc = exports.arrowPoints = exports.appendPolygon = exports.applyStyle = void 0;
  4. const scale_1 = require("@antv/scale");
  5. const util_1 = require("@antv/util");
  6. const d3_array_1 = require("d3-array");
  7. const array_1 = require("../utils/array");
  8. const coordinate_1 = require("../utils/coordinate");
  9. const vector_1 = require("../utils/vector");
  10. function applyStyle(selection, style) {
  11. for (const [key, value] of Object.entries(style)) {
  12. selection.style(key, value);
  13. }
  14. }
  15. exports.applyStyle = applyStyle;
  16. /**
  17. * Draw polygon path with points.
  18. * @param path
  19. * @param points
  20. */
  21. function appendPolygon(path, points) {
  22. points.forEach((p, idx) => idx === 0 ? path.moveTo(p[0], p[1]) : path.lineTo(p[0], p[1]));
  23. path.closePath();
  24. return path;
  25. }
  26. exports.appendPolygon = appendPolygon;
  27. /**
  28. * Draw arrow between `from` and `to`.
  29. * @param from
  30. * @param to
  31. * @returns
  32. */
  33. function arrowPoints(from, to, options) {
  34. const { arrowSize } = options;
  35. const size = typeof arrowSize === 'string'
  36. ? (+parseFloat(arrowSize) / 100) * (0, vector_1.dist)(from, to)
  37. : arrowSize;
  38. // TODO Use config from style.
  39. // Default arrow rotate is 30°.
  40. const arrowAngle = Math.PI / 6;
  41. const angle = Math.atan2(to[1] - from[1], to[0] - from[0]);
  42. const arrowAngle1 = Math.PI / 2 - angle - arrowAngle;
  43. const arrow1 = [
  44. to[0] - size * Math.sin(arrowAngle1),
  45. to[1] - size * Math.cos(arrowAngle1),
  46. ];
  47. const arrowAngle2 = angle - arrowAngle;
  48. const arrow2 = [
  49. to[0] - size * Math.cos(arrowAngle2),
  50. to[1] - size * Math.sin(arrowAngle2),
  51. ];
  52. return [arrow1, arrow2];
  53. }
  54. exports.arrowPoints = arrowPoints;
  55. /**
  56. * Draw arc by from -> to, with center and radius.
  57. * @param path
  58. * @param from
  59. * @param to
  60. * @param center
  61. * @param radius
  62. */
  63. function appendArc(path, from, to, center, radius) {
  64. const startAngle = (0, vector_1.angle)((0, vector_1.sub)(center, from)) + Math.PI;
  65. const endAngle = (0, vector_1.angle)((0, vector_1.sub)(center, to)) + Math.PI;
  66. path.arc(center[0], center[1], radius, startAngle, endAngle, endAngle - startAngle < 0);
  67. return path;
  68. }
  69. exports.appendArc = appendArc;
  70. /**
  71. * @todo Fix wrong key point.
  72. */
  73. function computeGradient(C, X, Y, from = 'y', mode = 'between') {
  74. const P = from === 'y' || from === true ? Y : X;
  75. const theta = from === 'y' || from === true ? 90 : 0;
  76. const I = (0, array_1.indexOf)(P);
  77. const [min, max] = (0, d3_array_1.extent)(I, (i) => P[i]);
  78. // This need to improve for non-uniform distributed colors.
  79. const p = new scale_1.Linear({
  80. domain: [min, max],
  81. range: [0, 100],
  82. });
  83. const percentage = (i) => p.map(P[i]);
  84. const gradientMode = {
  85. // Interpolate the colors for this segment.
  86. between: (i) => `${C[i]} ${percentage(i)}%`,
  87. // Use the color of the start point as the color for this segment.
  88. start: (i) => i === 0
  89. ? `${C[i]} ${percentage(i)}%`
  90. : `${C[i - 1]} ${percentage(i)}%, ${C[i]} ${percentage(i)}%`,
  91. // Use the color of the end point as the color for this segment.
  92. end: (i) => i === C.length - 1
  93. ? `${C[i]} ${percentage(i)}%`
  94. : `${C[i]} ${percentage(i)}%, ${C[i + 1]} ${percentage(i)}%`,
  95. };
  96. const gradient = I.sort((a, b) => percentage(a) - percentage(b))
  97. .map(gradientMode[mode] || gradientMode['between'])
  98. .join(',');
  99. return `linear-gradient(${theta}deg, ${gradient})`;
  100. }
  101. exports.computeGradient = computeGradient;
  102. function reorder(points) {
  103. const [p0, p1, p2, p3] = points;
  104. return [p3, p0, p1, p2];
  105. }
  106. exports.reorder = reorder;
  107. function getArcObject(coordinate, points, Y) {
  108. const [p0, p1, , p3] = (0, coordinate_1.isTranspose)(coordinate) ? reorder(points) : points;
  109. const [y, y1] = Y;
  110. const center = coordinate.getCenter();
  111. const a1 = (0, vector_1.angleWithQuadrant)((0, vector_1.sub)(p0, center));
  112. const a2 = (0, vector_1.angleWithQuadrant)((0, vector_1.sub)(p1, center));
  113. // There are two situations that a2 === a1:
  114. // 1. a1 - a2 = 0
  115. // 2. |a1 - a2| = Math.PI * 2
  116. // Distinguish them by y and y1:
  117. const a3 = a2 === a1 && y !== y1 ? a2 + Math.PI * 2 : a2;
  118. return {
  119. startAngle: a1,
  120. endAngle: a3 - a1 >= 0 ? a3 : Math.PI * 2 + a3,
  121. innerRadius: (0, vector_1.dist)(p3, center),
  122. outerRadius: (0, vector_1.dist)(p0, center),
  123. };
  124. }
  125. exports.getArcObject = getArcObject;
  126. /**
  127. * Get the mark.shape's style object.
  128. * @returns
  129. */
  130. function getShapeTheme(theme, mark, shape, defaultShape) {
  131. const { defaultColor } = theme;
  132. const markTheme = theme[mark] || {};
  133. const shapeTheme = markTheme[shape] || markTheme[defaultShape];
  134. return Object.assign({ defaultColor }, shapeTheme);
  135. }
  136. exports.getShapeTheme = getShapeTheme;
  137. /**
  138. * Pick connectStyle from style.
  139. * @param style
  140. */
  141. function getConnectStyle(style) {
  142. const PREFIX = 'connect';
  143. return Object.fromEntries(Object.entries(style)
  144. .filter(([key]) => key.startsWith(PREFIX))
  145. .map(([key, value]) => [
  146. (0, util_1.lowerFirst)(key.replace(PREFIX, '').trim()),
  147. value,
  148. ])
  149. .filter(([key]) => key !== undefined));
  150. }
  151. exports.getConnectStyle = getConnectStyle;
  152. function toOpacityKey(options) {
  153. const { colorAttribute, opacityAttribute = colorAttribute } = options;
  154. return `${opacityAttribute}Opacity`;
  155. }
  156. exports.toOpacityKey = toOpacityKey;
  157. function getTransform(coordinate, value) {
  158. if (!(0, coordinate_1.isPolar)(coordinate))
  159. return '';
  160. const center = coordinate.getCenter();
  161. const { transform: suffix } = value;
  162. return `translate(${center[0]}, ${center[1]}) ${suffix || ''}`;
  163. }
  164. exports.getTransform = getTransform;
  165. function getOrigin(points) {
  166. if (points.length === 1)
  167. return points[0];
  168. const [[x0, y0], [x2, y2]] = points;
  169. return [(x0 + x2) / 2, (y0 + y2) / 2];
  170. }
  171. exports.getOrigin = getOrigin;
  172. //# sourceMappingURL=utils.js.map