brushHighlight.js 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570
  1. var __rest = (this && this.__rest) || function (s, e) {
  2. var t = {};
  3. for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
  4. t[p] = s[p];
  5. if (s != null && typeof Object.getOwnPropertySymbols === "function")
  6. for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
  7. if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
  8. t[p[i]] = s[p[i]];
  9. }
  10. return t;
  11. };
  12. import { Rect, Path } from '@antv/g';
  13. import { subObject, omitPrefixObject } from '../utils/helper';
  14. import { selectionOf, pixelsOf } from '../utils/scale';
  15. import { createElement } from '../utils/createElement';
  16. import { select } from '../utils/selection';
  17. import { selectG2Elements, selectPlotArea, createDatumof, useState, createValueof, setCursor, brushMousePosition, selectFacetG2Elements, mergeState, selectFacetViews, } from './utils';
  18. function intersect(bbox1, bbox2) {
  19. const [minX1, minY1, maxX1, maxY1] = bbox1;
  20. const [minX2, minY2, maxX2, maxY2] = bbox2;
  21. return !(minX2 > maxX1 || maxX2 < minX1 || minY2 > maxY1 || maxY2 < minY1);
  22. }
  23. function normalizeBounds(x, y, x1, y1, extent) {
  24. const [minX, minY, maxX, maxY] = extent;
  25. return [
  26. Math.max(minX, Math.min(x, x1)),
  27. Math.max(minY, Math.min(y, y1)),
  28. Math.min(maxX, Math.max(x, x1)),
  29. Math.min(maxY, Math.max(y, y1)),
  30. ];
  31. }
  32. function bboxOf(root) {
  33. const { width, height } = root.getBBox();
  34. return [0, 0, width, height];
  35. }
  36. function applyStyle(selection, style) {
  37. for (const [key, value] of Object.entries(style)) {
  38. selection.style(key, value);
  39. }
  40. }
  41. const ResizableMask = createElement((g) => {
  42. const _a = g.attributes, { x, y, width, height, class: className, renders = {}, handleSize: size = 10, document } = _a, style = __rest(_a, ["x", "y", "width", "height", "class", "renders", "handleSize", "document"]);
  43. if (!document ||
  44. width === undefined ||
  45. height === undefined ||
  46. x === undefined ||
  47. y === undefined)
  48. return;
  49. const half = size / 2;
  50. const renderRect = (g, options, document) => {
  51. if (!g.handle) {
  52. g.handle = document.createElement('rect');
  53. g.append(g.handle);
  54. }
  55. const { handle } = g;
  56. handle.attr(options);
  57. return handle;
  58. };
  59. const _b = subObject(omitPrefixObject(style, 'handleNW', 'handleNE'), 'handleN'), { render: handleNRender = renderRect } = _b, handleNStyle = __rest(_b, ["render"]);
  60. const _c = subObject(style, 'handleE'), { render: handleERender = renderRect } = _c, handleEStyle = __rest(_c, ["render"]);
  61. const _d = subObject(omitPrefixObject(style, 'handleSE', 'handleSW'), 'handleS'), { render: handleSRender = renderRect } = _d, handleSStyle = __rest(_d, ["render"]);
  62. const _e = subObject(style, 'handleW'), { render: handleWRender = renderRect } = _e, handleWStyle = __rest(_e, ["render"]);
  63. const _f = subObject(style, 'handleNW'), { render: handleNWRender = renderRect } = _f, handleNWStyle = __rest(_f, ["render"]);
  64. const _g = subObject(style, 'handleNE'), { render: handleNERender = renderRect } = _g, handleNEStyle = __rest(_g, ["render"]);
  65. const _h = subObject(style, 'handleSE'), { render: handleSERender = renderRect } = _h, handleSEStyle = __rest(_h, ["render"]);
  66. const _j = subObject(style, 'handleSW'), { render: handleSWRender = renderRect } = _j, handleSWStyle = __rest(_j, ["render"]);
  67. const renderHandle = (g, renderNode) => {
  68. const { id } = g;
  69. const _a = g.attributes, { x, y } = _a, style = __rest(_a, ["x", "y"]);
  70. const handle = renderNode(g, Object.assign({ x: 0, y: 0 }, style), document);
  71. handle.id = id;
  72. handle.style.draggable = true;
  73. };
  74. const appendHandle = (handleRender) => {
  75. return () => {
  76. const Node = createElement((g) => renderHandle(g, handleRender));
  77. return new Node({});
  78. };
  79. };
  80. const container = select(g)
  81. .attr('className', className)
  82. .style('x', x)
  83. .style('y', y)
  84. .style('draggable', true);
  85. container
  86. .maybeAppend('selection', 'rect')
  87. .style('draggable', true)
  88. .style('fill', 'transparent')
  89. .call(applyStyle, Object.assign({ width, height }, omitPrefixObject(style, 'handle')));
  90. container
  91. .maybeAppend('handle-n', appendHandle(handleNRender))
  92. .style('x', half)
  93. .style('y', -half)
  94. .style('width', width - size)
  95. .style('height', size)
  96. .style('fill', 'transparent')
  97. .call(applyStyle, handleNStyle);
  98. container
  99. .maybeAppend('handle-e', appendHandle(handleERender))
  100. .style('x', width - half)
  101. .style('y', half)
  102. .style('width', size)
  103. .style('height', height - size)
  104. .style('fill', 'transparent')
  105. .call(applyStyle, handleEStyle);
  106. container
  107. .maybeAppend('handle-s', appendHandle(handleSRender))
  108. .style('x', half)
  109. .style('y', height - half)
  110. .style('width', width - size)
  111. .style('height', size)
  112. .style('fill', 'transparent')
  113. .call(applyStyle, handleSStyle);
  114. container
  115. .maybeAppend('handle-w', appendHandle(handleWRender))
  116. .style('x', -half)
  117. .style('y', half)
  118. .style('width', size)
  119. .style('height', height - size)
  120. .style('fill', 'transparent')
  121. .call(applyStyle, handleWStyle);
  122. container
  123. .maybeAppend('handle-nw', appendHandle(handleNWRender))
  124. .style('x', -half)
  125. .style('y', -half)
  126. .style('width', size)
  127. .style('height', size)
  128. .style('fill', 'transparent')
  129. .call(applyStyle, handleNWStyle);
  130. container
  131. .maybeAppend('handle-ne', appendHandle(handleNERender))
  132. .style('x', width - half)
  133. .style('y', -half)
  134. .style('width', size)
  135. .style('height', size)
  136. .style('fill', 'transparent')
  137. .call(applyStyle, handleNEStyle);
  138. container
  139. .maybeAppend('handle-se', appendHandle(handleSERender))
  140. .style('x', width - half)
  141. .style('y', height - half)
  142. .style('width', size)
  143. .style('height', size)
  144. .style('fill', 'transparent')
  145. .call(applyStyle, handleSEStyle);
  146. container
  147. .maybeAppend('handle-sw', appendHandle(handleSWRender))
  148. .style('x', -half)
  149. .style('y', height - half)
  150. .style('width', size)
  151. .style('height', size)
  152. .style('fill', 'transparent')
  153. .call(applyStyle, handleSWStyle);
  154. });
  155. export function brush(root, _a) {
  156. var { brushed = () => { }, brushended = () => { }, brushcreated = () => { }, extent = bboxOf(root), brushRegion = (x, y, x1, y1, extent) => [x, y, x1, y1], reverse = false, fill = '#777', fillOpacity = '0.3', stroke = '#fff', selectedHandles = [
  157. 'handle-n',
  158. 'handle-e',
  159. 'handle-s',
  160. 'handle-w',
  161. 'handle-nw',
  162. 'handle-ne',
  163. 'handle-se',
  164. 'handle-sw',
  165. ] } = _a, style = __rest(_a, ["brushed", "brushended", "brushcreated", "extent", "brushRegion", "reverse", "fill", "fillOpacity", "stroke", "selectedHandles"]);
  166. let start = null; // Start point of mask.
  167. let end = null; // End point of mask.
  168. let moveStart = null; // Start point of moving mask.
  169. let mask = null; // Mask instance.
  170. let background = null;
  171. let creating = false;
  172. const [originX, originY, width, height] = extent;
  173. setCursor(root, 'crosshair');
  174. root.style.draggable = true; // Make it response to drag event.
  175. // Remove old mask and init new mask.
  176. const initMask = (x, y) => {
  177. if (mask)
  178. mask.remove();
  179. if (background)
  180. background.remove();
  181. start = [x, y];
  182. if (reverse)
  183. return initReverseMask();
  184. initNormalMask();
  185. };
  186. const initReverseMask = () => {
  187. background = new Path({
  188. style: Object.assign(Object.assign({}, style), { fill,
  189. fillOpacity,
  190. stroke, pointerEvents: 'none' }),
  191. });
  192. mask = new ResizableMask({
  193. // @ts-ignore
  194. style: {
  195. x: 0,
  196. y: 0,
  197. width: 0,
  198. height: 0,
  199. draggable: true,
  200. document: root.ownerDocument,
  201. },
  202. className: 'mask',
  203. });
  204. root.appendChild(background);
  205. root.appendChild(mask);
  206. };
  207. const initNormalMask = () => {
  208. mask = new ResizableMask({
  209. // @ts-ignore
  210. style: Object.assign(Object.assign({ document: root.ownerDocument, x: 0, y: 0 }, style), { fill,
  211. fillOpacity,
  212. stroke, draggable: true }),
  213. className: 'mask',
  214. });
  215. root.appendChild(mask);
  216. };
  217. // Remove mask and reset states.
  218. const removeMask = (emit = true) => {
  219. if (mask)
  220. mask.remove();
  221. if (background)
  222. background.remove();
  223. start = null;
  224. end = null;
  225. moveStart = null;
  226. creating = false;
  227. mask = null;
  228. background = null;
  229. brushended(emit);
  230. };
  231. // Update mask and invoke brushended callback.
  232. const updateMask = (start, end, emit = true) => {
  233. const [x, y, x1, y1] = normalizeBounds(start[0], start[1], end[0], end[1], extent);
  234. const [fx, fy, fx1, fy1] = brushRegion(x, y, x1, y1, extent);
  235. if (reverse)
  236. updateReverseMask(fx, fy, fx1, fy1);
  237. else
  238. updateNormalMask(fx, fy, fx1, fy1);
  239. brushed(fx, fy, fx1, fy1, emit);
  240. return [fx, fy, fx1, fy1];
  241. };
  242. const updateNormalMask = (x, y, x1, y1) => {
  243. mask.style.x = x;
  244. mask.style.y = y;
  245. mask.style.width = x1 - x;
  246. mask.style.height = y1 - y;
  247. };
  248. const updateReverseMask = (x, y, x1, y1) => {
  249. background.style.d = `
  250. M${originX},${originY}L${width},${originY}L${width},${height}L${originX},${height}Z
  251. M${x},${y}L${x},${y1}L${x1},${y1}L${x1},${y}Z
  252. `;
  253. mask.style.x = x;
  254. mask.style.y = y;
  255. mask.style.width = x1 - x;
  256. mask.style.height = y1 - y;
  257. };
  258. // Move and update mask.
  259. const moveMask = (current) => {
  260. const clip = (dt, start, end, min, max) => {
  261. if (dt + start < min)
  262. return min - start;
  263. if (dt + end > max)
  264. return max - end;
  265. return dt;
  266. };
  267. const dx = current[0] - moveStart[0];
  268. const dy = current[1] - moveStart[1];
  269. const dx1 = clip(dx, start[0], end[0], originX, width);
  270. const dy1 = clip(dy, start[1], end[1], originY, height);
  271. const currentStart = [start[0] + dx1, start[1] + dy1];
  272. const currentEnd = [end[0] + dx1, end[1] + dy1];
  273. updateMask(currentStart, currentEnd);
  274. };
  275. const handles = {
  276. 'handle-n': { vector: [0, 1, 0, 0], cursor: 'ns-resize' },
  277. 'handle-e': { vector: [0, 0, 1, 0], cursor: 'ew-resize' },
  278. 'handle-s': { vector: [0, 0, 0, 1], cursor: 'ns-resize' },
  279. 'handle-w': { vector: [1, 0, 0, 0], cursor: 'ew-resize' },
  280. 'handle-nw': { vector: [1, 1, 0, 0], cursor: 'nwse-resize' },
  281. 'handle-ne': { vector: [0, 1, 1, 0], cursor: 'nesw-resize' },
  282. 'handle-se': { vector: [0, 0, 1, 1], cursor: 'nwse-resize' },
  283. 'handle-sw': { vector: [1, 0, 0, 1], cursor: 'nesw-resize' },
  284. };
  285. const isMask = (target) => {
  286. return isSelection(target) || isHandle(target);
  287. };
  288. const isHandle = (target) => {
  289. const { id } = target;
  290. if (selectedHandles.indexOf(id) === -1)
  291. return false;
  292. return new Set(Object.keys(handles)).has(id);
  293. };
  294. const isSelection = (target) => {
  295. return target === mask.getElementById('selection');
  296. };
  297. // If target is plot area, create mask.
  298. // If target is mask, about to update position.
  299. const dragstart = (event) => {
  300. const { target } = event;
  301. const [offsetX, offsetY] = brushMousePosition(root, event);
  302. if (!mask || !isMask(target)) {
  303. initMask(offsetX, offsetY);
  304. creating = true;
  305. return;
  306. }
  307. if (isMask(target)) {
  308. moveStart = [offsetX, offsetY];
  309. }
  310. };
  311. const drag = (event) => {
  312. const { target } = event;
  313. const mouse = brushMousePosition(root, event);
  314. if (!start)
  315. return;
  316. // If target is plot area, resize mask.
  317. if (!moveStart)
  318. return updateMask(start, mouse);
  319. // If target is selection area, move mask.
  320. if (isSelection(target))
  321. return moveMask(mouse);
  322. // If target is handle area, resize mask.
  323. const [dx, dy] = [mouse[0] - moveStart[0], mouse[1] - moveStart[1]];
  324. const { id } = target;
  325. if (handles[id]) {
  326. const [sx, sy, ex, ey] = handles[id].vector;
  327. return updateMask([start[0] + dx * sx, start[1] + dy * sy], [end[0] + dx * ex, end[1] + dy * ey]);
  328. }
  329. };
  330. // If target is plot area, finish creating.
  331. // If target is mask, finish moving mask.
  332. const dragend = (event) => {
  333. if (moveStart) {
  334. moveStart = null;
  335. // Update start and end;
  336. const { x, y, width, height } = mask.style;
  337. start = [x, y];
  338. end = [x + width, y + height];
  339. return;
  340. }
  341. end = brushMousePosition(root, event);
  342. const [fx, fy, fx1, fy1] = updateMask(start, end);
  343. creating = false;
  344. brushcreated(fx, fy, fx1, fy1, event);
  345. };
  346. // Hide mask.
  347. const click = (event) => {
  348. const { target } = event;
  349. if (mask && !isMask(target))
  350. removeMask();
  351. };
  352. // Update cursor depends on hovered element.
  353. const pointermove = (event) => {
  354. const { target } = event;
  355. if (!mask || !isMask(target) || creating)
  356. setCursor(root, 'crosshair');
  357. else if (isSelection(target))
  358. setCursor(root, 'move');
  359. else if (isHandle(target))
  360. setCursor(root, handles[target.id].cursor);
  361. };
  362. const pointerleave = () => {
  363. setCursor(root, 'default');
  364. };
  365. root.addEventListener('dragstart', dragstart);
  366. root.addEventListener('drag', drag);
  367. root.addEventListener('dragend', dragend);
  368. root.addEventListener('click', click);
  369. root.addEventListener('pointermove', pointermove);
  370. root.addEventListener('pointerleave', pointerleave);
  371. return {
  372. mask,
  373. move(x, y, x1, y1, emit = true) {
  374. if (!mask)
  375. initMask(x, y);
  376. start = [x, y];
  377. end = [x1, y1];
  378. updateMask([x, y], [x1, y1], emit);
  379. },
  380. remove() {
  381. if (mask)
  382. removeMask(false);
  383. },
  384. destroy() {
  385. // Do not emit brush:end event.
  386. if (mask)
  387. removeMask(false);
  388. setCursor(root, 'default');
  389. root.removeEventListener('dragstart', dragstart);
  390. root.removeEventListener('drag', drag);
  391. root.removeEventListener('dragend', dragend);
  392. root.removeEventListener('click', click);
  393. root.removeEventListener('pointermove', pointermove);
  394. root.removeEventListener('pointerleave', pointerleave);
  395. },
  396. };
  397. }
  398. function selectSiblingViews(target, viewInstances, brushKey) {
  399. return viewInstances.filter((d) => {
  400. if (d === target)
  401. return false;
  402. const { interaction = {} } = d.options;
  403. return Object.values(interaction).find((d) => d.brushKey === brushKey);
  404. });
  405. }
  406. function selectSiblingContainers(target, viewInstances, brushKey) {
  407. return selectSiblingViews(target, viewInstances, brushKey).map((d) => selectPlotArea(d.container));
  408. }
  409. function selectSiblingOptions(target, viewInstances, brushKey) {
  410. return selectSiblingViews(target, viewInstances, brushKey).map((d) => d.options);
  411. }
  412. /**
  413. * @todo Brush over view for series view.
  414. * @todo Test perf.
  415. */
  416. export function brushHighlight(root, _a) {
  417. var { elements: elementof, selectedHandles, siblings: siblingsof = (root) => [], datum, brushRegion, extent: optionalExtent, reverse, scale, coordinate, series = false, key = (d) => d, bboxOf = (root) => {
  418. const { x, y, width, height } = root.style;
  419. return { x, y, width, height };
  420. }, state = {}, emitter } = _a, rest = __rest(_a, ["elements", "selectedHandles", "siblings", "datum", "brushRegion", "extent", "reverse", "scale", "coordinate", "series", "key", "bboxOf", "state", "emitter"]);
  421. const elements = elementof(root);
  422. const siblings = siblingsof(root);
  423. const siblingElements = siblings.flatMap(elementof);
  424. const valueof = createValueof(elements, datum);
  425. const brushStyle = subObject(rest, 'mask');
  426. const { setState, removeState } = useState(state, valueof);
  427. const clonedElement = new Map();
  428. const { width: rootWidth, height: rootHeight, x: ordinalX = 0, y: ordinalY = 0, } = bboxOf(root);
  429. const extent = optionalExtent
  430. ? optionalExtent
  431. : [0, 0, rootWidth, rootHeight];
  432. const brushended = () => {
  433. for (const element of [...elements, ...siblingElements]) {
  434. removeState(element, 'active', 'inactive');
  435. }
  436. };
  437. const brushed = (x, y, x1, y1) => {
  438. var _a;
  439. // Hide brush for the sibling view.
  440. for (const sibling of siblings)
  441. (_a = sibling.brush) === null || _a === void 0 ? void 0 : _a.remove();
  442. // Store the key of the active element.
  443. const keys = new Set();
  444. // Highlight and store selected elements.
  445. for (const element of elements) {
  446. const { min, max } = element.getLocalBounds();
  447. const [ex, ey] = min;
  448. const [ex1, ey1] = max;
  449. if (!intersect([ex, ey, ex1, ey1], [x, y, x1, y1])) {
  450. setState(element, 'inactive');
  451. }
  452. else {
  453. setState(element, 'active');
  454. keys.add(key(element));
  455. }
  456. }
  457. // Highlight elements with same key in sibling view.
  458. for (const element of siblingElements) {
  459. if (keys.has(key(element)))
  460. setState(element, 'active');
  461. else
  462. setState(element, 'inactive');
  463. }
  464. };
  465. const seriesBrushend = () => {
  466. for (const element of elements)
  467. removeState(element, 'inactive');
  468. for (const cloned of clonedElement.values())
  469. cloned.remove();
  470. clonedElement.clear();
  471. };
  472. const seriesBrushed = (x, y, x1, y1) => {
  473. const clone = (element) => {
  474. const cloned = element.cloneNode();
  475. cloned.__data__ = element.__data__;
  476. element.parentNode.appendChild(cloned);
  477. clonedElement.set(element, cloned);
  478. return cloned;
  479. };
  480. for (const element of elements) {
  481. const cloned = clonedElement.get(element) || clone(element);
  482. cloned.style.clipPath = new Rect({
  483. style: {
  484. x: x + ordinalX,
  485. y: y + ordinalY,
  486. width: x1 - x,
  487. height: y1 - y,
  488. },
  489. });
  490. setState(element, 'inactive');
  491. setState(cloned, 'active');
  492. }
  493. };
  494. const brushHandler = brush(root, Object.assign(Object.assign({}, brushStyle), { extent,
  495. brushRegion,
  496. reverse,
  497. selectedHandles, brushended: (emit) => {
  498. const handler = series ? seriesBrushend : brushended;
  499. if (emit) {
  500. emitter.emit('brush:remove', { nativeEvent: true });
  501. }
  502. handler();
  503. }, brushed: (x, y, x1, y1, emit) => {
  504. const selection = selectionOf(x, y, x1, y1, scale, coordinate);
  505. if (emit) {
  506. emitter.emit('brush:highlight', {
  507. nativeEvent: true,
  508. data: { selection },
  509. });
  510. }
  511. const handler = series ? seriesBrushed : brushed;
  512. handler(x, y, x1, y1);
  513. } }));
  514. // Move brush and highlight data.
  515. const onHighlight = ({ nativeEvent, data }) => {
  516. if (nativeEvent)
  517. return;
  518. const { selection } = data;
  519. const [x, y, x1, y1] = pixelsOf(selection, scale, coordinate);
  520. brushHandler.move(x, y, x1, y1, false);
  521. };
  522. emitter.on('brush:highlight', onHighlight);
  523. // Remove brush and reset data.
  524. const onRemove = () => brushHandler.remove();
  525. emitter.on('brush:remove', onRemove);
  526. // Remove event handlers.
  527. const preBrushDestroy = brushHandler.destroy.bind(brushHandler);
  528. brushHandler.destroy = () => {
  529. emitter.off('brush:highlight', onHighlight);
  530. emitter.off('brush:remove', onRemove);
  531. preBrushDestroy();
  532. };
  533. return brushHandler;
  534. }
  535. export function BrushHighlight(_a) {
  536. var { facet, brushKey } = _a, rest = __rest(_a, ["facet", "brushKey"]);
  537. return (target, viewInstances, emitter) => {
  538. const { container, view, options } = target;
  539. const plotArea = selectPlotArea(container);
  540. const defaultOptions = {
  541. maskFill: '#777',
  542. maskFillOpacity: '0.3',
  543. maskStroke: '#fff',
  544. reverse: false,
  545. };
  546. const defaultStates = ['active', ['inactive', { opacity: 0.5 }]];
  547. const { scale, coordinate } = view;
  548. if (facet) {
  549. const bbox = plotArea.getBounds();
  550. const x = bbox.min[0];
  551. const y = bbox.min[1];
  552. const x1 = bbox.max[0];
  553. const y1 = bbox.max[1];
  554. return brushHighlight(plotArea.parentNode.parentNode, Object.assign(Object.assign({ elements: () => selectFacetG2Elements(target, viewInstances), datum: createDatumof(selectFacetViews(target, viewInstances).map((d) => d.view)), brushRegion: (x, y, x1, y1) => [x, y, x1, y1], extent: [x, y, x1, y1], state: mergeState(selectFacetViews(target, viewInstances).map((d) => d.options), defaultStates), emitter,
  555. scale,
  556. coordinate, selectedHandles: undefined }, defaultOptions), rest));
  557. }
  558. const brush = brushHighlight(plotArea, Object.assign(Object.assign({ elements: selectG2Elements, key: (element) => element.__data__.key, siblings: () => selectSiblingContainers(target, viewInstances, brushKey), datum: createDatumof([
  559. view,
  560. ...selectSiblingViews(target, viewInstances, brushKey).map((d) => d.view),
  561. ]), brushRegion: (x, y, x1, y1) => [x, y, x1, y1], extent: undefined, state: mergeState([options, ...selectSiblingOptions(target, viewInstances, brushKey)], defaultStates), emitter,
  562. scale,
  563. coordinate, selectedHandles: undefined }, defaultOptions), rest));
  564. // Bind brush to the view it belongs to.
  565. //@ts-ignore
  566. plotArea.brush = brush;
  567. return () => brush.destroy();
  568. };
  569. }
  570. //# sourceMappingURL=brushHighlight.js.map