202 lines
6.7 KiB
Java
202 lines
6.7 KiB
Java
/**
|
||
* view 中缓存 scale 的类
|
||
*/
|
||
import { deepMix, each, get, isNumber, last } from '@antv/util';
|
||
import { createScaleByField, syncScale } from '../../util/scale';
|
||
/** @ignore */
|
||
var ScalePool = /** @class */ (function () {
|
||
function ScalePool() {
|
||
/** 所有的 scales */
|
||
this.scales = new Map();
|
||
/** 需要同步的 scale 分组, key: scaleKeyArray */
|
||
this.syncScales = new Map();
|
||
}
|
||
/**
|
||
* 创建 scale
|
||
* @param field
|
||
* @param data
|
||
* @param scaleDef
|
||
* @param key
|
||
*/
|
||
ScalePool.prototype.createScale = function (field, data, scaleDef, key) {
|
||
var finalScaleDef = scaleDef;
|
||
var cacheScaleMeta = this.getScaleMeta(key);
|
||
if (data.length === 0 && cacheScaleMeta) {
|
||
// 在更新过程中数据变为空,同时 key 对应的 scale 已存在则保持 scale 同类型
|
||
var cacheScale = cacheScaleMeta.scale;
|
||
var cacheScaleDef = {
|
||
type: cacheScale.type,
|
||
};
|
||
if (cacheScale.isCategory) {
|
||
// 如果是分类类型,保持 values
|
||
cacheScaleDef.values = cacheScale.values;
|
||
}
|
||
finalScaleDef = deepMix(cacheScaleDef, cacheScaleMeta.scaleDef, scaleDef);
|
||
}
|
||
var scale = createScaleByField(field, data, finalScaleDef);
|
||
// 缓存起来
|
||
this.cacheScale(scale, scaleDef, key);
|
||
return scale;
|
||
};
|
||
/**
|
||
* 同步 scale
|
||
*/
|
||
ScalePool.prototype.sync = function () {
|
||
var _this = this;
|
||
// 对于 syncScales 中每一个 syncKey 下面的 scale 数组进行同步处理
|
||
this.syncScales.forEach(function (scaleKeys, syncKey) {
|
||
// min, max, values
|
||
var min = Number.MAX_SAFE_INTEGER;
|
||
var max = Number.MIN_SAFE_INTEGER;
|
||
var values = [];
|
||
// 1. 遍历求得最大最小值,values 等
|
||
each(scaleKeys, function (key) {
|
||
var scale = _this.getScale(key);
|
||
max = isNumber(scale.max) ? Math.max(max, scale.max) : max;
|
||
min = isNumber(scale.min) ? Math.min(min, scale.min) : min;
|
||
// 去重
|
||
each(scale.values, function (v) {
|
||
if (!values.includes(v)) {
|
||
values.push(v);
|
||
}
|
||
});
|
||
});
|
||
// 2. 同步
|
||
each(scaleKeys, function (key) {
|
||
var scale = _this.getScale(key);
|
||
if (scale.isContinuous) {
|
||
scale.change({
|
||
min: min,
|
||
max: max,
|
||
values: values,
|
||
});
|
||
}
|
||
else if (scale.isCategory) {
|
||
scale.change({
|
||
values: values,
|
||
});
|
||
}
|
||
});
|
||
});
|
||
};
|
||
/**
|
||
* 缓存一个 scale
|
||
* @param scale
|
||
* @param scaleDef
|
||
* @param key
|
||
*/
|
||
ScalePool.prototype.cacheScale = function (scale, scaleDef, key) {
|
||
// 1. 缓存到 scales
|
||
var sm = this.getScaleMeta(key);
|
||
// 存在则更新,同时检测类型是否一致
|
||
if (sm && sm.scale.type === scale.type) {
|
||
syncScale(sm.scale, scale);
|
||
sm.scaleDef = scaleDef;
|
||
// 更新 scaleDef
|
||
}
|
||
else {
|
||
sm = {
|
||
key: key,
|
||
scale: scale,
|
||
scaleDef: scaleDef,
|
||
};
|
||
this.scales.set(key, sm);
|
||
}
|
||
// 2. 缓存到 syncScales,构造 Record<sync, string[]> 数据结构
|
||
var syncKey = this.getSyncKey(sm);
|
||
sm.syncKey = syncKey; // 设置 sync 同步的 key
|
||
// 因为存在更新 scale 机制,所以在缓存之前,先从原 syncScales 中去除 sync 的缓存引用
|
||
this.removeFromSyncScales(key);
|
||
// 存在 sync 标记才进行 sync
|
||
if (syncKey) {
|
||
// 不存在这个 syncKey,则创建一个空数组
|
||
var scaleKeys = this.syncScales.get(syncKey);
|
||
if (!scaleKeys) {
|
||
scaleKeys = [];
|
||
this.syncScales.set(syncKey, scaleKeys);
|
||
}
|
||
scaleKeys.push(key);
|
||
}
|
||
};
|
||
/**
|
||
* 通过 key 获取 scale
|
||
* @param key
|
||
*/
|
||
ScalePool.prototype.getScale = function (key) {
|
||
var scaleMeta = this.getScaleMeta(key);
|
||
if (!scaleMeta) {
|
||
var field = last(key.split('-'));
|
||
var scaleKeys = this.syncScales.get(field);
|
||
if (scaleKeys && scaleKeys.length) {
|
||
scaleMeta = this.getScaleMeta(scaleKeys[0]);
|
||
}
|
||
}
|
||
return scaleMeta && scaleMeta.scale;
|
||
};
|
||
/**
|
||
* 在 view 销毁的时候,删除 scale 实例,防止内存泄露
|
||
* @param key
|
||
*/
|
||
ScalePool.prototype.deleteScale = function (key) {
|
||
var scaleMeta = this.getScaleMeta(key);
|
||
if (scaleMeta) {
|
||
var syncKey = scaleMeta.syncKey;
|
||
var scaleKeys = this.syncScales.get(syncKey);
|
||
// 移除同步的关系
|
||
if (scaleKeys && scaleKeys.length) {
|
||
var idx = scaleKeys.indexOf(key);
|
||
if (idx !== -1) {
|
||
scaleKeys.splice(idx, 1);
|
||
}
|
||
}
|
||
}
|
||
// 删除 scale 实例
|
||
this.scales.delete(key);
|
||
};
|
||
/**
|
||
* 清空
|
||
*/
|
||
ScalePool.prototype.clear = function () {
|
||
this.scales.clear();
|
||
this.syncScales.clear();
|
||
};
|
||
/**
|
||
* 删除 sync scale 引用
|
||
* @param key
|
||
*/
|
||
ScalePool.prototype.removeFromSyncScales = function (key) {
|
||
var _this = this;
|
||
this.syncScales.forEach(function (scaleKeys, syncKey) {
|
||
var idx = scaleKeys.indexOf(key);
|
||
if (idx !== -1) {
|
||
scaleKeys.splice(idx, 1);
|
||
// 删除空数组值
|
||
if (scaleKeys.length === 0) {
|
||
_this.syncScales.delete(syncKey);
|
||
}
|
||
return false; // 跳出循环
|
||
}
|
||
});
|
||
};
|
||
/**
|
||
* get sync key
|
||
* @param sm
|
||
*/
|
||
ScalePool.prototype.getSyncKey = function (sm) {
|
||
var scale = sm.scale, scaleDef = sm.scaleDef;
|
||
var field = scale.field;
|
||
var sync = get(scaleDef, ['sync']);
|
||
// 如果 sync = true,则直接使用字段名作为 syncKey
|
||
return sync === true ? field : sync === false ? undefined : sync;
|
||
};
|
||
/**
|
||
* 通过 key 获取 scale
|
||
* @param key
|
||
*/
|
||
ScalePool.prototype.getScaleMeta = function (key) {
|
||
return this.scales.get(key);
|
||
};
|
||
return ScalePool;
|
||
}());
|
||
export { ScalePool };
|
||
//# sourceMappingURL=scale-pool.js.map |