From f10b5b287bf691cecaf8cef641e8cccd44458aeb Mon Sep 17 00:00:00 2001 From: xile611 Date: Thu, 1 Aug 2024 16:52:51 +0800 Subject: [PATCH] fix: use util functions in vutils --- packages/vchart/src/data/transforms/pie.ts | 3 +- packages/vchart/src/util/math.ts | 18 ---- .../vutils-extension/src/spec/clone-deep.ts | 59 ++---------- .../vutils-extension/src/spec/merge-spec.ts | 90 +------------------ 4 files changed, 10 insertions(+), 160 deletions(-) diff --git a/packages/vchart/src/data/transforms/pie.ts b/packages/vchart/src/data/transforms/pie.ts index e1af1f6d3..05c200ef9 100644 --- a/packages/vchart/src/data/transforms/pie.ts +++ b/packages/vchart/src/data/transforms/pie.ts @@ -1,8 +1,9 @@ import type { DataView } from '@visactor/vdataset'; import type { Datum } from '../../typings'; import { couldBeValidNumber } from '../../util/type'; -import { computeQuadrant, getPercentValue } from '../../util/math'; +import { getPercentValue } from '../../util/math'; import { ARC_TRANSFORM_VALUE } from '../../constant/polar'; +import { computeQuadrant } from '@visactor/vutils'; export interface IPieOpt { angleField: string; diff --git a/packages/vchart/src/util/math.ts b/packages/vchart/src/util/math.ts index 56fa6ae43..1a060608b 100644 --- a/packages/vchart/src/util/math.ts +++ b/packages/vchart/src/util/math.ts @@ -18,24 +18,6 @@ import { angleLabelOrientAttribute } from '@visactor/vrender-components'; export const isClose = isNumberClose; export { isGreater, isLess, normalizeAngle, angleLabelOrientAttribute }; -/** - * 根据角度计算象限 - * 计算角度所在象限 - * @param angle - * @returns - */ -export function computeQuadrant(angle: number): Quadrant { - angle = normalizeAngle(angle); - if (angle > 0 && angle <= Math.PI / 2) { - return 2; - } else if (angle > Math.PI / 2 && angle <= Math.PI) { - return 3; - } else if (angle > Math.PI && angle <= (3 * Math.PI) / 2) { - return 4; - } - return 1; -} - /** * 将角度轴起始角度 & 终结角度标准化 * @param start diff --git a/packages/vutils-extension/src/spec/clone-deep.ts b/packages/vutils-extension/src/spec/clone-deep.ts index 35998a9ba..c95337fbd 100644 --- a/packages/vutils-extension/src/spec/clone-deep.ts +++ b/packages/vutils-extension/src/spec/clone-deep.ts @@ -1,61 +1,14 @@ -import { isArray, isBoolean, isDate, isNumber, isString, isValid, isHTMLElement } from '@visactor/vutils'; +import { isHTMLElement, cloneDeep } from '@visactor/vutils'; import { isDataView } from '@visactor/vdataset'; +const ignoreWhen = (value: any) => { + return isDataView(value) || isHTMLElement(value); +}; + /** * 深拷贝 spec,为避免循环引用,DataView 维持原有引用 * @param spec 原spec */ export function cloneDeepSpec(spec: any, excludeKeys: string[] = ['data']) { - const value = spec; - - let result; - if (!isValid(value) || typeof value !== 'object') { - return value; - } - - // 判断是不是不能深拷贝的对象 - if (isDataView(value) || isHTMLElement(value)) { - return value; - } - - const isArr = isArray(value); - const length = value.length; - // 不考虑特殊数组的额外处理 - if (isArr) { - result = new Array(length); - } - // 不考虑 buffer / arguments 类型的处理以及 prototype 的额外处理 - else if (typeof value === 'object') { - result = {}; - } - // 不建议使用作为 Boolean / Number / String 作为构造器 - else if (isBoolean(value) || isNumber(value) || isString(value)) { - result = value; - } else if (isDate(value)) { - result = new Date(+value); - } - // 不考虑 ArrayBuffer / DataView / TypedArray / map / set / regexp / symbol 类型 - else { - result = undefined; - } - - // 不考虑 map / set / TypedArray 类型的赋值 - - // 不考虑对象的 symbol 属性 - const props = isArr ? undefined : Object.keys(Object(value)); - - let index = -1; - if (result) { - while (++index < (props || value).length) { - const key = props ? props[index] : index; - const subValue = value[key]; - if (excludeKeys?.includes(key.toString())) { - result[key] = subValue; - } else { - result[key] = cloneDeepSpec(subValue, excludeKeys); - } - } - } - - return result; + return cloneDeep(spec, ignoreWhen, excludeKeys); } diff --git a/packages/vutils-extension/src/spec/merge-spec.ts b/packages/vutils-extension/src/spec/merge-spec.ts index b7d3a8433..e219eb902 100644 --- a/packages/vutils-extension/src/spec/merge-spec.ts +++ b/packages/vutils-extension/src/spec/merge-spec.ts @@ -1,90 +1,4 @@ -import { isArray, isArrayLike, isObject, isPlainObject, isValid } from '@visactor/vutils'; - -function baseMerge(target: any, source: any, shallowArray = false) { - if (source) { - if (target === source) { - return; - } - if (isValid(source) && typeof source === 'object') { - // baseFor - const iterable = Object(source); - const props = []; - // keysIn - for (const key in iterable) { - props.push(key); - } - let { length } = props; - let propIndex = -1; - while (length--) { - const key = props[++propIndex]; - if ( - isValid(iterable[key]) && - typeof iterable[key] === 'object' && - !isArray(target[key]) // VChart 特有逻辑 - ) { - baseMergeDeep(target, source, key, shallowArray); - } else { - assignMergeValue(target, key, iterable[key]); - } - } - } - } -} - -// 由于目前 VChart 内部对 spec 会先执行一次深拷贝,merge 暂时不考虑 source 中有环的问题 -function baseMergeDeep(target: object, source: object, key: string, shallowArray = false) { - const objValue = target[key]; - const srcValue = source[key]; - let newValue = source[key]; - let isCommon = true; - // 不考虑 buffer / typedArray 类型 - if (isArray(srcValue)) { - if (shallowArray) { - // 依据参数对数组做浅拷贝 - newValue = []; - } else if (isArray(objValue)) { - newValue = objValue; - } else if (isArrayLike(objValue)) { - // 如果 source 为数组,则 target 的 arrayLike 对象也视作为数组处理 - newValue = new Array(objValue.length); - let index = -1; - const length = objValue.length; - while (++index < length) { - newValue[index] = objValue[index]; - } - } - } - // else if (isArray(srcValue) && shallowArray) { - // newValue = []; - // } - // 不考虑 argument 类型 - else if (isPlainObject(srcValue)) { - newValue = objValue ?? {}; - // 不考虑 prototype 的额外处理 - if (typeof objValue === 'function' || typeof objValue !== 'object') { - newValue = {}; - } - } else { - isCommon = false; - } - // 对 class 等复杂对象或者浅拷贝的 array 不做拷贝处理 - if (isCommon) { - baseMerge(newValue, srcValue, shallowArray); - } - assignMergeValue(target, key, newValue); -} - -function assignMergeValue(target: object, key: string, value: any) { - if ((value !== undefined && !eq(target[key], value)) || (value === undefined && !(key in target))) { - // 不考虑 __proto__ 的赋值处理 - target[key] = value; - } -} - -function eq(value: any, other: any) { - return value === other || (Number.isNaN(value) && Number.isNaN(other)); -} - +import { baseMerge, isArray, isObject } from '@visactor/vutils'; /* 与原生的 lodash merge 差异在于对数组是否应用最后一个 source 的结果 * 以及对一些特殊情况的处理,比如对数组类型 padding 和对象类型的 padding 的 merge */ @@ -93,7 +7,7 @@ export function mergeSpec(target: any, ...sources: any[]): any { const length = sources.length; while (++sourceIndex < length) { const source = sources[sourceIndex]; - baseMerge(target, source, true); + baseMerge(target, source, true, true); } return target; }