elementHighlight.js 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  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.ElementHighlight = exports.elementHighlight = void 0;
  15. const util_1 = require("@antv/util");
  16. const d3_array_1 = require("d3-array");
  17. const helper_1 = require("../utils/helper");
  18. const utils_1 = require("./utils");
  19. /**
  20. * highlight a group of elements.
  21. */
  22. function elementHighlight(root, { elements: elementsof, // given the root of chart returns elements to be manipulated
  23. datum, // given each element returns the datum of it
  24. groupKey = (d) => d, // group elements by specified key
  25. link = false, // draw link or not
  26. background = false, // draw background or not
  27. delay = 60, // delay to unhighlighted element
  28. scale, coordinate, emitter, state = {}, }) {
  29. var _a;
  30. const elements = elementsof(root);
  31. const elementSet = new Set(elements);
  32. const keyGroup = (0, d3_array_1.group)(elements, groupKey);
  33. const valueof = (0, utils_1.createValueof)(elements, datum);
  34. const [appendLink, removeLink] = (0, utils_1.renderLink)(Object.assign({ elements,
  35. valueof,
  36. link,
  37. coordinate }, (0, helper_1.subObject)(state.active, 'link')));
  38. const [appendBackground, removeBackground, isBackground] = (0, utils_1.renderBackground)(Object.assign({ scale,
  39. coordinate,
  40. background,
  41. valueof }, (0, helper_1.subObject)(state.active, 'background')));
  42. const elementStyle = (0, util_1.deepMix)(state, {
  43. active: Object.assign({}, (((_a = state.active) === null || _a === void 0 ? void 0 : _a.offset) && {
  44. //Apply translate to mock slice out.
  45. transform: (...params) => {
  46. const value = state.active.offset(...params);
  47. const [, i] = params;
  48. return (0, utils_1.offsetTransform)(elements[i], value, coordinate);
  49. },
  50. })),
  51. });
  52. const { setState, removeState, hasState } = (0, utils_1.useState)(elementStyle, valueof);
  53. let out; // Timer for delaying unhighlighted.
  54. const pointerover = (event) => {
  55. const { target: element, nativeEvent = true } = event;
  56. if (!elementSet.has(element))
  57. return;
  58. if (out)
  59. clearTimeout(out);
  60. const k = groupKey(element);
  61. const group = keyGroup.get(k);
  62. const groupSet = new Set(group);
  63. for (const e of elements) {
  64. if (groupSet.has(e)) {
  65. if (!hasState(e, 'active'))
  66. setState(e, 'active');
  67. }
  68. else {
  69. setState(e, 'inactive');
  70. removeLink(e);
  71. }
  72. if (e !== element)
  73. removeBackground(e);
  74. }
  75. appendBackground(element);
  76. appendLink(group);
  77. // Emit events.
  78. if (!nativeEvent)
  79. return;
  80. emitter.emit('element:highlight', {
  81. nativeEvent,
  82. data: {
  83. data: datum(element),
  84. group: group.map(datum),
  85. },
  86. });
  87. };
  88. const delayUnhighlighted = () => {
  89. if (out)
  90. clearTimeout(out);
  91. out = setTimeout(() => {
  92. unhighlighted();
  93. out = null;
  94. }, delay);
  95. };
  96. const unhighlighted = (nativeEvent = true) => {
  97. for (const e of elements) {
  98. removeState(e, 'active', 'inactive');
  99. removeBackground(e);
  100. removeLink(e);
  101. }
  102. if (nativeEvent) {
  103. emitter.emit('element:unhighlight', { nativeEvent });
  104. }
  105. };
  106. const pointerout = (event) => {
  107. const { target: element } = event;
  108. if (background && !isBackground(element))
  109. return;
  110. if (!background && !elementSet.has(element))
  111. return;
  112. if (delay > 0)
  113. delayUnhighlighted();
  114. else
  115. unhighlighted();
  116. };
  117. const pointerleave = () => {
  118. unhighlighted();
  119. };
  120. root.addEventListener('pointerover', pointerover);
  121. root.addEventListener('pointerout', pointerout);
  122. root.addEventListener('pointerleave', pointerleave);
  123. const onRest = (e) => {
  124. const { nativeEvent } = e;
  125. if (nativeEvent)
  126. return;
  127. unhighlighted(false);
  128. };
  129. const onHighlight = (e) => {
  130. const { nativeEvent } = e;
  131. if (nativeEvent)
  132. return;
  133. const { data } = e.data;
  134. const element = (0, utils_1.selectElementByData)(elements, data, datum);
  135. if (!element)
  136. return;
  137. pointerover({ target: element, nativeEvent: false });
  138. };
  139. emitter.on('element:highlight', onHighlight);
  140. emitter.on('element:unhighlight', onRest);
  141. return () => {
  142. root.removeEventListener('pointerover', pointerover);
  143. root.removeEventListener('pointerout', pointerout);
  144. root.removeEventListener('pointerleave', pointerleave);
  145. emitter.off('element:highlight', onHighlight);
  146. emitter.off('element:unhighlight', onRest);
  147. for (const e of elements) {
  148. removeBackground(e);
  149. removeLink(e);
  150. }
  151. };
  152. }
  153. exports.elementHighlight = elementHighlight;
  154. function ElementHighlight(_a) {
  155. var { delay, createGroup, background = false, link = false } = _a, rest = __rest(_a, ["delay", "createGroup", "background", "link"]);
  156. return (context, _, emitter) => {
  157. const { container, view, options } = context;
  158. const { scale, coordinate } = view;
  159. const plotArea = (0, utils_1.selectPlotArea)(container);
  160. return elementHighlight(plotArea, Object.assign({ elements: utils_1.selectG2Elements, datum: (0, utils_1.createDatumof)(view), groupKey: createGroup ? createGroup(view) : undefined, coordinate,
  161. scale, state: (0, utils_1.mergeState)(options, [
  162. ['active', background ? {} : { lineWidth: '1', stroke: '#000' }],
  163. 'inactive',
  164. ]), background,
  165. link,
  166. delay,
  167. emitter }, rest));
  168. };
  169. }
  170. exports.ElementHighlight = ElementHighlight;
  171. //# sourceMappingURL=elementHighlight.js.map