UNPKG

wangbd-myui

Version:

MY前端基础框架核心组件库

203 lines (181 loc) 6.52 kB
import isObject from 'lodash/isObject' /** * 构造 source 数据表格 * @param {Object[]} standardColumns 标准列配置 * @param {Array[]|Object[]} rows 行数据 * @param {object} settings 配置 * @return {Array} 二维数组 */ function createSource(standardColumns = [], rows = [], settings = {}) { // 构造二维数据表头 const headerRow = standardColumns.map(col => (col.displayName || col.name)) // 初始化资源数据 const source = headerRow.length ? [headerRow] : [] // 找到需要做数据转换的列索引 const indexes = getNeedTransformColumnIndexes(standardColumns) // 列数据 const dataRows = [] // 把行数据填充到二维数据表 rows.forEach(row => { const newRow = Array.isArray(row) ? row : standardColumns.map(col => { return row[col.name] }) // 转换数据 transformData(standardColumns, indexes, newRow) dataRows.push(newRow) }) // 找到第一个设置了排序的列 const sortColumnIndex = standardColumns.findIndex(col => !!col.sort) // 如果有设置排序,对数据进行从大到小排序 if (sortColumnIndex >= 0) { const col = standardColumns[sortColumnIndex] // 要判断类别所在的轴,横和竖的排序方式不同 const dir = settings.direction const sortType = typeof col.sort === 'string' ? col.sort : (dir === 'x' ? 'asc' : 'desc') dataRows.sort((first, second) => { return sortType === 'asc' ? second[sortColumnIndex] - first[sortColumnIndex] : first[sortColumnIndex] - second[sortColumnIndex] }) } return source.concat(dataRows) } /** * 获取需要进行数据格式转换列的索引 * @param {Object[]} standardColumns 标准列配置 * @return {*} */ function getNeedTransformColumnIndexes(standardColumns) { const indexes = [] standardColumns.forEach((col, index) => { if (col.unit || col.precision >= 0) { indexes.push(index) } }) return indexes } /** * 对行数据进行数据转换 * @param {Object[]} standardColumns 标准列配置 * @param {number[]} indexes 需要转换列的索引 * @param {*} row 数据行 */ function transformData(standardColumns, indexes, row) { indexes.forEach(index => { const column = standardColumns[index] let value = row[index] const unit = column.unit || 'n' const precision = column.precision || 0 switch (unit.toLowerCase()) { case 'k': value = value / 1000 break; case 'w': value = value / 10000 break; case 'p': value = value * 100 break; } row[index] = formatValue(value, precision) }) } /** * 保留几位小数 * @param {number} value 原始值 * @param {number} precision 精度 * @return {number} */ function formatValue(value, precision) { return Number.parseFloat(value.toFixed(precision)) } /** * 构造 维度 dimensions * @param {string} layout 用行还是列对应到系列上,即 echarts 的配置seriesLayoutBy, 可选:column | row ,默认:column * @param {Object[]} standardColumns 标准列配置 * @param {Array[]} source 二维数据表 * @return {Object[]} */ function createDimensions(layout, standardColumns, source) { return layout === 'column' ? standardColumns : source.map(row => row[0]) } /** * 构建限制类目数的行数据 * @param standardColumns 标准列 * @param rows 行数据 * @param limit 限制条数 * @return {*} */ function getLimitRows(standardColumns, rows, limit) { if (!limit || rows.length <= limit || !standardColumns[1]) { return rows } const valueColumn = standardColumns[1] const columnName = valueColumn.name // 按维度从大到小排序 rows.sort((first, second) => { // 纬度值取默认第二列 const firstValue = Array.isArray(first) ? first[1] : first[columnName] const secondValue = Array.isArray(second) ? second[1] : second[columnName] return secondValue - firstValue }) // 计算需要合并到其他类目的值总和 const otherTotal = rows.filter((n, index) => index >= limit).reduce((total, item) => { return total + (Array.isArray(item) ? item[1] : item[columnName]) }, 0) const other = ['其他', otherTotal] const limitRows = rows.slice(0, limit) limitRows.push(other) return limitRows } /** * 把用户的列配置转换成标准的配置格式 * @param {string|object[]} columns * @return {*} * * @example * * 用户的配置有以下格式 * 1、数据项是字符串,如:['月份', '销量'] * 2、数据项是对象形式,如: * [ * {name:'month',displayName:'月份'}, * {name:'value', displayName:'销量', type:'int', unit:'k', precision:0, sort:true|asc|desc} * ] * 其中 name、displayName、type是echarts自带功能, unit、precision 是自扩展功能 * type 表示数据类型,通常不需要设置,echarts 会自动识别,可选值:number | ordinal | float | float | time * unit 表示转换数据单位,需要对数据进行转换时设置,可选值:k(千) | w(万) | p(百分比) * precision 转换数据精度,保留几位小数,默认:0 * sort 排序,从大到小 * * 该函数的作用是统一把用户配置都转换成标准的对象配置形式 */ export function columnsToStandard({columns = []}) { return columns.map(col => { return isObject(col) ? col : {name: col} }) } /** * 构造 dataset * @param {Object[]} standardColumns 标准列配置 * @param {string} id * @param {string[]|Object[]} columns 列配置 * @param {array[]|object[]} rows 行数据 * @param {string} layout 用行还是列对应到系列上,即 echarts 的配置seriesLayoutBy, 可选:column | row ,默认:column * @param {boolean} header 数据是否包含列头,默认echarts自动判断 * @param {object} settings 配置 * @return {Object} */ export function createDataset(standardColumns, {id, rows, layout = 'column', header}, settings) { const limitRows = getLimitRows(standardColumns, rows, settings.limit) const source = createSource(standardColumns, limitRows, settings) const dimensions = createDimensions(layout, standardColumns, source) return { id: id, dimensions: dimensions, source: source, sourceHeader: header } }