UNPKG

@visactor/vgrammar-core

Version:

VGrammar is a visual grammar library

202 lines (198 loc) 13.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: !0 }), exports.GlyphElement = void 0; const vutils_1 = require("@visactor/vutils"), transform_1 = require("./attributes/transform"), constants_1 = require("./constants"), enums_1 = require("./enums"), element_1 = require("./element"), encode_1 = require("./mark/encode"); class GlyphElement extends element_1.Element { constructor(mark) { super(mark), this.getStateAttrs = (stateName, nextStates) => { var _a, _b, _c, _d; const isRuntimeState = !(0, vutils_1.isNil)(null === (_a = this.runtimeStatesEncoder) || void 0 === _a ? void 0 : _a[stateName]), encoder = isRuntimeState ? Object.assign(Object.assign({}, null === (_b = this.mark.getSpec().encode) || void 0 === _b ? void 0 : _b[stateName]), this.runtimeStatesEncoder[stateName]) : null === (_c = this.mark.getSpec().encode) || void 0 === _c ? void 0 : _c[stateName], glyphStateAttributes = {}; if (!encoder) return glyphStateAttributes; if ((0, vutils_1.isFunction)(encoder)) return glyphStateAttributes.attributes = encoder(this.getDatum(), this, stateName, nextStates), glyphStateAttributes; if (!isRuntimeState && (null === (_d = this.graphicItem.glyphStates) || void 0 === _d ? void 0 : _d[stateName])) return this.graphicItem.glyphStates[stateName]; if (encoder) { const item = this.items[0], targetItems = [ Object.assign({}, item, { nextAttrs: {} }) ]; return (0, encode_1.invokeEncoderToItems)(this, targetItems, encoder, this.mark.parameters()), this.coordinateTransformEncode(targetItems), glyphStateAttributes.attributes = targetItems[0].nextAttrs, this.graphicItem.glyphStates ? this.graphicItem.glyphStates[stateName] || (this.graphicItem.glyphStates[stateName] = glyphStateAttributes) : this.graphicItem.glyphStates = { [stateName]: glyphStateAttributes }, glyphStateAttributes; } return glyphStateAttributes; }, this.glyphMeta = this.mark.getGlyphMeta(); } getGlyphGraphicItems() { return this.glyphGraphicItems; } initGraphicItem(attributes = {}) { if (this.graphicItem) return; this.graphicItem = this.mark.addGraphicItem(attributes, this.groupKey), this.graphicItem[constants_1.BridgeElementKey] = this, this.graphicItem.onBeforeAttributeUpdate = this._onGlyphAttributeUpdate(!1); const glyphMarks = this.glyphMeta.getMarks(); this.glyphGraphicItems = {}, this.graphicItem.getSubGraphic().forEach((graphic => { const markType = glyphMarks[graphic.name]; this.glyphGraphicItems[graphic.name] = graphic, graphic.onBeforeAttributeUpdate = attributes => { if (!this.mark) return attributes; return (0, transform_1.transformAttributes)(markType, attributes, this, graphic.name); }; })), this.clearGraphicAttributes(); } useStates(states, hasAnimation) { if (!this.graphicItem) return !1; this.mark.emit(enums_1.HOOK_EVENT.BEFORE_ELEMENT_STATE, { states: states }, this), this.states = states.slice(); const stateAnimationEnable = (0, vutils_1.isBoolean)(hasAnimation) ? hasAnimation : this.hasStateAnimation(); return this.graphicItem.glyphStateProxy = this.getStateAttrs, this.graphicItem.useStates(this.states, stateAnimationEnable), this.mark.emit(enums_1.HOOK_EVENT.AFTER_ELEMENT_STATE, { states: states }, this), !0; } encodeGraphic() { this.coordinateTransformEncode(this.items); const graphicAttributes = this.transformElementItems(this.items, this.mark.markType), isGraphicInit = !this.graphicItem; this.graphicItem ? (this.graphicItem.clearStates(), this.graphicItem.states = {}, this.graphicItem.stateProxy = null) : this.initGraphicItem(), this.diffState === enums_1.DiffState.enter || isGraphicInit ? (this.graphicItem.onBeforeAttributeUpdate = this._onGlyphAttributeUpdate(!0), this.applyGraphicAttributes(graphicAttributes), this.graphicItem.onBeforeAttributeUpdate = this._onGlyphAttributeUpdate(!1)) : this.applyGraphicAttributes(graphicAttributes), this.diffState !== enums_1.DiffState.enter && this.diffState !== enums_1.DiffState.update || !this.states.length || (Object.values(this.glyphGraphicItems).forEach((graphicItem => { graphicItem.states = {}; })), this.useStates(this.states)), this.items.map((item => { item.nextAttrs = {}; })); } encodeCustom(nextAttrs) { var _a; let customEncodeValues = {}; const channelEncoder = this.glyphMeta.getChannelEncoder(), functionEncoder = this.glyphMeta.getFunctionEncoder(); if (functionEncoder && (customEncodeValues = functionEncoder.call(null, Object.assign({}, null === (_a = this.graphicItem) || void 0 === _a ? void 0 : _a.attribute, nextAttrs), this.getDatum(), this, this.mark.getGlyphConfig())), channelEncoder) { let allAttrs; Object.keys(channelEncoder).forEach((channel => { var _a; if (!(0, vutils_1.isNil)(nextAttrs[channel])) { allAttrs || (allAttrs = Object.assign({}, null === (_a = this.graphicItem) || void 0 === _a ? void 0 : _a.attribute, nextAttrs)); const encodeResult = channelEncoder[channel].call(null, channel, nextAttrs[channel], allAttrs, this.getDatum(), this, this.mark.getGlyphConfig()); Object.keys(null != encodeResult ? encodeResult : {}).forEach((markName => { var _a; customEncodeValues[markName] = Object.assign(null !== (_a = customEncodeValues[markName]) && void 0 !== _a ? _a : {}, encodeResult[markName]); })); } })); } return customEncodeValues; } encodeDefault() { const defaultEncodeValues = {}; if (this.glyphMeta.getDefaultEncoder()) { const defaultEncodeResult = this.glyphMeta.getDefaultEncoder().call(null, this.getDatum(), this, this.mark.getGlyphConfig()); Object.assign(defaultEncodeValues, defaultEncodeResult); } return defaultEncodeValues; } _onGlyphAttributeUpdate(first = !1) { return attributes => { if (!this.mark) return attributes; const glyphMarks = this.glyphMeta.getMarks(), graphicAttributes = (0, transform_1.transformAttributes)(this.mark.getAttributeTransforms(), attributes, this), defaultEncodeValues = first ? this.encodeDefault() : null, customEncodeValues = this.encodeCustom(attributes); return Object.keys(glyphMarks).forEach((markName => { const markType = glyphMarks[markName], graphicItem = this.glyphGraphicItems[markName], customAttributes = null == customEncodeValues ? void 0 : customEncodeValues[markName], additionalAttributes = Object.assign({}, customAttributes); if (first) { const defaultAttributes = null == defaultEncodeValues ? void 0 : defaultEncodeValues[markName]; Object.keys(null != defaultAttributes ? defaultAttributes : {}).forEach((key => { (0, vutils_1.has)(this.items[0].nextAttrs, key) || (0, vutils_1.has)(additionalAttributes, key) || (additionalAttributes[key] = defaultAttributes[key]); })); } const glyphAttributes = Object.assign({}, (0, transform_1.cloneTransformAttributes)(markType, attributes), additionalAttributes), glyphItems = this._generateGlyphItems(markType, this.items, glyphAttributes); this.coordinateTransformEncode(glyphItems); const graphicAttributes = this.transformElementItems(glyphItems, markType); this.applyGlyphGraphicAttributes(graphicAttributes, markName, graphicItem), markType === enums_1.GrammarMarkType.shape && (graphicItem.datum = glyphItems[0].datum); })), graphicAttributes; }; } _generateGlyphItems(markType, items, additionalAttributes) { const glyphItems = items.map((item => Object.assign({}, item, { nextAttrs: additionalAttributes }))); return constants_1.CollectionMarkType.includes(markType) && this.mark.getSpec().enableSegments && glyphItems.forEach(((glyphItem, index) => { glyphItem.nextAttrs = Object.assign({}, items[index].nextAttrs, additionalAttributes); })), glyphItems; } getGraphicAttribute(channel, prev = !1, markName) { if (!this.graphicItem) return; const prevGraphicAttributes = this.getPrevGraphicAttributes(markName); if (prev && (0, vutils_1.has)(prevGraphicAttributes, channel)) return prevGraphicAttributes[channel]; return (markName ? this.glyphGraphicItems[markName] : this.graphicItem).attribute[channel]; } setGraphicAttribute(channel, value, final = !0, markName) { if (!this.graphicItem) return; const graphicItem = markName ? this.glyphGraphicItems[markName] : this.graphicItem, finalGraphicAttributes = this.getFinalGraphicAttributes(markName), prevGraphicAttributes = this.getPrevGraphicAttributes(markName); final && (finalGraphicAttributes[channel] = value), (0, vutils_1.has)(prevGraphicAttributes, channel) || (prevGraphicAttributes[channel] = graphicItem.attribute[channel]), graphicItem.setAttribute(channel, value); } setGraphicAttributes(attributes, final = !0, markName) { if (!this.graphicItem) return; const graphicItem = markName ? this.glyphGraphicItems[markName] : this.graphicItem, finalGraphicAttributes = this.getFinalGraphicAttributes(markName), prevGraphicAttributes = this.getPrevGraphicAttributes(markName); Object.keys(attributes).forEach((key => { final && (finalGraphicAttributes[key] = attributes[key]), (0, vutils_1.has)(prevGraphicAttributes, key) || (prevGraphicAttributes[key] = graphicItem.attribute[key]); })), graphicItem.setAttributes(attributes); } diffAttributes(graphicAttributes, markName) { const diffResult = {}, finalGraphicAttributes = this.getFinalGraphicAttributes(markName); for (const key in graphicAttributes) (0, vutils_1.has)(finalGraphicAttributes, key) && (0, vutils_1.isEqual)(finalGraphicAttributes[key], graphicAttributes[key]) || (diffResult[key] = graphicAttributes[key]); return diffResult; } applyGlyphGraphicAttributes(graphicAttributes, markName, graphicItem) { var _a, _b; if (this.mark.needAnimate()) { const nextGraphicAttributes = this.diffAttributes(graphicAttributes, markName), prevGraphicAttributes = null !== (_a = this.getPrevGraphicAttributes(markName)) && void 0 !== _a ? _a : {}, finalGraphicAttributes = null !== (_b = this.getFinalGraphicAttributes(markName)) && void 0 !== _b ? _b : {}; Object.keys(nextGraphicAttributes).forEach((channel => { prevGraphicAttributes[channel] = graphicItem.attribute[channel], finalGraphicAttributes[channel] = nextGraphicAttributes[channel]; })), this.setNextGraphicAttributes(nextGraphicAttributes, markName), this.setPrevGraphicAttributes(prevGraphicAttributes, markName), this.setFinalGraphicAttributes(finalGraphicAttributes, markName), graphicItem.setAttributes(nextGraphicAttributes); } else graphicItem.setAttributes(graphicAttributes); } getFinalGraphicAttributes(markName) { return (markName ? this.glyphGraphicItems[markName] : this.graphicItem).finalAttrs; } setFinalGraphicAttributes(attributes, markName) { (markName ? this.glyphGraphicItems[markName] : this.graphicItem).finalAttrs = attributes; } getPrevGraphicAttributes(markName) { return (markName ? this.glyphGraphicItems[markName] : this.graphicItem).prevAttrs; } setPrevGraphicAttributes(attributes, markName) { (markName ? this.glyphGraphicItems[markName] : this.graphicItem).prevAttrs = attributes; } getNextGraphicAttributes(markName) { return (markName ? this.glyphGraphicItems[markName] : this.graphicItem).nextAttrs; } setNextGraphicAttributes(attributes, markName) { (markName ? this.glyphGraphicItems[markName] : this.graphicItem).nextAttrs = attributes; } clearChangedGraphicAttributes() { this.setPrevGraphicAttributes(null), this.setNextGraphicAttributes(null), Object.keys(this.glyphGraphicItems).forEach((markName => { this.setPrevGraphicAttributes(null, markName), this.setNextGraphicAttributes(null, markName); })); } clearGraphicAttributes() { this.setPrevGraphicAttributes(null), this.setNextGraphicAttributes(null), this.setFinalGraphicAttributes(null), Object.keys(this.glyphGraphicItems).forEach((markName => { this.setPrevGraphicAttributes(null, markName), this.setNextGraphicAttributes(null, markName), this.setFinalGraphicAttributes(null, markName); })); } remove() { this.glyphGraphicItems = null, super.remove(); } release() { this.glyphGraphicItems && (Object.values(this.glyphGraphicItems).forEach((graphicItem => { graphicItem[constants_1.BridgeElementKey] = null; })), this.glyphGraphicItems = null), super.release(); } } exports.GlyphElement = GlyphElement; //# sourceMappingURL=glyph-element.js.map