@visactor/vchart
Version:
charts lib based @visactor/VGrammar
159 lines (152 loc) • 7.35 kB
JavaScript
import { isContinuous } from "@visactor/vscale";
import { isArray, isObject, isValid, isBoolean } from "@visactor/vutils";
import { PREFIX } from "../../constant/base";
import { isMultiDatumMark } from "../../mark/utils/common";
import { StateManager } from "../signal/state-manager";
import { stateInDefaultEnum } from "./util";
export class MarkStateManager extends StateManager {
getStateInfoList() {
return this._stateInfoList;
}
constructor(option, mark) {
super(option), this._stateInfoList = [], this._mark = mark;
}
_getDefaultStateMap() {
return {
markUpdateRank: 1
};
}
getStateInfo(stateValue) {
return this._stateInfoList.find((s => s.stateValue === stateValue));
}
addStateInfo(stateInfo) {
if (this.getStateInfo(stateInfo.stateValue)) return;
stateInfo.level = stateInfo.level || 0;
let needPush = !0;
for (let i = 0; i < this._stateInfoList.length; i++) {
const level = this._stateInfoList[i].level;
if (level && level > stateInfo.level) {
this._stateInfoList.splice(i, 0, stateInfo), needPush = !1;
break;
}
}
needPush && this._stateInfoList.push(stateInfo);
}
_clearStateBeforeSet(state) {
state.datums = null, state.items = null, state.fields = null, state.filter = null;
}
changeStateInfo(stateInfo) {
const s = this.getStateInfo(stateInfo.stateValue);
if (s) {
if (void 0 !== stateInfo.datums && (this._clearStateBeforeSet(s), s.datums = stateInfo.datums,
s.datumKeys = stateInfo.datumKeys), void 0 !== stateInfo.items && (this._clearStateBeforeSet(s),
s.items = stateInfo.items), void 0 !== stateInfo.fields) if (this._clearStateBeforeSet(s),
null === stateInfo.fields) s.fields = stateInfo.fields; else {
s.fields = s.fields || {};
for (const key in stateInfo.fields) {
const new_f = stateInfo.fields[key];
s.fields[key] = s.fields[key] || {};
const old_f = s.fields[key];
isValid(new_f.domain) && (old_f.domain = new_f.domain), isValid(new_f.type) && (old_f.type = new_f.type);
}
}
stateInfo.filter && (this._clearStateBeforeSet(s), s.filter = stateInfo.filter);
} else this.addStateInfo(stateInfo);
}
clearStateInfo(stateValues) {
stateValues.forEach((stateValue => {
this.getStateInfo(stateValue) && this.changeStateInfo({
stateValue: stateValue,
datumKeys: null,
datums: null,
fields: null,
items: null,
filter: null,
cache: {}
});
}));
}
checkOneState(renderNode, datum, state, isMultiMark) {
var _a;
isMultiMark = isBoolean(isMultiDatumMark) ? isMultiMark : !renderNode.mark || isMultiDatumMark(renderNode.mark.markType);
let inState = !1, stateChecked = !1;
if (isValid(state.datums) && state.datums.length > 0) inState = this.checkDatumState(state, datum, isMultiMark),
stateChecked = !0; else if (state.items) inState = null !== (_a = this.checkItemsState(state, renderNode)) && void 0 !== _a && _a,
stateChecked = !0; else if (state.fields) inState = this.checkFieldsState(state, datum, renderNode, isMultiMark),
stateChecked = !0; else if (!inState && state.filter) {
const options = {
mark: this._mark,
renderNode: renderNode,
type: renderNode.mark.markType
};
inState = state.filter(datum, options), stateChecked = !0;
}
return stateChecked ? inState ? "in" : "out" : "skip";
}
checkState(renderNode, datum) {
const result = renderNode.getStates().filter((s => stateInDefaultEnum(s))).map((s => [ s, 10 ])), isMultiMark = !renderNode.mark || isMultiDatumMark(renderNode.mark.markType);
for (let i = 0; i < this._stateInfoList.length; i++) {
const state = this._stateInfoList[i], inOut = this.checkOneState(renderNode, datum, state, isMultiMark);
"skip" !== inOut && ("in" === inOut && result.push([ state.stateValue, state.level ]));
}
return result.map((res => res[0]));
}
checkDatumState(state, datum, isMultiMark) {
let inState = !1;
const datum_v = isMultiMark ? datum[0] : datum;
if (isArray(state.datums)) {
const keys = state.datumKeys || Object.keys(state.datums[0]).filter((k => !k.startsWith(PREFIX)));
inState = state.datums.some((d => isMultiMark && isArray(null == d ? void 0 : d.items) ? keys.every((k => {
var _a, _b;
return (null === (_b = null === (_a = null == d ? void 0 : d.items) || void 0 === _a ? void 0 : _a[0]) || void 0 === _b ? void 0 : _b[k]) === (null == datum_v ? void 0 : datum_v[k]);
})) : keys.every((k => (null == d ? void 0 : d[k]) === (null == datum_v ? void 0 : datum_v[k])))));
} else if (isObject(state.datums)) {
inState = (state.datumKeys || Object.keys(state.datums).filter((k => !k.startsWith(PREFIX)))).every((k => {
var _a, _b;
return isMultiMark ? (null === (_a = state.datums.items) || void 0 === _a ? void 0 : _a[0][k]) === datum_v[k] : (null === (_b = state.datums) || void 0 === _b ? void 0 : _b[k]) === datum_v[k];
}));
} else inState = datum === state.datums;
return inState;
}
checkItemsState(state, item) {
var _a;
return null === (_a = state.items) || void 0 === _a ? void 0 : _a.includes(item);
}
checkFieldsState(state, datum, item, isMultiMark) {
var _a;
let inState = !0;
for (const key in state.fields) {
const field = state.fields[key], type = field.type, domain = field.domain, datum_v = isMultiMark ? null === (_a = datum[0]) || void 0 === _a ? void 0 : _a[key] : datum[key];
if (isContinuous(type) && domain.length > 1) {
if (this.checkLinearFieldState(domain, key, datum, item, isMultiMark)) {
inState = !1;
break;
}
inState = !0;
} else {
if (!domain.some((d => d === datum_v))) {
inState = !1;
break;
}
inState = !0;
}
}
return inState;
}
checkLinearFieldState(domain, key, datum, item, isMultiMark) {
var _a;
const datum_v = isMultiMark ? null === (_a = datum[0]) || void 0 === _a ? void 0 : _a[key] : datum[key];
return datum_v < domain[0] || datum_v > domain[domain.length - 1];
}
updateLayoutState(noRender) {
return this._stateMap.markUpdateRank++, this.updateState({
markUpdateRank: this._stateMap.markUpdateRank
}, noRender);
}
compileState(product, stateSort) {
product.state({
callback: (datum, element) => this.checkState(element, datum)
}, stateSort);
}
}
//# sourceMappingURL=mark-state-manager.js.map