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

271 lines (255 loc) 11.7 kB
import { array, isArray, isString, merge, uniqArray } from "@visactor/vutils"; import { ChartType } from "../types"; import { getFieldInfoFromDataset } from "./field"; import { COLOR_FIELD, FOLD_NAME, FOLD_VALUE, FOLD_VALUE_MAIN, FOLD_VALUE_SUB, GROUP_FIELD } from "@visactor/chart-advisor"; import { data, discreteLegend as legend } from "../atom/chartGenerator/spec/transformers/common"; import { funnelData } from "../atom/chartGenerator/spec/transformers/funnel"; import { sankeyData } from "../atom/chartGenerator/spec/transformers/sankey"; import { sequenceData } from "../atom/chartGenerator/spec/transformers/rankingBar"; import { wordCloudData } from "../atom/chartGenerator/spec/transformers/wordcloud"; import { foldDataTableByYField, foldDatasetByYField } from "./dataTable"; export const getChartTypeFromSpec = (spec, vchartType) => { if (!spec) return; const type = null != vchartType ? vchartType : null == spec ? void 0 : spec.type; if ("bar" === type) return ChartType.BarChart; if ("line" === type) return ChartType.LineChart; if ("area" === type) return ChartType.AreaChart; if ("pie" === type) return ChartType.PieChart; if ("wordCloud" === type) return ChartType.WordCloud; if ("scatter" === type) return ChartType.ScatterPlot; if ("funnel" === type) return ChartType.FunnelChart; if ("rose" === type) return ChartType.RoseChart; if ("radar" === type) return ChartType.RadarChart; if ("sankey" === type) return ChartType.SankeyChart; if ("waterfall" === type) return ChartType.WaterFallChart; if ("boxPlot" === type) return ChartType.BoxPlot; if ("common" === type) { const {series: series} = spec; if (1 === uniqArray(series.map((s => s.type))).length) return getChartTypeFromSpec(series[0], vchartType); if (series.length > 1 && series.every((s => "bar" === s.type || "line" === s.type || "area" === s.type))) return ChartType.DualAxisChart; } }; export const getDatasetFromSpec = spec => { if (!spec) return []; return array(spec.data).map((d => d.values)).flat(2); }; export const getFieldMappingFromSpec = spec => { if (!spec) return {}; let res = {}; return array(spec.data).forEach((d => { (null == d ? void 0 : d.fields) && (res = merge(res, d.fields)); })), res; }; export const getCellFromSpec = (spec, vmindChartType) => { var _a, _b, _c, _d; if (!spec) return {}; const {type: type, direction: direction} = spec, isTransposed = "horizontal" === direction; if ("bar" === type && spec.player) { return { time: spec.timeField, x: spec.yField, y: spec.xField, color: spec.seriesField, isTransposed: isTransposed }; } if ([ "bar", "line", "area" ].includes(type)) { return { x: spec.xField, y: spec.yField, color: spec.seriesField, isTransposed: isTransposed }; } if ("radar" === type) return { x: spec.categoryField, y: spec.valueField, color: spec.seriesField }; if ([ "pie", "rose" ].includes(type)) return { x: spec.categoryField, y: spec.valueField, color: spec.categoryField, angle: spec.valueField }; if ("scatter" === type) return { color: spec.seriesField, size: spec.sizeField, x: spec.xField, y: spec.yField }; if ("boxPlot" === type) return { x: spec.xField, y: [ spec.minField, spec.q1Field, spec.medianField, spec.q3Field, spec.maxField ].filter(Boolean) }; if ("common" === type) { if ([ ChartType.BarChart, ChartType.AreaChart, ChartType.LineChart ].includes(vmindChartType)) return { x: uniqArray(spec.series.map((s => s.xField)).filter((xField => !!xField)).flat()), y: uniqArray(spec.series.map((s => s.yField)).filter((yField => !!yField)).flat()), color: spec.series[0].seriesField, isTransposed: isTransposed || spec.series.every((s => "horizontal" === s.direction)) }; const series = null !== (_a = spec.series) && void 0 !== _a ? _a : []; if (vmindChartType === ChartType.DualAxisChart) { const seriesField = uniqArray(series.map((s => null == s ? void 0 : s.seriesField)).filter((v => !!v))); return { x: null === (_b = series[0]) || void 0 === _b ? void 0 : _b.xField, y: uniqArray([ null === (_c = series[0]) || void 0 === _c ? void 0 : _c.yField, null === (_d = series[1]) || void 0 === _d ? void 0 : _d.yField ].filter(Boolean)), color: 1 === (null == seriesField ? void 0 : seriesField.length) ? seriesField[0] : void 0, isTransposed: isTransposed }; } return getCellFromSpec(series[0], vmindChartType); } return "wordCloud" === type ? { color: spec.nameField, size: spec.valueField } : "funnel" === type ? { x: spec.categoryField, y: spec.valueField } : "waterfall" === type ? { x: spec.xField, y: spec.yField, color: null == spec ? void 0 : spec.seriesField } : "sankey" === type ? { source: spec.sourceField, target: spec.targetField, value: spec.valueField } : {}; }; export const revisedCell = (cell, dataset) => { const {color: color} = cell, colorField = isArray(color) ? color[0] : color; if (colorField) { uniqArray(dataset.map((d => d[colorField]))).length <= 1 && (cell.color = void 0); } if (cell.isTransposed) { const temp = cell.x; cell.x = cell.y, cell.y = temp; } return cell; }; const removeInvalidFieldFromCell = (cell, fieldInfo) => { const fieldList = fieldInfo.map((f => f.fieldName)).concat([ FOLD_NAME.toString(), FOLD_VALUE.toString(), FOLD_VALUE_MAIN.toString(), FOLD_VALUE_SUB.toString(), COLOR_FIELD.toString(), GROUP_FIELD.toString() ]), cellNew = Object.assign({}, cell); return Object.keys(cellNew).forEach((key => { const fields = cellNew[key]; if (isArray(fields)) { const filteredFields = fields.filter((field => fieldList.includes(field))); cellNew[key] = 0 === filteredFields.length ? void 0 : filteredFields; } else isString(fields) && (cellNew[key] = fieldList.includes(fields) ? fields : void 0); })), cellNew; }; export const fillSpecTemplateWithData = (template, dataset, propsCell, totalTime) => { const {type: type} = template, fieldInfo = getFieldInfoFromDataset(dataset), tempCell = null != propsCell ? propsCell : getCellFromSpec(template); let cellNew = Object.assign({}, tempCell), datasetNew = dataset; const hasFold = isArray(cellNew.y) ? cellNew.y[0] === FOLD_VALUE.toString() || cellNew.y[0] === FOLD_VALUE_MAIN.toString() && cellNew.y[1] === FOLD_VALUE_SUB.toString() : cellNew.y === FOLD_VALUE.toString(); cellNew = removeInvalidFieldFromCell(cellNew, fieldInfo); const context = { spec: template, dataset: datasetNew, cells: [ cellNew ], totalTime: totalTime }; if ("bar" === type && template.player) { const {spec: spec} = sequenceData(context); return spec; } if ([ "bar", "line" ].includes(type)) { if (hasFold) { const {foldInfo: foldInfo} = cellNew, {foldMap: foldMap} = foldInfo; datasetNew = foldDataTableByYField(datasetNew, Object.keys(foldMap), fieldInfo); } if (cellNew.color === COLOR_FIELD.toString()) { const {cartesianInfo: cartesianInfo} = cellNew, colorFields = cartesianInfo.fieldList; datasetNew = datasetNew.map((data => { const colorItem = colorFields.map((field => data[field])).join("-"); return Object.assign(Object.assign({}, data), { [COLOR_FIELD]: colorItem }); })); } const contextNew = { spec: template, dataset: datasetNew, cells: [ cellNew ], totalTime: totalTime }, {spec: spec1} = data(contextNew), {spec: spec} = legend(Object.assign(Object.assign({}, contextNew), { spec: spec1 })); return spec; } if ([ "pie", "scatter", "rose", "radar", "waterfall", "boxPlot" ].includes(type)) { if (hasFold) { const {foldInfo: foldInfo} = cellNew, {foldMap: foldMap} = foldInfo; datasetNew = foldDatasetByYField(datasetNew, Object.keys(foldMap), fieldInfo); } if (cellNew.color === COLOR_FIELD.toString()) { const {cartesianInfo: cartesianInfo} = cellNew, colorFields = cartesianInfo.fieldList; datasetNew = datasetNew.map((data => { const colorItem = colorFields.map((field => data[field])).join("-"); return Object.assign(Object.assign({}, data), { [COLOR_FIELD]: colorItem }); })); } const contextNew = { spec: template, dataset: datasetNew, cells: [ cellNew ], totalTime: totalTime }, {spec: spec} = data(contextNew); return spec; } if ("common" === type) { let mainSeriesData = datasetNew, subSeriesData = datasetNew; if (hasFold) { const {foldInfo: foldInfo} = cellNew, {foldMap: foldMap} = foldInfo; mainSeriesData = foldDatasetByYField(datasetNew, [ Object.keys(foldMap)[0] ], fieldInfo, FOLD_NAME, FOLD_VALUE_MAIN), subSeriesData = foldDatasetByYField(datasetNew, [ Object.keys(foldMap)[1] ], fieldInfo, FOLD_NAME, FOLD_VALUE_SUB); } const {spec: spec1} = data(context), {spec: finalSpec} = legend(Object.assign(Object.assign({}, context), { spec: spec1 })), {cartesianInfo: cartesianInfo, y: y} = cellNew; if (finalSpec.series && finalSpec.series[0]) { finalSpec.series[0].seriesField = COLOR_FIELD; const colorFields = cartesianInfo ? cartesianInfo.fieldList : void 0; finalSpec.series[0].data = { id: finalSpec.data.id + "_bar", values: mainSeriesData.map((d => { const colorItem = isArray(colorFields) ? colorFields.map((field => d[field])).join("-") : y[0]; return Object.assign(Object.assign({}, d), { [COLOR_FIELD]: colorItem }); })) }; } if (finalSpec.series && finalSpec.series[1]) { finalSpec.series[1].seriesField = COLOR_FIELD; const colorFields = cartesianInfo ? cartesianInfo.fieldList : void 0; finalSpec.series[1].data = { id: finalSpec.data.id + "_line", values: subSeriesData.map((d => { const colorItem = isArray(colorFields) ? colorFields.map((field => d[field])).join("-") : y[1]; return Object.assign(Object.assign({}, d), { [COLOR_FIELD]: colorItem }); })) }; } return finalSpec; } if ("wordCloud" === type) { const {spec: spec} = wordCloudData(context); return spec; } if ("funnel" === type) { const {spec: spec} = funnelData(context); return spec; } if ("sankey" === type) { const {spec: spec} = sankeyData(context); return spec; } const {spec: spec} = data(context); return spec; }; //# sourceMappingURL=spec.js.map