UNPKG

7.47 kBJavaScriptView Raw
1/**
2 * view 中缓存 scale 的类
3 */
4import { deepMix, each, get, isNumber, last } from '@antv/util';
5import { createScaleByField, syncScale, getDefaultCategoryScaleRange } from '../../util/scale';
6/** @ignore */
7var ScalePool = /** @class */ (function () {
8 function ScalePool() {
9 /** 所有的 scales */
10 this.scales = new Map();
11 /** 需要同步的 scale 分组, key: scaleKeyArray */
12 this.syncScales = new Map();
13 }
14 /**
15 * 创建 scale
16 * @param field
17 * @param data
18 * @param scaleDef
19 * @param key
20 */
21 ScalePool.prototype.createScale = function (field, data, scaleDef, key) {
22 var finalScaleDef = scaleDef;
23 var cacheScaleMeta = this.getScaleMeta(key);
24 if (data.length === 0 && cacheScaleMeta) {
25 // 在更新过程中数据变为空,同时 key 对应的 scale 已存在则保持 scale 同类型
26 var cacheScale = cacheScaleMeta.scale;
27 var cacheScaleDef = {
28 type: cacheScale.type,
29 };
30 if (cacheScale.isCategory) {
31 // 如果是分类类型,保持 values
32 cacheScaleDef.values = cacheScale.values;
33 }
34 finalScaleDef = deepMix(cacheScaleDef, cacheScaleMeta.scaleDef, scaleDef);
35 }
36 var scale = createScaleByField(field, data, finalScaleDef);
37 // 缓存起来
38 this.cacheScale(scale, scaleDef, key);
39 return scale;
40 };
41 /**
42 * 同步 scale
43 */
44 ScalePool.prototype.sync = function (coordinate, theme) {
45 var _this = this;
46 // 对于 syncScales 中每一个 syncKey 下面的 scale 数组进行同步处理
47 this.syncScales.forEach(function (scaleKeys, syncKey) {
48 // min, max, values, ranges
49 var min = Number.MAX_SAFE_INTEGER;
50 var max = Number.MIN_SAFE_INTEGER;
51 var values = [];
52 // 1. 遍历求得最大最小值,values 等
53 each(scaleKeys, function (key) {
54 var scale = _this.getScale(key);
55 max = isNumber(scale.max) ? Math.max(max, scale.max) : max;
56 min = isNumber(scale.min) ? Math.min(min, scale.min) : min;
57 // 去重
58 each(scale.values, function (v) {
59 if (!values.includes(v)) {
60 values.push(v);
61 }
62 });
63 });
64 // 2. 同步
65 each(scaleKeys, function (key) {
66 var scale = _this.getScale(key);
67 if (scale.isContinuous) {
68 scale.change({
69 min: min,
70 max: max,
71 values: values,
72 });
73 }
74 else if (scale.isCategory) {
75 var range = scale.range;
76 var cacheScaleMeta = _this.getScaleMeta(key);
77 // 存在 value 值,且用户没有配置 range 配置 to fix https://github.com/antvis/G2/issues/2996
78 if (values && !get(cacheScaleMeta, ['scaleDef', 'range'])) {
79 // 更新 range
80 range = getDefaultCategoryScaleRange(deepMix({}, scale, {
81 values: values,
82 }), coordinate, theme);
83 }
84 scale.change({
85 values: values,
86 range: range,
87 });
88 }
89 });
90 });
91 };
92 /**
93 * 缓存一个 scale
94 * @param scale
95 * @param scaleDef
96 * @param key
97 */
98 ScalePool.prototype.cacheScale = function (scale, scaleDef, key) {
99 // 1. 缓存到 scales
100 var sm = this.getScaleMeta(key);
101 // 存在则更新,同时检测类型是否一致
102 if (sm && sm.scale.type === scale.type) {
103 syncScale(sm.scale, scale);
104 sm.scaleDef = scaleDef;
105 // 更新 scaleDef
106 }
107 else {
108 sm = {
109 key: key,
110 scale: scale,
111 scaleDef: scaleDef,
112 };
113 this.scales.set(key, sm);
114 }
115 // 2. 缓存到 syncScales,构造 Record<sync, string[]> 数据结构
116 var syncKey = this.getSyncKey(sm);
117 sm.syncKey = syncKey; // 设置 sync 同步的 key
118 // 因为存在更新 scale 机制,所以在缓存之前,先从原 syncScales 中去除 sync 的缓存引用
119 this.removeFromSyncScales(key);
120 // 存在 sync 标记才进行 sync
121 if (syncKey) {
122 // 不存在这个 syncKey,则创建一个空数组
123 var scaleKeys = this.syncScales.get(syncKey);
124 if (!scaleKeys) {
125 scaleKeys = [];
126 this.syncScales.set(syncKey, scaleKeys);
127 }
128 scaleKeys.push(key);
129 }
130 };
131 /**
132 * 通过 key 获取 scale
133 * @param key
134 */
135 ScalePool.prototype.getScale = function (key) {
136 var scaleMeta = this.getScaleMeta(key);
137 if (!scaleMeta) {
138 var field = last(key.split('-'));
139 var scaleKeys = this.syncScales.get(field);
140 if (scaleKeys && scaleKeys.length) {
141 scaleMeta = this.getScaleMeta(scaleKeys[0]);
142 }
143 }
144 return scaleMeta && scaleMeta.scale;
145 };
146 /**
147 * 在 view 销毁的时候,删除 scale 实例,防止内存泄露
148 * @param key
149 */
150 ScalePool.prototype.deleteScale = function (key) {
151 var scaleMeta = this.getScaleMeta(key);
152 if (scaleMeta) {
153 var syncKey = scaleMeta.syncKey;
154 var scaleKeys = this.syncScales.get(syncKey);
155 // 移除同步的关系
156 if (scaleKeys && scaleKeys.length) {
157 var idx = scaleKeys.indexOf(key);
158 if (idx !== -1) {
159 scaleKeys.splice(idx, 1);
160 }
161 }
162 }
163 // 删除 scale 实例
164 this.scales.delete(key);
165 };
166 /**
167 * 清空
168 */
169 ScalePool.prototype.clear = function () {
170 this.scales.clear();
171 this.syncScales.clear();
172 };
173 /**
174 * 删除 sync scale 引用
175 * @param key
176 */
177 ScalePool.prototype.removeFromSyncScales = function (key) {
178 var _this = this;
179 this.syncScales.forEach(function (scaleKeys, syncKey) {
180 var idx = scaleKeys.indexOf(key);
181 if (idx !== -1) {
182 scaleKeys.splice(idx, 1);
183 // 删除空数组值
184 if (scaleKeys.length === 0) {
185 _this.syncScales.delete(syncKey);
186 }
187 return false; // 跳出循环
188 }
189 });
190 };
191 /**
192 * get sync key
193 * @param sm
194 */
195 ScalePool.prototype.getSyncKey = function (sm) {
196 var scale = sm.scale, scaleDef = sm.scaleDef;
197 var field = scale.field;
198 var sync = get(scaleDef, ['sync']);
199 // 如果 sync = true,则直接使用字段名作为 syncKey
200 return sync === true ? field : sync === false ? undefined : sync;
201 };
202 /**
203 * 通过 key 获取 scale
204 * @param key
205 */
206 ScalePool.prototype.getScaleMeta = function (key) {
207 return this.scales.get(key);
208 };
209 return ScalePool;
210}());
211export { ScalePool };
212//# sourceMappingURL=scale-pool.js.map
\No newline at end of file