UNPKG

@visactor/vchart

Version:

charts lib based @visactor/VGrammar

582 lines (575 loc) 39.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: !0 }), exports.registerSankeySeries = exports.SankeySeries = void 0; const cartesian_1 = require("../cartesian/cartesian"), type_1 = require("../interface/type"), utils_1 = require("../../animation/utils"), config_1 = require("../../animation/config"), register_1 = require("../../data/register"), sankey_1 = require("../../data/transforms/sankey"), sankey_nodes_1 = require("../../data/transforms/sankey-nodes"), sankey_links_1 = require("../../data/transforms/sankey-links"), interface_1 = require("../../compile/mark/interface"), vdataset_1 = require("@visactor/vdataset"), layout_1 = require("../../constant/layout"), attribute_1 = require("../../constant/attribute"), event_1 = require("../../constant/event"), tooltip_helper_1 = require("./tooltip-helper"), vutils_1 = require("@visactor/vutils"), animation_1 = require("./animation"), color_ordinal_scale_1 = require("../../scale/color-ordinal-scale"), rect_1 = require("../../mark/rect"), text_1 = require("../../mark/text"), link_path_1 = require("../../mark/link-path"), constant_1 = require("./constant"), flatten_1 = require("../../data/transforms/flatten"), factory_1 = require("../../core/factory"), initialize_1 = require("../../data/initialize"), data_key_1 = require("../../data/transforms/data-key"), sankey_transformer_1 = require("./sankey-transformer"), util_1 = require("../../component/util"), util_2 = require("../../util"), glyph_1 = require("../../mark/utils/glyph"), sankey_2 = require("../../theme/builtin/common/series/sankey"); class SankeySeries extends cartesian_1.CartesianSeries { constructor() { super(...arguments), this.type = type_1.SeriesTypeEnum.sankey, this.transformerConstructor = sankey_transformer_1.SankeySeriesSpecTransformer, this._nodeLayoutZIndex = layout_1.LayoutZIndex.Node, this._labelLayoutZIndex = layout_1.LayoutZIndex.Label, this._viewBox = new vutils_1.Bounds, this._fillByNode = datum => { var _a, _b, _c, _d, _e; if (datum && datum.sourceRect && datum.targetRect) return this._fillByLink(datum); const fill = null === (_b = null === (_a = this._spec.node) || void 0 === _a ? void 0 : _a.style) || void 0 === _b ? void 0 : _b.fill; if ((0, vutils_1.isValid)(fill)) return fill; if ((0, vutils_1.isValid)(this._spec.seriesField)) { const colorScale = null === (_d = null === (_c = this._option) || void 0 === _c ? void 0 : _c.globalScale) || void 0 === _d ? void 0 : _d.getScale("color"), nodeDatum = (null == datum ? void 0 : datum.datum) ? datum.datum : datum; return null == colorScale ? void 0 : colorScale.scale(null == nodeDatum ? void 0 : nodeDatum[this._spec.seriesField]); } return null === (_e = this._colorScale) || void 0 === _e ? void 0 : _e.scale(this._getNodeNameFromData(datum)); }, this._fillByLink = datum => { var _a, _b, _c, _d, _e, _f; const fill = null === (_b = null === (_a = this._spec.link) || void 0 === _a ? void 0 : _a.style) || void 0 === _b ? void 0 : _b.fill; if (fill) return fill; if ((0, vutils_1.isValid)(this._spec.seriesField)) { const sourceNode = null === (_c = this._nodesSeriesData.latestData) || void 0 === _c ? void 0 : _c.find((entry => datum.source === entry.key)), nodeDatum = null == sourceNode ? void 0 : sourceNode.datum, colorScale = null === (_e = null === (_d = this._option) || void 0 === _d ? void 0 : _d.globalScale) || void 0 === _e ? void 0 : _e.getScale("color"); return null == colorScale ? void 0 : colorScale.scale(null == nodeDatum ? void 0 : nodeDatum[this._spec.seriesField]); } const sourceName = (0, vutils_1.isNumber)(datum.source) ? this.getNodeList()[datum.source] : datum.source; return null === (_f = this._colorScale) || void 0 === _f ? void 0 : _f.scale(sourceName); }, this._handleEmphasisElement = params => { var _a; const emphasisSpec = null !== (_a = this._spec.emphasis) && void 0 !== _a ? _a : {}, graphic = params.item; "adjacency" === emphasisSpec.effect ? graphic && params.mark === this._nodeMark ? this._handleNodeAdjacencyClick(graphic) : graphic && params.mark === this._linkMark ? this._handleLinkAdjacencyClick(graphic) : this._handleClearEmpty() : "related" === emphasisSpec.effect && (graphic && params.mark === this._nodeMark ? this._handleNodeRelatedClick(graphic) : graphic && params.mark === this._linkMark ? this._handleLinkRelatedClick(graphic) : this._handleClearEmpty()); }, this._handleClearEmpty = () => { var _a, _b; if (!this._needClear) return; const allNodeElements = null === (_a = this._nodeMark) || void 0 === _a ? void 0 : _a.getGraphics(); if (!allNodeElements || !allNodeElements.length) return; const allLinkElements = null === (_b = this._linkMark) || void 0 === _b ? void 0 : _b.getGraphics(); allLinkElements && allLinkElements.length && (allNodeElements.forEach((el => { el.removeState(interface_1.STATE_VALUE_ENUM.STATE_SANKEY_EMPHASIS), el.removeState(interface_1.STATE_VALUE_ENUM.STATE_SANKEY_EMPHASIS_REVERSE); })), allLinkElements.forEach((el => { el.removeState(interface_1.STATE_VALUE_ENUM.STATE_SANKEY_EMPHASIS), el.removeState(interface_1.STATE_VALUE_ENUM.STATE_SANKEY_EMPHASIS_REVERSE); })), this._needClear = !1); }, this._handleNodeAdjacencyClick = graphic => { const nodeDatum = (0, util_2.getDatumOfGraphic)(graphic), highlightNodes = [ nodeDatum.key ]; if (this._linkMark) { const allLinkElements = this._linkMark.getGraphics(); if (!allLinkElements || !allLinkElements.length) return; allLinkElements.forEach(((linkEl, i) => { const linkDatum = (0, util_2.getDatumOfGraphic)(linkEl); linkDatum.source === nodeDatum.key ? (highlightNodes.includes(linkDatum.target) || highlightNodes.push(linkDatum.target), linkEl.removeState(interface_1.STATE_VALUE_ENUM.STATE_SANKEY_EMPHASIS_REVERSE), linkEl.addState(interface_1.STATE_VALUE_ENUM.STATE_SANKEY_EMPHASIS, !0)) : linkDatum.target === nodeDatum.key ? (highlightNodes.includes(linkDatum.source) || highlightNodes.push(linkDatum.source), linkEl.removeState(interface_1.STATE_VALUE_ENUM.STATE_SANKEY_EMPHASIS_REVERSE), linkEl.addState(interface_1.STATE_VALUE_ENUM.STATE_SANKEY_EMPHASIS, !0)) : (linkEl.removeState(interface_1.STATE_VALUE_ENUM.STATE_SANKEY_EMPHASIS), linkEl.addState(interface_1.STATE_VALUE_ENUM.STATE_SANKEY_EMPHASIS_REVERSE, !0)); })); } this._nodeMark && this._highLightElements(this._nodeMark.getGraphics(), highlightNodes), this._needClear = !0; }, this._handleLinkAdjacencyClick = graphic => { const curLinkDatum = (0, util_2.getDatumOfGraphic)(graphic), highlightNodes = [ curLinkDatum.source, curLinkDatum.target ]; if (this._linkMark) { const allLinkElements = this._linkMark.getGraphics(); if (!allLinkElements || !allLinkElements.length) return; allLinkElements.forEach((linkEl => { linkEl === graphic ? (linkEl.removeState(interface_1.STATE_VALUE_ENUM.STATE_SANKEY_EMPHASIS_REVERSE), (0, glyph_1.addRuntimeState)(linkEl, interface_1.STATE_VALUE_ENUM.STATE_SANKEY_EMPHASIS, { ratio: 1 })) : (linkEl.removeState(interface_1.STATE_VALUE_ENUM.STATE_SANKEY_EMPHASIS), linkEl.addState(interface_1.STATE_VALUE_ENUM.STATE_SANKEY_EMPHASIS_REVERSE, !0)); })); } this._nodeMark && this._highLightElements(this._nodeMark.getGraphics(), highlightNodes), this._needClear = !0; }, this._handleNodeRelatedClick = graphic => { var _a; const nodeDatum = (0, util_2.getDatumOfGraphic)(graphic), allNodeElements = this._nodeMark.getGraphics(); if (!allNodeElements || !allNodeElements.length) return; const allLinkElements = this._linkMark.getGraphics(); if (!allLinkElements || !allLinkElements.length) return; const father = (null === (_a = (0, util_2.getDatumOfGraphic)(allLinkElements[0])) || void 0 === _a ? void 0 : _a.parents) ? "parents" : "source"; if ("source" === father) { const highlightNodes = [ nodeDatum.key ], highlightLinks = []; if (allLinkElements.forEach(((linkEl, i) => { var _a, _b, _c, _d; const linkDatum = (0, util_2.getDatumOfGraphic)(linkEl), father = (null == linkDatum ? void 0 : linkDatum.parents) ? "parents" : "source"; if ((0, vutils_1.array)(linkDatum[father]).includes(nodeDatum.key)) { if (highlightLinks.includes(null !== (_a = linkDatum.key) && void 0 !== _a ? _a : linkDatum.index) || highlightLinks.push(null !== (_b = linkDatum.key) && void 0 !== _b ? _b : linkDatum.index), highlightNodes.includes(linkDatum.source) || highlightNodes.push(linkDatum.source), !highlightNodes.includes(linkDatum.target)) { highlightNodes.push(linkDatum.target); let targetNodeSourceLinks = allNodeElements.find((nodeElement => nodeElement.data[0].key === linkDatum.target)).data[0].sourceLinks; for (;(null == targetNodeSourceLinks ? void 0 : targetNodeSourceLinks.length) > 0; ) { const newTargetNodeSourceLinks = []; return targetNodeSourceLinks.forEach((targetNodeSourceLinkDatum => { var _a, _b; if (!highlightLinks.includes(null !== (_a = targetNodeSourceLinkDatum.key) && void 0 !== _a ? _a : targetNodeSourceLinkDatum.index) && (highlightLinks.push(null !== (_b = targetNodeSourceLinkDatum.key) && void 0 !== _b ? _b : targetNodeSourceLinkDatum.index), !highlightNodes.includes(targetNodeSourceLinkDatum.target))) { highlightNodes.push(targetNodeSourceLinkDatum.target); const sourceNodeTemp = allNodeElements.find((nodeElement => nodeElement.data[0].key === targetNodeSourceLinkDatum.target)); newTargetNodeSourceLinks.push(sourceNodeTemp.data[0].targetLinks); } })), void (targetNodeSourceLinks = newTargetNodeSourceLinks); } } } else if (linkDatum.target === nodeDatum.key && (highlightLinks.includes(null !== (_c = linkDatum.key) && void 0 !== _c ? _c : linkDatum.index) || highlightLinks.push(null !== (_d = linkDatum.key) && void 0 !== _d ? _d : linkDatum.index), !highlightNodes.includes(linkDatum.source))) { highlightNodes.push(linkDatum.source); let sourceNodeTargetLinks = allNodeElements.find((nodeElement => nodeElement.data[0].key === linkDatum.source)).data[0].targetLinks; for (;(null == sourceNodeTargetLinks ? void 0 : sourceNodeTargetLinks.length) > 0; ) { const newSourceNodeTargetLinks = []; return sourceNodeTargetLinks.forEach((sourceNodeTargetLinkDatum => { var _a, _b; if (!highlightLinks.includes(null !== (_a = sourceNodeTargetLinkDatum.key) && void 0 !== _a ? _a : sourceNodeTargetLinkDatum.index) && (highlightLinks.push(null !== (_b = sourceNodeTargetLinkDatum.key) && void 0 !== _b ? _b : sourceNodeTargetLinkDatum.index), !highlightNodes.includes(sourceNodeTargetLinkDatum.source))) { highlightNodes.push(sourceNodeTargetLinkDatum.source); const sourceNodeTemp = allNodeElements.find((nodeElement => nodeElement.data[0].key === sourceNodeTargetLinkDatum.source)); newSourceNodeTargetLinks.push(sourceNodeTemp.data[0].targetLinks); } })), void (sourceNodeTargetLinks = newSourceNodeTargetLinks); } } })), this._linkMark) { const allLinkElements = this._linkMark.getGraphics(); if (!allLinkElements || !allLinkElements.length) return; allLinkElements.forEach(((linkEl, i) => { var _a; const linkDatum = (0, util_2.getDatumOfGraphic)(linkEl); highlightLinks.includes(null !== (_a = linkDatum.key) && void 0 !== _a ? _a : linkDatum.index) ? (linkEl.removeState(interface_1.STATE_VALUE_ENUM.STATE_SANKEY_EMPHASIS_REVERSE), linkEl.addState(interface_1.STATE_VALUE_ENUM.STATE_SANKEY_EMPHASIS, !0)) : (linkEl.removeState(interface_1.STATE_VALUE_ENUM.STATE_SANKEY_EMPHASIS), linkEl.addState(interface_1.STATE_VALUE_ENUM.STATE_SANKEY_EMPHASIS_REVERSE, !0)); })); } this._nodeMark && this._highLightElements(this._nodeMark.getGraphics(), highlightNodes); } else { const highlightNodes = [ nodeDatum.key ], upstreamLinks = nodeDatum.targetLinks.reduce(((res, link) => ((0, vutils_1.array)(link.datum).forEach((dividedLink => { const parents = dividedLink.parents, len = parents.length; for (let i = 0; i < len; i++) { const source = parents[i].key, target = parents[i + 1] ? parents[i + 1].key : nodeDatum.key, value = dividedLink.value, existingItem = res.find((item => item.source === source && item.target === target)); existingItem ? existingItem.value += value : res.push({ source: source, target: target, value: value }); } })), res)), []); allLinkElements.forEach(((linkEl, i) => { const linkDatum = (0, util_2.getDatumOfGraphic)(linkEl), originalDatum = linkDatum.datum, selectedDatum = originalDatum ? originalDatum.filter((entry => entry[father].some((par => par.key === nodeDatum.key)))) : null, upSelectedLink = upstreamLinks.find((upLink => upLink.source === linkDatum.source && upLink.target === linkDatum.target)); if (selectedDatum && selectedDatum.length) { highlightNodes.includes(linkDatum.source) || highlightNodes.push(linkDatum.source), highlightNodes.includes(linkDatum.target) || highlightNodes.push(linkDatum.target); const ratio = selectedDatum.reduce(((sum, d) => sum + d.value), 0) / linkDatum.value; return linkEl.removeState(interface_1.STATE_VALUE_ENUM.STATE_SANKEY_EMPHASIS_REVERSE), void (0, glyph_1.addRuntimeState)(linkEl, interface_1.STATE_VALUE_ENUM.STATE_SANKEY_EMPHASIS, { ratio: ratio }); } if (upSelectedLink) return highlightNodes.includes(linkDatum.source) || highlightNodes.push(linkDatum.source), highlightNodes.includes(linkDatum.target) || highlightNodes.push(linkDatum.target), linkEl.removeState(interface_1.STATE_VALUE_ENUM.STATE_SANKEY_EMPHASIS_REVERSE), void (0, glyph_1.addRuntimeState)(linkEl, interface_1.STATE_VALUE_ENUM.STATE_SANKEY_EMPHASIS, { ratio: upSelectedLink.value / linkDatum.value }); linkEl.removeState(interface_1.STATE_VALUE_ENUM.STATE_SANKEY_EMPHASIS), linkEl.addState(interface_1.STATE_VALUE_ENUM.STATE_SANKEY_EMPHASIS_REVERSE, !0); })), this._nodeMark && this._highLightElements(this._nodeMark.getGraphics(), highlightNodes); } this._needClear = !0; }, this._handleLinkRelatedClick = graphic => { const allNodeElements = this._nodeMark.getGraphics(); if (!allNodeElements || !allNodeElements.length) return; const allLinkElements = this._linkMark.getGraphics(); if (!allLinkElements || !allLinkElements.length) return; if ("source" === ((0, util_2.getDatumOfGraphic)(graphic) ? "parents" : "source")) this._linkMark && allLinkElements.forEach((linkEl => { linkEl.removeState(interface_1.STATE_VALUE_ENUM.STATE_SANKEY_EMPHASIS), linkEl.removeState(interface_1.STATE_VALUE_ENUM.STATE_SANKEY_EMPHASIS_REVERSE); })), this._nodeMark && allNodeElements.forEach((el => { el.removeState(interface_1.STATE_VALUE_ENUM.STATE_SANKEY_EMPHASIS), el.removeState(interface_1.STATE_VALUE_ENUM.STATE_SANKEY_EMPHASIS_REVERSE); })); else { const curLinkDatum = (0, util_2.getDatumOfGraphic)(graphic), highlightNodes = [ curLinkDatum.source, curLinkDatum.target ], upstreamLinks = []; (0, vutils_1.array)(curLinkDatum.datum).forEach((dividedLink => { const parents = dividedLink.parents, len = parents.length; for (let i = 0; i < len - 1; i++) { const source = parents[i].key, target = parents[i + 1].key, value = dividedLink.value, existingItem = upstreamLinks.find((item => item.source === source && item.target === target)); upstreamLinks.push({ source: parents[i].key, target: parents[i + 1].key, value: dividedLink.value }), existingItem ? existingItem.value += value : upstreamLinks.push({ source: source, target: target, value: value }); } })), allLinkElements.forEach((linkEl => { const linkDatum = (0, util_2.getDatumOfGraphic)(linkEl), originalDatum = linkDatum.datum; if (linkDatum.source === curLinkDatum.source && linkDatum.target === curLinkDatum.target) return linkEl.removeState(interface_1.STATE_VALUE_ENUM.STATE_SANKEY_EMPHASIS_REVERSE), void (0, glyph_1.addRuntimeState)(linkEl, interface_1.STATE_VALUE_ENUM.STATE_SANKEY_EMPHASIS, { ratio: 1 }); const selectedDatum = originalDatum ? originalDatum.filter((entry => { const parentKeysList = entry.parents.map((item => item.key)); return parentKeysList.includes(curLinkDatum.source) && parentKeysList.includes(curLinkDatum.target); })) : null; if (selectedDatum && selectedDatum.length) { highlightNodes.includes(linkDatum.source) || highlightNodes.push(linkDatum.source), highlightNodes.includes(linkDatum.target) || highlightNodes.push(linkDatum.target); const ratio = selectedDatum.filter((entry => entry.parents.some(((par, index) => { var _a; return par.key === curLinkDatum.source && (null === (_a = entry.parents[index + 1]) || void 0 === _a ? void 0 : _a.key) === curLinkDatum.target; })))).reduce(((sum, d) => sum + d.value), 0) / linkDatum.value; return linkEl.removeState(interface_1.STATE_VALUE_ENUM.STATE_SANKEY_EMPHASIS_REVERSE), void (0, glyph_1.addRuntimeState)(linkEl, interface_1.STATE_VALUE_ENUM.STATE_SANKEY_EMPHASIS, { ratio: ratio }); } const upSelectedLink = upstreamLinks.find((upLink => upLink.source === linkDatum.source && upLink.target === linkDatum.target)); if (upSelectedLink) return highlightNodes.includes(linkDatum.source) || highlightNodes.push(linkDatum.source), highlightNodes.includes(linkDatum.target) || highlightNodes.push(linkDatum.target), linkEl.removeState(interface_1.STATE_VALUE_ENUM.STATE_SANKEY_EMPHASIS_REVERSE), void (0, glyph_1.addRuntimeState)(linkEl, interface_1.STATE_VALUE_ENUM.STATE_SANKEY_EMPHASIS, { ratio: upSelectedLink.value / linkDatum.value }); linkEl.removeState(interface_1.STATE_VALUE_ENUM.STATE_SANKEY_EMPHASIS), linkEl.addState(interface_1.STATE_VALUE_ENUM.STATE_SANKEY_EMPHASIS_REVERSE, !0); })), this._highLightElements(allNodeElements, highlightNodes); } this._needClear = !0; }; } get direction() { var _a; return null !== (_a = this._spec.direction) && void 0 !== _a ? _a : "horizontal"; } getCategoryField() { return this._categoryField; } setCategoryField(f) { return this._categoryField = f, this._categoryField; } getValueField() { return this._valueField; } setValueField(f) { return this._valueField = f, this._valueField; } setAttrFromSpec() { var _a; super.setAttrFromSpec(), this.setCategoryField(this._spec.categoryField), this.setValueField(this._spec.valueField), this.setSeriesField(null !== (_a = this._spec.seriesField) && void 0 !== _a ? _a : this._spec.categoryField); } initData() { var _a, _b, _c, _d; super.initData(); const viewData = this.getViewData(), rawData = this.getRawData(); if (rawData && viewData) { (0, register_1.registerDataSetInstanceTransform)(this._dataSet, "sankeyLayout", sankey_1.sankeyLayout), (0, register_1.registerDataSetInstanceTransform)(this._dataSet, "sankeyFormat", sankey_1.sankeyFormat), rawData.transform({ type: "sankeyFormat" }, !1), viewData.transform({ type: "sankeyLayout", options: { view: () => ({ x0: this._viewBox.x1, x1: this._viewBox.x2, y0: this._viewBox.y1, y1: this._viewBox.y2 }), sourceField: this._spec.sourceField, targetField: this._spec.targetField, valueField: this._spec.valueField, direction: this.direction, crossNodeAlign: this._spec.crossNodeAlign, nodeAlign: null !== (_a = this._spec.nodeAlign) && void 0 !== _a ? _a : "justify", nodeGap: null !== (_b = this._spec.nodeGap) && void 0 !== _b ? _b : 8, nodeWidth: null !== (_c = this._spec.nodeWidth) && void 0 !== _c ? _c : 10, linkWidth: this._spec.linkWidth, minStepWidth: this._spec.minStepWidth, minNodeHeight: null !== (_d = this._spec.minNodeHeight) && void 0 !== _d ? _d : 4, maxNodeHeight: this._spec.maxNodeHeight, minLinkHeight: this._spec.minLinkHeight, maxLinkHeight: this._spec.maxLinkHeight, iterations: this._spec.iterations, nodeKey: this._spec.nodeKey, linkSortBy: this._spec.linkSortBy, nodeSortBy: this._spec.nodeSortBy, setNodeLayer: this._spec.setNodeLayer, dropIsolatedNode: this._spec.dropIsolatedNode, nodeHeight: this._spec.nodeHeight, linkHeight: this._spec.linkHeight, equalNodeHeight: this._spec.equalNodeHeight, linkOverlap: this._spec.linkOverlap, inverse: this._spec.inverse }, level: initialize_1.TransformLevel.sankeyLayout }); const {dataSet: dataSet} = this._option; (0, register_1.registerDataSetInstanceTransform)(dataSet, "sankeyNodes", sankey_nodes_1.sankeyNodes), (0, register_1.registerDataSetInstanceTransform)(dataSet, "flatten", flatten_1.flatten); const nodesDataView = new vdataset_1.DataView(dataSet, { name: `sankey-node-${this.id}-data` }); nodesDataView.parse([ this.getViewData() ], { type: "dataview" }), nodesDataView.transform({ type: "sankeyNodes" }), nodesDataView.transform({ type: "flatten", options: { callback: node => { if (node.datum) { const nodeData = node.datum[node.depth]; return Object.assign(Object.assign({}, node), nodeData); } return node; } } }, !1), nodesDataView.transform({ type: "addVChartProperty", options: { beforeCall: data_key_1.initKeyMap.bind(this), call: data_key_1.addDataKey } }, !1), this._nodesSeriesData = nodesDataView, (0, register_1.registerDataSetInstanceTransform)(dataSet, "sankeyLinks", sankey_links_1.sankeyLinks); const linksDataView = new vdataset_1.DataView(dataSet, { name: `sankey-link-${this.id}-data` }); linksDataView.parse([ this.getViewData() ], { type: "dataview" }), linksDataView.transform({ type: "sankeyLinks" }), linksDataView.transform({ type: "addVChartProperty", options: { beforeCall: data_key_1.initKeyMap.bind(this), call: data_key_1.addDataKey } }, !1), this._linksSeriesData = linksDataView; } } compileData() { var _a, _b; super.compileData(), null === (_a = this._linkMark) || void 0 === _a || _a.compileData(), null === (_b = this._nodeMark) || void 0 === _b || _b.compileData(); } initMark() { this._rootMark.setMarkConfig({ overflow: this._spec.overflow, interactive: !!this._spec.overflow }); const nodeMark = this._createMark(SankeySeries.mark.node, { isSeriesMark: !0, dataView: this._nodesSeriesData }); nodeMark && (nodeMark.setMarkConfig({ zIndex: this._nodeLayoutZIndex }), this._nodeMark = nodeMark); const linkMark = this._createMark(SankeySeries.mark.link, { dataView: this._linksSeriesData }); linkMark && (this._linkMark = linkMark); } _buildMarkAttributeContext() { super._buildMarkAttributeContext(), this._markAttributeContext.valueToNode = this.valueToNode.bind(this), this._markAttributeContext.valueToLink = this.valueToLink.bind(this); } valueToNode(value) { const nodes = this._nodesSeriesData.latestData, specifyValue = (0, vutils_1.array)(value)[0]; return nodes && nodes.find((node => node.key === specifyValue)); } valueToLink(value) { const links = this._linksSeriesData.latestData, specifyValue = (0, vutils_1.array)(value); return links && links.find((link => link && link.source === specifyValue[0] && link.target === specifyValue[1])); } valueToPositionX(value) { const node = this.valueToNode(value); return null == node ? void 0 : node.x0; } valueToPositionY(value) { const node = this.valueToNode(value); return null == node ? void 0 : node.y0; } initMarkStyle() { this._initNodeMarkStyle(), this._initLinkMarkStyle(); } _initNodeMarkStyle() { var _a, _b; const nodeMark = this._nodeMark; nodeMark && (this.setMarkStyle(nodeMark, { x: datum => datum.x0, x1: datum => datum.x1, y: datum => datum.y0, y1: datum => datum.y1 }, interface_1.STATE_VALUE_ENUM.STATE_NORMAL, attribute_1.AttributeLevel.Mark), this.setMarkStyle(nodeMark, { fill: null !== (_b = null === (_a = this._spec.node.style) || void 0 === _a ? void 0 : _a.fill) && void 0 !== _b ? _b : this._fillByNode }, "normal", attribute_1.AttributeLevel.User_Mark)); } _initLinkMarkStyle() { var _a, _b; const linkMark = this._linkMark; linkMark && (linkMark.setGlyphConfig({ direction: this.direction }), this.setMarkStyle(linkMark, { x0: datum => datum.x0, x1: datum => datum.x1, y0: datum => datum.y0, y1: datum => datum.y1, thickness: datum => datum.thickness }, interface_1.STATE_VALUE_ENUM.STATE_NORMAL, attribute_1.AttributeLevel.Series), this.setMarkStyle(linkMark, { fill: null !== (_b = null === (_a = this._spec.link.style) || void 0 === _a ? void 0 : _a.fill) && void 0 !== _b ? _b : this._fillByLink }, "normal", attribute_1.AttributeLevel.User_Mark)); } initLabelMarkStyle(labelMark, labelSpec) { if (!labelMark) return; const position = labelSpec.position; position && position.includes("inside") ? this.setMarkStyle(labelMark, { fill: "#ffffff", text: datum => this._createText(datum, labelSpec), maxLineWidth: datum => { var _a; return null !== (_a = labelSpec.limit) && void 0 !== _a ? _a : datum.x1 - datum.x0; } }) : this.setMarkStyle(labelMark, { fill: this._fillByNode, text: datum => this._createText(datum, labelSpec), maxLineWidth: labelSpec.limit }), labelMark.setMarkConfig({ zIndex: this._labelLayoutZIndex }); } _createText(datum, labelSpec) { if ((0, vutils_1.isNil)(datum) || (0, vutils_1.isNil)(datum.datum)) return ""; let text = datum.datum[this._spec.categoryField] || ""; const {formatMethod: formatMethod, formatter: formatter} = labelSpec || {}, {formatFunc: formatFunc, args: args} = (0, util_1.getFormatFunction)(formatMethod, formatter, text, datum.datum); return formatFunc && (text = formatFunc(...args, { series: this })), text; } initAnimation() { var _a, _b, _c, _d; const animationParams = { direction: this.direction, growFrom: () => { var _a, _b; return "horizontal" === this.direction ? null === (_a = this._xAxisHelper) || void 0 === _a ? void 0 : _a.getScale(0).scale(0) : null === (_b = this._yAxisHelper) || void 0 === _b ? void 0 : _b.getScale(0).scale(0); } }, appearPreset = null === (_b = null === (_a = this._spec) || void 0 === _a ? void 0 : _a.animationAppear) || void 0 === _b ? void 0 : _b.preset; this._nodeMark && this._nodeMark.setAnimationConfig((0, utils_1.animationConfig)(null === (_c = factory_1.Factory.getAnimationInKey("sankeyNode")) || void 0 === _c ? void 0 : _c(animationParams, appearPreset), (0, utils_1.userAnimationConfig)("node", this._spec, this._markAttributeContext))), this._linkMark && this._linkMark.setAnimationConfig((0, utils_1.animationConfig)(null === (_d = factory_1.Factory.getAnimationInKey("sankeyLinkPath")) || void 0 === _d ? void 0 : _d(animationParams, appearPreset), (0, utils_1.userAnimationConfig)("link", this._spec, this._markAttributeContext))); } initEvent() { var _a, _b, _c; super.initEvent(), null === (_a = this._nodesSeriesData) || void 0 === _a || _a.target.addListener("change", this.nodesSeriesDataUpdate.bind(this)), null === (_b = this._linksSeriesData) || void 0 === _b || _b.target.addListener("change", this.linksSeriesDataUpdate.bind(this)); const emphasisSpec = null !== (_c = this._spec.emphasis) && void 0 !== _c ? _c : {}; if (!0 !== this._option.disableTriggerEvent && emphasisSpec.enable && ("adjacency" === emphasisSpec.effect || "related" === emphasisSpec.effect)) { const event = "hover" === emphasisSpec.trigger ? "pointerover" : "pointerdown"; this.event.on(event, { level: event_1.Event_Bubble_Level.chart }, this._handleEmphasisElement); } } nodesSeriesDataUpdate() { this._nodeMark.getData().updateData(), this._nodeList = null, this._setNodeOrdinalColorScale(); } linksSeriesDataUpdate() { this._linkMark.getData().updateData(); } _highLightElements(graphics, highlightNodes) { graphics && graphics.length && graphics.forEach((g => { g.removeState([ interface_1.STATE_VALUE_ENUM.STATE_SANKEY_EMPHASIS_REVERSE, interface_1.STATE_VALUE_ENUM.STATE_SANKEY_EMPHASIS ]), highlightNodes.includes((0, util_2.getDatumOfGraphic)(g).key) ? g.addState(interface_1.STATE_VALUE_ENUM.STATE_SANKEY_EMPHASIS, !0) : g.addState(interface_1.STATE_VALUE_ENUM.STATE_SANKEY_EMPHASIS_REVERSE, !0); })); } initTooltip() { this._tooltipHelper = new tooltip_helper_1.SankeySeriesTooltipHelper(this), this._nodeMark && this._tooltipHelper.activeTriggerSet.mark.add(this._nodeMark), this._linkMark && this._tooltipHelper.activeTriggerSet.mark.add(this._linkMark); } _setNodeOrdinalColorScale() { var _a, _b, _c, _d, _e; const colorScale = null === (_b = null === (_a = this._option) || void 0 === _a ? void 0 : _a.globalScale) || void 0 === _b ? void 0 : _b.getScale("color"); if (null == colorScale ? void 0 : colorScale._specified) return void (this._colorScale = colorScale); let colorDomain, colorRange; colorScale && (colorDomain = colorScale.domain(), colorRange = colorScale.range()), colorRange || (colorRange = this._getDataScheme()), colorDomain && !(0, vutils_1.isNil)(colorDomain[0]) || (colorDomain = this.getNodeList(), colorDomain && colorDomain.length > 10 && (colorRange = null === (_c = this._getDataScheme()[1]) || void 0 === _c ? void 0 : _c.scheme)); const ordinalScale = new color_ordinal_scale_1.ColorOrdinalScale; null === (_e = (_d = ordinalScale.domain(colorDomain)).range) || void 0 === _e || _e.call(_d, colorRange), this._colorScale = ordinalScale; } getNodeList() { var _a, _b; if (this._nodeList) return this._nodeList; const data = this._rawData.latestData[0], nodeList = (null == data ? void 0 : data.nodes) ? (null === (_a = data.nodes[0]) || void 0 === _a ? void 0 : _a.children) ? Array.from(this.extractNamesFromTree(data.nodes, this._spec.categoryField)) : data.nodes.map(((datum, index) => datum[this._spec.categoryField])) : (null == data ? void 0 : data.links) ? Array.from(this.extractNamesFromLink(data.links)) : null === (_b = null == data ? void 0 : data.values) || void 0 === _b ? void 0 : _b.map(((datum, index) => datum[this._spec.categoryField])); return this._nodeList = nodeList, nodeList; } _getNodeNameFromData(datum) { var _a; return (null == datum ? void 0 : datum.datum) ? datum.datum[this._spec.categoryField] : null !== (_a = datum.key) && void 0 !== _a ? _a : datum[this._spec.categoryField]; } extractNamesFromTree(tree, categoryName) { const uniqueNames = new Set; return tree.forEach((node => { if (uniqueNames.add(node[categoryName]), node.children) { this.extractNamesFromTree(node.children, categoryName).forEach((name => uniqueNames.add(name))); } })), uniqueNames; } extractNamesFromLink(links) { const uniqueNames = new Set, {sourceField: sourceField, targetField: targetField} = this._spec; return links.forEach((link => { (0, vutils_1.isValid)(link[sourceField]) && uniqueNames.add(link[sourceField]), (0, vutils_1.isValid)(link[targetField]) && uniqueNames.add(link[targetField]); })), uniqueNames; } getDimensionField() { return [ this._spec.categoryField ]; } getMeasureField() { return [ this._valueField ]; } getRawDataStatisticsByField(field, isNumeric) { var _a; if (this._rawStatisticsCache || (this._rawStatisticsCache = {}), !this._rawStatisticsCache[field]) { this._viewDataStatistics && this.getViewData().transformsArr.length <= 1 && (null === (_a = this._viewDataStatistics.latestData) || void 0 === _a ? void 0 : _a[field]) ? this._rawStatisticsCache[field] = this._viewDataStatistics.latestData[field] : this._rawData && (this._rawStatisticsCache[field] = { values: this._collectByField(field) }); } return this._rawStatisticsCache[field]; } _collectByField(field) { var _a, _b, _c; const keyArray = [], rawData = null === (_b = null === (_a = this.getRawData()) || void 0 === _a ? void 0 : _a.latestData) || void 0 === _b ? void 0 : _b[0]; if (!rawData) return []; if (rawData.links) (null === (_c = rawData.nodes) || void 0 === _c ? void 0 : _c.length) && rawData.nodes.forEach((node => { node[this._seriesField] && keyArray.push(node[this._seriesField]); })); else if (rawData.nodes) { const set = new Set; return (0, sankey_1.collectHierarchyField)(set, rawData.nodes, this._seriesField), Array.from(set); } return keyArray; } onLayoutEnd() { super.onLayoutEnd(), this._viewBox.set(0, 0, this._region.getLayoutRect().width, this._region.getLayoutRect().height), this.getViewData().reRunAllTransform(); } getDefaultShapeType() { return "square"; } _noAnimationDataKey(datum, index) {} getActiveMarks() { return [ this._nodeMark, this._linkMark ]; } getMarkData(datum) { return datum.datum ? (0, vutils_1.isArray)(datum.datum) ? datum.datum[datum.datum.length - 1] : datum.datum : datum; } } exports.SankeySeries = SankeySeries, SankeySeries.type = type_1.SeriesTypeEnum.sankey, SankeySeries.transformerConstructor = sankey_transformer_1.SankeySeriesSpecTransformer, SankeySeries.mark = constant_1.sankeySeriesMark, SankeySeries.builtInTheme = { sankey: sankey_2.sankey }; const registerSankeySeries = () => { (0, rect_1.registerRectMark)(), (0, link_path_1.registerLinkPathMark)(), (0, text_1.registerTextMark)(), (0, animation_1.registerSankeyAnimation)(), (0, config_1.registerFadeInOutAnimation)(), factory_1.Factory.registerSeries(SankeySeries.type, SankeySeries); }; exports.registerSankeySeries = registerSankeySeries; //# sourceMappingURL=sankey.js.map