@antv/g2
Version:
the Grammar of Graphics in Javascript
180 lines • 7.52 kB
JavaScript
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ElementSelect = exports.elementSelect = void 0;
const d3_array_1 = require("d3-array");
const util_1 = require("@antv/util");
const helper_1 = require("../utils/helper");
const utils_1 = require("./utils");
/**
* Active a group of elements.
*/
function elementSelect(root, { elements: elementsof, // given the root of chart returns elements to be manipulated
datum, // given each element returns the datum of it
groupKey = (d) => d, // group elements by specified key
link = false, // draw link or not
single = false, // single select or not
coordinate, background = false, scale, emitter, state = {}, }) {
var _a;
const elements = elementsof(root);
const elementSet = new Set(elements);
const keyGroup = (0, d3_array_1.group)(elements, groupKey);
const valueof = (0, utils_1.createValueof)(elements, datum);
const [appendLink, removeLink] = (0, utils_1.renderLink)(Object.assign({ link,
elements,
valueof,
coordinate }, (0, helper_1.subObject)(state.selected, 'link')));
const [appendBackground, removeBackground] = (0, utils_1.renderBackground)(Object.assign({ document: root.ownerDocument, background,
coordinate,
scale,
valueof }, (0, helper_1.subObject)(state.selected, 'background')));
const elementStyle = (0, util_1.deepMix)(state, {
selected: Object.assign({}, (((_a = state.selected) === null || _a === void 0 ? void 0 : _a.offset) && {
//Apply translate to mock slice out.
transform: (...params) => {
const value = state.selected.offset(...params);
const [, i] = params;
return (0, utils_1.offsetTransform)(elements[i], value, coordinate);
},
})),
});
const { setState, removeState, hasState } = (0, utils_1.useState)(elementStyle, valueof);
const clear = (nativeEvent = true) => {
for (const e of elements) {
removeState(e, 'selected', 'unselected');
removeLink(e);
removeBackground(e);
}
if (nativeEvent)
emitter.emit('element:unselect', { nativeEvent: true });
return;
};
const singleSelect = (event, element, nativeEvent = true) => {
// Clear states if clicked selected element.
if (hasState(element, 'selected'))
clear();
else {
const k = groupKey(element);
const group = keyGroup.get(k);
const groupSet = new Set(group);
for (const e of elements) {
if (groupSet.has(e))
setState(e, 'selected');
else {
setState(e, 'unselected');
removeLink(e);
}
if (e !== element)
removeBackground(e);
}
appendLink(group);
appendBackground(element);
if (!nativeEvent)
return;
emitter.emit('element:select', Object.assign(Object.assign({}, event), { nativeEvent, data: {
data: [datum(element), ...group.map(datum)],
} }));
}
};
const multipleSelect = (event, element, nativeEvent = true) => {
const k = groupKey(element);
const group = keyGroup.get(k);
const groupSet = new Set(group);
if (!hasState(element, 'selected')) {
const hasSelectedGroup = group.some((e) => hasState(e, 'selected'));
for (const e of elements) {
if (groupSet.has(e))
setState(e, 'selected');
else if (!hasState(e, 'selected'))
setState(e, 'unselected');
}
// Append link for each group only once.
if (!hasSelectedGroup && link)
appendLink(group);
appendBackground(element);
}
else {
// If there is no selected elements after resetting this group,
// clear the states.
const hasSelected = elements.some((e) => !groupSet.has(e) && hasState(e, 'selected'));
if (!hasSelected)
return clear();
// If there are still some selected elements after resetting this group,
// only remove the link.
for (const e of group) {
setState(e, 'unselected');
removeLink(e);
removeBackground(e);
}
}
if (!nativeEvent)
return;
emitter.emit('element:select', Object.assign(Object.assign({}, event), { nativeEvent, data: {
data: elements.filter((e) => hasState(e, 'selected')).map(datum),
} }));
};
const click = (event) => {
const { target: element, nativeEvent = true } = event;
// Click non-element shape, reset.
// Such as the rest of content area(background).
if (!elementSet.has(element))
return clear();
if (single)
return singleSelect(event, element, nativeEvent);
return multipleSelect(event, element, nativeEvent);
};
root.addEventListener('click', click);
const onSelect = (e) => {
const { nativeEvent, data } = e;
if (nativeEvent)
return;
const selectedData = single ? data.data.slice(0, 1) : data.data;
for (const d of selectedData) {
const element = (0, utils_1.selectElementByData)(elements, d, datum);
click({ target: element, nativeEvent: false });
}
};
const onUnSelect = () => {
clear(false);
};
emitter.on('element:select', onSelect);
emitter.on('element:unselect', onUnSelect);
return () => {
for (const e of elements)
removeLink(e);
root.removeEventListener('click', click);
emitter.off('element:select', onSelect);
emitter.off('element:unselect', onUnSelect);
};
}
exports.elementSelect = elementSelect;
function ElementSelect(_a) {
var { createGroup, background = false, link = false } = _a, rest = __rest(_a, ["createGroup", "background", "link"]);
return (context, _, emitter) => {
const { container, view, options } = context;
const { coordinate, scale } = view;
const plotArea = (0, utils_1.selectPlotArea)(container);
return elementSelect(plotArea, Object.assign({ elements: utils_1.selectG2Elements, datum: (0, utils_1.createDatumof)(view), groupKey: createGroup ? createGroup(view) : undefined, coordinate,
scale, state: (0, utils_1.mergeState)(options, [
['selected', background ? {} : { lineWidth: '1', stroke: '#000' }],
'unselected',
]), background,
link,
emitter }, rest));
};
}
exports.ElementSelect = ElementSelect;
ElementSelect.props = {
reapplyWhenUpdate: true,
};
//# sourceMappingURL=elementSelect.js.map
;