import { DataItem, LegendOptions, TooltipOptions, Options, GeneralAxisOptions, AxisPointerOptions, AxisPointerCustomOptions, AxisOptions, GridOptions, SeriesOptions, } from '../models'; import { merge } from '../utils/merge'; import { lightTheme, darkTheme } from '../theme/index'; import defaultConfig from '../models/globalDefault'; import { Data } from '../models/graph/base'; import { isNumber, isArray, isObject } from '../utils/type'; import { AxisTypeEnum } from '../constants'; export interface ParsedOptions { grid: GridOptions; axis: { x: AxisOptions; y: AxisOptions[]; }; dataset: Array; series: Array; tooltip: TooltipOptions; legend: LegendOptions; colors: any; axisPointer: AxisPointerOptions; } export default class OptionParser { constructor(private options: Options) {} public parse() { return { grid: this.parseGrid(), axis: this.parseAxis(), dataset: this.parseDataset(), series: this.parseSeries(), tooltip: this.parseTooltip(), legend: this.parseLegend(), colors: this.parseColors(), axisPointer: this.parseAxisPointer(), }; } private parseGrid() { const { grid = {} } = this.options; return grid; } /** * 数据格式约定: * 1.标准数据:{name:'n', value:'v'} * 2.空值数据:{name:'n', value:null} * 3.长度补齐数据:{name:'n', value:null, isFake: true} */ private parseDataset(): Array { const data: Array = []; const { xAxis = {}, series } = this.options; const { data: xAxisData } = xAxis; // venn图的特殊数据格式 const { type, data: vennData } = series[0]; if (type === 'venn') { return [vennData as DataItem[]]; } const seriesData = series.map(item => item.data); if (!xAxisData) { const longestSeriesLength = Math.max(...seriesData.map(item => item.length)); const longestSeries = seriesData.find(item => item.length === longestSeriesLength); const formatData = (dataItems: Array) => { const formattedData = dataItems.map((item, index) => { if (isNumber(item)) { /** * demo: [1, 2, 3, 4, 5] * 说明:表示数据数组,配合xAxis.data横轴数据使用 */ return { name: String(index), value: item as number, }; } if (isArray(item)) { /** * demo: [ * 维度X 维度Y 其他维度 ... * [ "2000-06-05", 116, 15, 43], * [ "2000-07-05", 155, 20, 91], * [ "2000-08-05", 106, 30, 18], * [ "2000-09-05", 150, 18, 57] * ] * 说明:表示二维数据 * TODO:暂时实现单轴数据,后续支持多轴数据 */ return { name: item[0], value: item[1], }; } if (isObject(item)) { /** * demo: [ * { * name: "2000-06-05", * value: 116, * }, * { * name: "2000-07-05", * value: 155, * } * ] * 说明:表示二维数据 */ return { name: (item as DataItem).name, value: (item as DataItem).value, isFake: (item as DataItem).isFake, itemStyle: (item as DataItem).itemStyle, }; } }); return formattedData; }; return seriesData.map((data) => { const rawData = [...data]; /** * seriesData中的数据长度不一致时,补齐数据 * 如:[ * [{name:'2020-05',value:10}], * [{name:'2020-05',value:10},{name:'2020-06',value:11}], * ] * 补齐后:[ * [{name:'2020-05',value:10},{name:'2020-06',value:11, isFake: true}], * [{name:'2020-05',value:10},{name:'2020-06',value:11 }], * ] */ if (rawData.length < longestSeriesLength) { const diffArr = longestSeries.slice(rawData.length, longestSeriesLength); rawData.push(...diffArr.map((item) => { let name = null; if (isNumber(item)) { name = item; } if (isArray(item)) { name = item[0]; } if (isObject(item)) { name = (item as DataItem).name; } return { name, value: null, isFake: true, ...item }; })); } return formatData(rawData as (number | DataItem | [string, number])[]); }); } seriesData.forEach((graphData) => { const newData: DataItem[] = []; xAxisData.forEach((item, index) => { const value = (graphData as number[])[index] || null; newData.push({ name: String(item), value, isFake: true, }); }); data.push(newData); }); return data; } private parseAxis(): GeneralAxisOptions { const { xAxis, yAxis } = this.options; // option.yAxis统一为array格式 const parsedYAxis = Array.isArray(yAxis) ? yAxis : [yAxis]; return { x: xAxis, y: parsedYAxis, }; } private parseTooltip(): TooltipOptions { return this.options.tooltip; } private parseLegend(): LegendOptions { return this.options.legend; } private parseColors() { const { darkMode } = this.options; const defaultColors = defaultConfig.colors; // 默认颜色 const themeColors = darkMode ? darkTheme.colors : lightTheme.colors; // 主题颜色 const { colors } = this.options; // 自定义颜色 return merge(defaultColors, themeColors, colors); } private parseAxisPointer(): AxisPointerOptions & AxisPointerCustomOptions { const { xAxis } = this.options; const xAxisType = xAxis?.type as AxisTypeEnum; const isVertical = xAxisType !== 'value'; return { isVertical, ...this.options.axisPointer, }; } private parseSeries(): Array { const { series } = this.options; return series.map((item, index) => ({ ...item, data: this.parseDataset()[index], })) as Array; } }