UNPKG

@visactor/vmind

Version:

<div align="center"> <a href="https://github.com/VisActor#gh-light-mode-only" target="_blank"> <img alt="VisActor Logo" width="200" src="https://github.com/VisActor/.github/blob/main/profile/logo_500_200_light.svg"/> </a> <a href="https://githu

628 lines (615 loc) 20.1 kB
import { isArray, isNil, isPlainObject, isString, isValid, merge } from "@visactor/vutils"; import { deleteByPath, set } from "../../utils/set"; export const validSeriesForChart = { line: { series: [ "line" ] }, area: { series: [ "area" ] }, bar: { series: [ "bar" ] }, bar3d: { series: [ "bar3d" ] }, pie: { series: [ "pie" ] }, pie3d: { series: [ "pie3d" ] }, scatter: { series: [ "scatter" ] }, funnel: { series: [ "funnel" ] }, funnel3d: { series: [ "funnel3d" ] }, map: { series: [ "map" ] }, radar: { series: [ "radar" ] }, wordCloud: { series: [ "wordCloud" ] }, wordCloud3d: { series: [ "wordCloud3d" ] }, heatmap: { series: [ "heatmap" ] }, treemap: { series: [ "treemap" ] }, gauge: { series: [ "gauge", "gaugePointer" ] }, rangeColumn: { series: [ "rangeColumn" ] }, rangeColumn3d: { series: [ "rangeColumn3d" ] }, rangeArea: { series: [ "rangeArea" ] }, sequence: { series: [ "dot", "link" ] }, rose: { series: [ "rose" ] }, circularProgress: { series: [ "circularProgress" ] }, linearProgress: { series: [ "linearProgress" ] }, boxPlot: { series: [ "boxPlot" ] }, sankey: { series: [ "sankey" ] }, gaugePointer: { series: [ "gaugePointer" ] }, sunburst: { series: [ "sunburst" ] }, circlePacking: { series: [ "circlePacking" ] }, waterfall: { series: [ "waterfall" ] }, correlation: { series: [ "correlation" ] }, liquid: { series: [ "liquid" ] }, venn: { series: [ "venn" ] }, mosaic: { series: [ "mosaic" ] }, histogram: { series: [ "bar" ] }, histogram3d: { series: [ "bar3d" ] }, pictogram: { series: [ "pictogram" ] } }; export const getChartAxisType = chartSpec => [ "bar", "bar3d", "line", "scatter", "area", "boxPlot", "histogram", "histogram3d", "mosaic", "rangeArea", "rangeColumn", "rangeColumn3d", "waterfall" ].includes(chartSpec.type) ? "cartesian" : [ "radar", "rose" ].includes(chartSpec.type) ? "polar" : "none"; export const aliasByComponentType = { axes: { isArray: !0, aliasMap: { xAxis: { appendSpec: { orient: "bottom" } }, yAxis: { appendSpec: { orient: "left" } }, radiusAxis: { appendSpec: { orient: "radius" } }, angleAxis: { appendSpec: { orient: "angle" } }, leftAxis: { appendSpec: { orient: "left" } }, rightAxis: { appendSpec: { orient: "right" } }, topAxis: { appendSpec: { orient: "top" } }, bottomAxis: { appendSpec: { orient: "bottom" } }, allAxis: { filter: entry => !0 } } }, legends: { aliasMap: { discreteLegend: { filter: entry => isNil(entry.type) || "discrete" === entry.type }, colorLegend: { appendSpec: { type: "color" } }, sizeLegend: { appendSpec: { type: "size" } } } }, dataZoom: { aliasMap: { yDataZoom: { appendSpec: { orient: "left" }, filter: entry => "left" === entry.orient }, xDataZoom: { appendSpec: { orient: "bottom" }, filter: entry => "bottom" === entry.orient } } }, scrollBar: { aliasMap: { yScrollbar: { appendSpec: { orient: "right" }, filter: entry => "right" === entry.orient }, xScrollbar: { appendSpec: { orient: "bottom" }, filter: entry => "bottom" === entry.orient } } }, series: { isArray: !0, aliasMap: { lineSeries: { appendSpec: { type: "line" } }, areaSeries: { appendSpec: { type: "area" } }, barSeries: { appendSpec: { type: "bar" } }, bar3dSeries: { appendSpec: { type: "bar3d" } }, pieSeries: { appendSpec: { type: "pie" } }, pie3dSeries: { appendSpec: { type: "pie3d" } }, scatterSeries: { appendSpec: { type: "scatter" } }, funnelSeries: { appendSpec: { type: "funnel" } }, funnel3dSeries: { appendSpec: { type: "funnel3d" } }, mapSeries: { appendSpec: { type: "map" } }, radarSeries: { appendSpec: { type: "radar" } }, wordCloudSeries: { appendSpec: { type: "wordCloud" } }, wordCloud3dSeries: { appendSpec: { type: "wordCloud3d" } }, heatmapSeries: { appendSpec: { type: "heatmap" } }, treemapSeries: { appendSpec: { type: "treemap" } }, gaugeSeries: { appendSpec: { type: "gauge" } }, rangeColumnSeries: { appendSpec: { type: "rangeColumn" } }, rangeColumn3dSeries: { appendSpec: { type: "rangeColumn3d" } }, rangeAreaSeries: { appendSpec: { type: "rangeArea" } }, dotSeries: { appendSpec: { type: "dot" } }, geoSeries: { appendSpec: { type: "geo" } }, linkSeries: { appendSpec: { type: "link" } }, roseSeries: { appendSpec: { type: "rose" } }, circularProgressSeries: { appendSpec: { type: "circularProgress" } }, linearProgressSeries: { appendSpec: { type: "linearProgress" } }, boxPlotSeries: { appendSpec: { type: "boxPlot" } }, sankeySeries: { appendSpec: { type: "sankey" } }, gaugePointerSeries: { appendSpec: { type: "gaugePointer" } }, sunburstSeries: { appendSpec: { type: "sunburst" } }, circlePackingSeries: { appendSpec: { type: "circlePacking" } }, waterfallSeries: { appendSpec: { type: "waterfall" } }, correlationSeries: { appendSpec: { type: "correlation" } }, liquidSeries: { appendSpec: { type: "liquid" } }, vennSeries: { appendSpec: { type: "venn" } }, mosaicSeries: { appendSpec: { type: "mosaic" } } } }, scales: { isArray: !0 }, customMark: { isArray: !0 }, background: { isArray: !1 }, player: { isArray: !1 }, crosshair: {}, region: { isArray: !0 }, title: {}, markLine: {}, markArea: {}, markPoint: {}, seriesStyle: { isArray: !0 }, tooltip: { isArray: !1 }, brush: { isArray: !1 }, label: {} }; export const removeUnneedArrayInSpec = (leafSpec, compKey, parentKeyPath) => compKey === parentKeyPath && isArray(leafSpec) ? leafSpec[0] : leafSpec; export const findComponentNameByAlias = alias => { if (aliasByComponentType[alias]) return alias; const comp = Object.keys(aliasByComponentType).find((key => { var _a, _b; return !!(null === (_b = null === (_a = aliasByComponentType[key]) || void 0 === _a ? void 0 : _a.aliasMap) || void 0 === _b ? void 0 : _b[alias]); })); return comp || alias; }; const ALIAS_NAME_KEY = "_alias_name"; export const parseAliasOfPath = (parentKeyPath, compKey, chartSpec, leafSpec, op) => { var _a, _b, _c; const subPaths = parentKeyPath.split("."), aliasOptions = aliasByComponentType[compKey]; if (!aliasOptions) return { parentKeyPath: parentKeyPath }; const aliasName = subPaths[0].replace(/\[\d\]/, ""), isValidAlias = aliasOptions && aliasName && !!(null === (_a = aliasOptions.aliasMap) || void 0 === _a ? void 0 : _a[aliasName]); let newLeafSpec = leafSpec; 1 === subPaths.length && (newLeafSpec = isArray(leafSpec) ? leafSpec[0] : leafSpec); const isTargetArray = chartSpec[compKey] && isArray(chartSpec[compKey]) || (null == aliasOptions ? void 0 : aliasOptions.isArray), specifiedIndexRes = /\[(\d+)\]/.exec(subPaths[0]), specifiedIndex = specifiedIndexRes ? Number(specifiedIndexRes[1]) : -1; if (isTargetArray ? "add" === op && 1 === subPaths.length ? specifiedIndex >= 0 && (!chartSpec[compKey] || specifiedIndex <= chartSpec[compKey].length) ? subPaths[0] = `${compKey}[${specifiedIndex}]` : subPaths[0] = `${compKey}[${null !== (_c = null === (_b = chartSpec[compKey]) || void 0 === _b ? void 0 : _b.length) && void 0 !== _c ? _c : 0}]` : specifiedIndex >= 0 && (!chartSpec[compKey] || specifiedIndex <= chartSpec[compKey].length - 1) ? subPaths[0] = `${compKey}[${specifiedIndex}]` : subPaths[0] = `${compKey}[0]` : !1 !== (null == aliasOptions ? void 0 : aliasOptions.isArray) && "add" === op && chartSpec[compKey] ? (chartSpec[compKey] = [ chartSpec[compKey] ], subPaths[0] = `${compKey}[1]`) : subPaths[0] = compKey, !isValidAlias || "delete" === op || "deleteAll" === op) return { parentKeyPath: subPaths.join("."), leafSpec: newLeafSpec }; const appendSpec = Object.assign(Object.assign({}, aliasOptions.aliasMap[aliasName].appendSpec), { _alias_name: aliasName }), appendPath = []; if (chartSpec[compKey]) { const isMatchComp = comp => { const aliasEntry = aliasOptions.aliasMap[aliasName]; return aliasEntry.filter ? aliasEntry.filter(comp) : !!aliasEntry.appendSpec && Object.keys(aliasEntry.appendSpec).every((key => comp[key] === aliasEntry.appendSpec[key])); }; if (isArray(chartSpec[compKey])) { let specifiedComps = "add" !== op ? chartSpec[compKey].filter((comp => comp._alias_name === aliasName)) : []; if ("add" === op || specifiedComps.length || (specifiedComps = chartSpec[compKey].filter(isMatchComp)), specifiedComps.length) specifiedComps.forEach((comp => { const index = chartSpec[compKey].indexOf(comp), appended = [ ...subPaths ]; appended[0] = `${compKey}[${index}]`, appendPath.push(appended); })); else if (isValidAlias || "add" === op) { const appended = [ ...subPaths ]; appended[0] = `${compKey}[${chartSpec[compKey].length}]`, appendPath.push(appended); } } else if (isMatchComp(chartSpec[compKey]) && "add" !== op) { const appended = [ ...subPaths ]; appended[0] = `${compKey}`, appendPath.push(appended); } else { chartSpec[compKey] = [ chartSpec[compKey] ]; const appended = [ ...subPaths ]; appended[0] = `${compKey}[1]`, appendPath.push(appended); } } else if ("allAxis" === aliasName) { const axisType = getChartAxisType(chartSpec); if ("cartesian" === axisType) return { aliasName: aliasName, appendContent: [ { appendPath: "axes[0]", appendSpec: Object.assign({}, aliasByComponentType.axes.aliasMap.xAxis.appendSpec), parentKeyPath: [ "axes[0]", ...subPaths.slice(1) ].join(".") }, { appendPath: "axes[1]", appendSpec: Object.assign({}, aliasByComponentType.axes.aliasMap.yAxis.appendSpec), parentKeyPath: [ "axes[1]", ...subPaths.slice(1) ].join(".") } ], parentKeyPath: subPaths.join(".") }; if ("polar" === axisType) return { aliasName: aliasName, appendContent: [ { appendPath: "axes[0]", appendSpec: Object.assign({}, aliasByComponentType.axes.aliasMap.radiusAxis.appendSpec), parentKeyPath: [ "axes[0]", ...subPaths.slice(1) ].join(".") }, { appendPath: "axes[1]", appendSpec: Object.assign({}, aliasByComponentType.axes.aliasMap.angleAxis.appendSpec), parentKeyPath: [ "axes[1]", ...subPaths.slice(1) ].join(".") } ], parentKeyPath: subPaths.join(".") }; } else appendPath.push(subPaths); return { aliasName: aliasName, appendContent: appendPath.map((path => ({ appendPath: path[0], appendSpec: appendSpec, parentKeyPath: path.join(".") }))), parentKeyPath: subPaths.join(".") }; }; export const checkDuplicatedKey = (parentPath, key) => { let isDuplicated = !1; if (parentPath === key) return { remainKeyPath: "" }; if (/^\d$/.exec(key)) { const indexString = `[${key}]`; if (parentPath.startsWith(indexString) && (isDuplicated = !0, isDuplicated)) return { remainKeyPath: parentPath.substring(indexString.length + 1) }; } if (parentPath.startsWith(`${key}`)) { let remainKeyPath = parentPath.substring(key.length); return "." === remainKeyPath[0] && (remainKeyPath = remainKeyPath.substring(1)), { remainKeyPath: remainKeyPath }; } if (parentPath.includes(`.${key}`)) { const str = `.${key}`; let remainKeyPath = parentPath.substring(parentPath.indexOf(str) + str.length); return "." === remainKeyPath[0] && (remainKeyPath = remainKeyPath.substring(1)), { remainKeyPath: remainKeyPath }; } return null; }; export const reduceDuplicatedPath = (parentPath, spec) => { var _a; if (isPlainObject(spec) && parentPath) { const keys = Object.keys(spec); if (1 === keys.length) { const res = checkDuplicatedKey(parentPath, keys[0]); return res ? reduceDuplicatedPath(res.remainKeyPath, spec[keys[0]]) : spec; } if (keys.length > 1) { const fixedKey = keys.find((k => checkDuplicatedKey(parentPath, k))); if (fixedKey) { const res = checkDuplicatedKey(parentPath, fixedKey); return reduceDuplicatedPath(res.remainKeyPath, spec[fixedKey]); } } } else if (isArray(spec) && parentPath) { const res = /^\[((\d)+)\]/.exec(parentPath); if (res) { const remainPath = parentPath.substring(res[0].length + 1), val = null !== (_a = spec[+res[1]]) && void 0 !== _a ? _a : spec[spec.length - 1]; return remainPath ? reduceDuplicatedPath(remainPath, val) : val; } } return spec; }; export const convertFunctionString = spec => { if (isPlainObject(spec)) { const newSpec = {}; return Object.keys(spec).forEach((key => { newSpec[key] = convertFunctionString(spec[key]); })), newSpec; } if (isArray(spec)) return spec.map(convertFunctionString); if (isString(spec) && (spec.includes("=>") || spec.includes("function"))) try { return new Function(`return (${spec})`)(); } catch (e) { return spec; } return spec; }; export const updateSpecByOperation = (prevSpec, op) => { const newSpec = merge({}, prevSpec); let parentKeyPath = op.target, updatedKeyPaths = null, leafSpec = op.value; const aliasName = parentKeyPath.split(".")[0].replace(/\[\d\]/, ""), compKey = findComponentNameByAlias(aliasName); if (compKey.startsWith("series") && "common" !== newSpec.type && !newSpec.series) leafSpec = removeUnneedArrayInSpec(op.value, "series", op.target), parentKeyPath = parentKeyPath.indexOf(".") > 0 ? parentKeyPath.slice(parentKeyPath.indexOf(".") + 1) : ""; else { const aliasResult = parseAliasOfPath(parentKeyPath, compKey, newSpec, leafSpec, op.op); aliasResult.appendContent && (aliasResult.appendContent.forEach((entry => { set(newSpec, entry.appendPath, entry.appendSpec); })), aliasResult.appendContent.length && (updatedKeyPaths = aliasResult.appendContent.map((entry => entry.parentKeyPath)))), isValid(aliasResult.parentKeyPath) && (parentKeyPath = aliasResult.parentKeyPath), isValid(aliasResult.leafSpec) && (leafSpec = aliasResult.leafSpec), leafSpec = convertFunctionString(leafSpec); } return "add" === op.op || "update" === op.op ? (null != updatedKeyPaths ? updatedKeyPaths : [ parentKeyPath ]).forEach((kp => { kp ? set(newSpec, kp, leafSpec) : merge(newSpec, leafSpec); })) : "delete" === op.op ? (null != updatedKeyPaths ? updatedKeyPaths : [ parentKeyPath ]).forEach((kp => { kp && deleteByPath(newSpec, kp); })) : "deleteAll" === op.op && (null != updatedKeyPaths ? updatedKeyPaths : [ parentKeyPath ]).forEach((kp => { kp && deleteByPath(newSpec, kp.replace(/(\[(\d+)\])$/, "")); })), { newSpec: newSpec, code: 0 }; }; export const runOperactionsOfSpec = (prevSpec, ops) => { let spec = prevSpec; const codes = []; return ops.forEach((op => { const res = updateSpecByOperation(spec, op); spec = res.newSpec, codes.push(res.code); })), { spec: spec, codes: codes }; }; //# sourceMappingURL=utils.js.map