UNPKG

54.7 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3var tslib_1 = require("tslib");
4var adjust_1 = require("@antv/adjust");
5var attr_1 = require("@antv/attr");
6var util_1 = require("@antv/util");
7var animate_1 = require("../animate");
8var base_1 = tslib_1.__importDefault(require("../base"));
9var constant_1 = require("../constant");
10var helper_1 = require("../util/helper");
11var element_1 = tslib_1.__importDefault(require("./element"));
12var label_1 = require("./label");
13var base_2 = require("./shape/base");
14var group_data_1 = require("./util/group-data");
15var is_model_change_1 = require("./util/is-model-change");
16var parse_fields_1 = require("./util/parse-fields");
17var coordinate_1 = require("../util/coordinate");
18// 根据 elementId 查找对应的 label,因为有可能一个 element 对应多个 labels,所以在给 labels 打标识时做了处理
19// 打标规则详见 ./label/base.ts#L263
20function filterLabelsById(id, labelsMap) {
21 var labels = [];
22 util_1.each(labelsMap, function (label, labelId) {
23 var elementId = labelId.split(' ')[0];
24 if (elementId === id) {
25 labels.push(label);
26 }
27 });
28 return labels;
29}
30/**
31 * Geometry 几何标记基类,主要负责数据到图形属性的映射以及绘制逻辑。
32 */
33var Geometry = /** @class */ (function (_super) {
34 tslib_1.__extends(Geometry, _super);
35 /**
36 * 创建 Geometry 实例。
37 * @param cfg
38 */
39 function Geometry(cfg) {
40 var _this = _super.call(this, cfg) || this;
41 /** Geometry 几何标记类型。 */
42 _this.type = 'base';
43 // 内部产生的属性
44 /** Attribute map */
45 _this.attributes = {};
46 /** Element map */
47 _this.elements = [];
48 /** 使用 key-value 结构存储 Element,key 为每个 Element 实例对应的唯一 ID */
49 _this.elementsMap = {};
50 /** animate 配置项 */
51 _this.animateOption = true;
52 /** 图形属性映射配置 */
53 _this.attributeOption = {};
54 /** 存储上一次渲染时的 element 映射表,用于更新逻辑 */
55 _this.lastElementsMap = {};
56 /** 是否生成多个点来绘制图形。 */
57 _this.generatePoints = false;
58 /** 存储发生图形属性映射前的数据 */
59 _this.beforeMappingData = null;
60 _this.adjusts = {};
61 _this.idFields = [];
62 _this.hasSorted = false;
63 _this.isCoordinateChanged = false;
64 var container = cfg.container, labelsContainer = cfg.labelsContainer, coordinate = cfg.coordinate, data = cfg.data, _a = cfg.sortable, sortable = _a === void 0 ? false : _a, _b = cfg.visible, visible = _b === void 0 ? true : _b, theme = cfg.theme, _c = cfg.scales, scales = _c === void 0 ? {} : _c, _d = cfg.scaleDefs, scaleDefs = _d === void 0 ? {} : _d,
65 // 柱状图间隔与宽度相关配置
66 intervalPadding = cfg.intervalPadding, dodgePadding = cfg.dodgePadding, maxColumnWidth = cfg.maxColumnWidth, minColumnWidth = cfg.minColumnWidth, columnWidthRatio = cfg.columnWidthRatio, roseWidthRatio = cfg.roseWidthRatio, multiplePieWidthRatio = cfg.multiplePieWidthRatio, zIndexReversed = cfg.zIndexReversed;
67 _this.container = container;
68 _this.labelsContainer = labelsContainer;
69 _this.coordinate = coordinate;
70 _this.data = data;
71 _this.sortable = sortable;
72 _this.visible = visible;
73 _this.userTheme = theme;
74 _this.scales = scales;
75 _this.scaleDefs = scaleDefs;
76 // 柱状图间隔与宽度相关配置
77 _this.intervalPadding = intervalPadding;
78 _this.dodgePadding = dodgePadding;
79 _this.maxColumnWidth = maxColumnWidth;
80 _this.minColumnWidth = minColumnWidth;
81 _this.columnWidthRatio = columnWidthRatio;
82 _this.roseWidthRatio = roseWidthRatio;
83 _this.multiplePieWidthRatio = multiplePieWidthRatio;
84 _this.zIndexReversed = zIndexReversed;
85 return _this;
86 }
87 /**
88 * 配置 position 通道映射规则。
89 *
90 * @example
91 * ```typescript
92 * // 数据结构: [{ x: 'A', y: 10, color: 'red' }]
93 * geometry.position('x*y');
94 * geometry.position([ 'x', 'y' ]);
95 * geometry.position({
96 * fields: [ 'x', 'y' ],
97 * });
98 * ```
99 *
100 * @param cfg 映射规则
101 * @returns
102 */
103 Geometry.prototype.position = function (cfg) {
104 var positionCfg = cfg;
105 if (!util_1.isPlainObject(cfg)) {
106 // 字符串字段或者数组字段
107 positionCfg = {
108 fields: parse_fields_1.parseFields(cfg),
109 };
110 }
111 var fields = util_1.get(positionCfg, 'fields');
112 if (fields.length === 1) {
113 // 默认填充一维 1*xx
114 fields.unshift('1');
115 util_1.set(positionCfg, 'fields', fields);
116 }
117 util_1.set(this.attributeOption, 'position', positionCfg);
118 return this;
119 };
120 Geometry.prototype.color = function (field, cfg) {
121 this.createAttrOption('color', field, cfg);
122 return this;
123 };
124 Geometry.prototype.shape = function (field, cfg) {
125 this.createAttrOption('shape', field, cfg);
126 return this;
127 };
128 Geometry.prototype.size = function (field, cfg) {
129 this.createAttrOption('size', field, cfg);
130 return this;
131 };
132 /**
133 * 设置数据调整方式。G2 目前内置了四种类型:
134 * 1. dodge
135 * 2. stack
136 * 3. symmetric
137 * 4. jitter
138 *
139 *
140 * **Tip**
141 * + 对于 'dodge' 类型,可以额外进行如下属性的配置:
142 * ```typescript
143 * geometry.adjust('dodge', {
144 * marginRatio: 0, // 取 0 到 1 范围的值(相对于每个柱子宽度),用于控制一个分组中柱子之间的间距
145 * dodgeBy: 'x', // 该属性只对 'dodge' 类型生效,声明以哪个数据字段为分组依据
146 * });
147 * ```
148 *
149 * + 对于 'stack' 类型,可以额外进行如下属性的配置:
150 * ```typescript
151 * geometry.adjust('stack', {
152 * reverseOrder: false, // 用于控制是否对数据进行反序操作
153 * });
154 * ```
155 *
156 * @example
157 * ```typescript
158 * geometry.adjust('stack');
159 *
160 * geometry.adjust({
161 * type: 'stack',
162 * reverseOrder: false,
163 * });
164 *
165 * // 组合使用 adjust
166 * geometry.adjust([ 'stack', 'dodge' ]);
167 *
168 * geometry.adjust([
169 * { type: 'stack' },
170 * { type: 'dodge', dodgeBy: 'x' },
171 * ]);
172 * ```
173 *
174 * @param adjustCfg 数据调整配置
175 * @returns
176 */
177 Geometry.prototype.adjust = function (adjustCfg) {
178 var adjusts = adjustCfg;
179 if (util_1.isString(adjustCfg) || util_1.isPlainObject(adjustCfg)) {
180 adjusts = [adjustCfg];
181 }
182 util_1.each(adjusts, function (adjust, index) {
183 if (!util_1.isObject(adjust)) {
184 adjusts[index] = { type: adjust };
185 }
186 });
187 this.adjustOption = adjusts;
188 return this;
189 };
190 Geometry.prototype.style = function (field, styleFunc) {
191 if (util_1.isString(field)) {
192 var fields = parse_fields_1.parseFields(field);
193 this.styleOption = {
194 fields: fields,
195 callback: styleFunc,
196 };
197 }
198 else {
199 var _a = field, fields = _a.fields, callback = _a.callback, cfg = _a.cfg;
200 if (fields || callback || cfg) {
201 this.styleOption = field;
202 }
203 else {
204 this.styleOption = {
205 cfg: field,
206 };
207 }
208 }
209 return this;
210 };
211 Geometry.prototype.tooltip = function (field, cfg) {
212 if (util_1.isString(field)) {
213 var fields = parse_fields_1.parseFields(field);
214 this.tooltipOption = {
215 fields: fields,
216 callback: cfg,
217 };
218 }
219 else {
220 this.tooltipOption = field;
221 }
222 return this;
223 };
224 /**
225 * Geometry 动画配置。
226 *
227 * + `animate(false)` 关闭动画
228 * + `animate(true)` 开启动画,默认开启。
229 *
230 * 我们将动画分为四个场景:
231 * 1. appear: 图表第一次加载时的入场动画;
232 * 2. enter: 图表绘制完成,发生更新后,产生的新图形的进场动画;
233 * 3. update: 图表绘制完成,数据发生变更后,有状态变更的图形的更新动画;
234 * 4. leave: 图表绘制完成,数据发生变更后,被销毁图形的销毁动画。
235 *
236 * @example
237 * ```typescript
238 * animate({
239 * enter: {
240 * duration: 1000, // enter 动画执行时间
241 * },
242 * leave: false, // 关闭 leave 销毁动画
243 * });
244 * ```
245 *
246 * @param cfg 动画配置
247 * @returns
248 */
249 Geometry.prototype.animate = function (cfg) {
250 this.animateOption = cfg;
251 return this;
252 };
253 Geometry.prototype.label = function (field, secondParam, thirdParam) {
254 if (util_1.isString(field)) {
255 var labelOption = {};
256 var fields = parse_fields_1.parseFields(field);
257 labelOption.fields = fields;
258 if (util_1.isFunction(secondParam)) {
259 labelOption.callback = secondParam;
260 }
261 else if (util_1.isPlainObject(secondParam)) {
262 labelOption.cfg = secondParam;
263 }
264 if (thirdParam) {
265 labelOption.cfg = thirdParam;
266 }
267 this.labelOption = labelOption;
268 }
269 else {
270 this.labelOption = field;
271 }
272 return this;
273 };
274 /**
275 * 设置状态对应的样式。
276 *
277 * @example
278 * ```ts
279 * chart.interval().state({
280 * selected: {
281 * animate: { duration: 100, easing: 'easeLinear' },
282 * style: {
283 * lineWidth: 2,
284 * stroke: '#000',
285 * },
286 * },
287 * });
288 * ```
289 *
290 * 如果图形 shape 是由多个 shape 组成,即为一个 G.Group 对象,那么针对 group 中的每个 shape,我们需要使用下列方式进行状态样式设置:
291 * 如果我们为 group 中的每个 shape 设置了 'name' 属性(shape.set('name', 'xx')),则以 'name' 作为 key,否则默认以索引值(即 shape 的 添加顺序)为 key。
292 *
293 * ```ts
294 * chart.interval().shape('groupShape').state({
295 * selected: {
296 * style: {
297 * 0: { lineWidth: 2 },
298 * 1: { fillOpacity: 1 },
299 * }
300 * }
301 * });
302 * ```
303 *
304 * @param cfg 状态样式
305 */
306 Geometry.prototype.state = function (cfg) {
307 this.stateOption = cfg;
308 return this;
309 };
310 /**
311 * 用于向 shape 中传入自定义的数据。目前可能仅仅可能用于在自定义 shape 的时候,像自定义 shape 中传入自定义的数据,方便实现自定义 shape 的配置能力。
312 *
313 * @example
314 * ```ts
315 * chart.interval().customInfo({ yourData: 'hello, g2!' });
316 * ```
317 *
318 * 然后在自定义 shape 的时候,可以拿到这个信息。
319 *
320 * ```ts
321 * registerShape('interval', 'your-shape', {
322 * draw(shapeInfo, container) {
323 * const { customInfo } = shapeInfo;
324 * console.log(customInfo); // will log { yourData: 'hello, g2!' }.
325 * }
326 * });
327 * ```
328 *
329 * @param cfg
330 */
331 Geometry.prototype.customInfo = function (cfg) {
332 this.customOption = cfg;
333 return this;
334 };
335 /**
336 * 初始化 Geomtry 实例:
337 * 创建 [[Attribute]] and [[Scale]] 实例,进行数据处理,包括分组、数值化以及数据调整。
338 */
339 Geometry.prototype.init = function (cfg) {
340 if (cfg === void 0) { cfg = {}; }
341 this.setCfg(cfg);
342 this.initAttributes(); // 创建图形属性
343 // 数据加工:分组 -> 数字化 -> adjust
344 this.processData(this.data);
345 // 调整 scale
346 this.adjustScale();
347 };
348 /**
349 * Geometry 更新。
350 * @param [cfg] 更新的配置
351 */
352 Geometry.prototype.update = function (cfg) {
353 if (cfg === void 0) { cfg = {}; }
354 var data = cfg.data, isDataChanged = cfg.isDataChanged, isCoordinateChanged = cfg.isCoordinateChanged;
355 var _a = this, attributeOption = _a.attributeOption, lastAttributeOption = _a.lastAttributeOption;
356 if (!util_1.isEqual(attributeOption, lastAttributeOption)) {
357 // 映射发生改变,则重新创建图形属性
358 this.init(cfg);
359 }
360 else if (data && (isDataChanged || !util_1.isEqual(data, this.data))) {
361 // 数据发生变化
362 this.setCfg(cfg);
363 this.initAttributes(); // 创建图形属性
364 this.processData(data); // 数据加工:分组 -> 数字化 -> adjust
365 }
366 else {
367 // 有可能 coordinate 变化
368 this.setCfg(cfg);
369 }
370 // 调整 scale
371 this.adjustScale();
372 this.isCoordinateChanged = isCoordinateChanged;
373 };
374 /**
375 * 将原始数据映射至图形空间,同时创建图形对象。
376 */
377 Geometry.prototype.paint = function (isUpdate) {
378 var _this = this;
379 if (isUpdate === void 0) { isUpdate = false; }
380 if (this.animateOption) {
381 this.animateOption = util_1.deepMix({}, animate_1.getDefaultAnimateCfg(this.type, this.coordinate), this.animateOption);
382 }
383 this.defaultSize = undefined;
384 this.elements = [];
385 this.elementsMap = {};
386 var offscreenGroup = this.getOffscreenGroup();
387 offscreenGroup.clear();
388 var beforeMappingData = this.beforeMappingData;
389 var dataArray = this.beforeMapping(beforeMappingData);
390 var mappingArray = [];
391 for (var index = 0, length_1 = dataArray.length; index < length_1; index++) {
392 var eachGroup = dataArray[index];
393 var mappingData = this.mapping(eachGroup);
394 mappingArray.push(mappingData);
395 this.createElements(mappingData, index, isUpdate);
396 }
397 if (this.canDoGroupAnimation(isUpdate)) {
398 // 如果用户没有配置 appear.animation,就默认走整体动画
399 var container = this.container;
400 var type = this.type;
401 var coordinate = this.coordinate;
402 var animateCfg = util_1.get(this.animateOption, 'appear');
403 var yScale = this.getYScale();
404 var yMinPoint = coordinate.convert({
405 x: 0,
406 y: yScale.scale(this.getYMinValue()),
407 });
408 animate_1.doGroupAppearAnimate(container, animateCfg, type, coordinate, yMinPoint);
409 }
410 // 添加 label
411 if (this.labelOption) {
412 this.renderLabels(util_1.flatten(mappingArray), isUpdate);
413 }
414 this.dataArray = mappingArray;
415 // 销毁被删除的 elements
416 util_1.each(this.lastElementsMap, function (deletedElement) {
417 // 更新动画配置,用户有可能在更新之前有对动画进行配置操作
418 deletedElement.animate = _this.animateOption;
419 deletedElement.destroy();
420 });
421 this.lastElementsMap = this.elementsMap;
422 // 缓存,用于更新
423 this.lastAttributeOption = tslib_1.__assign({}, this.attributeOption);
424 if (this.visible === false) {
425 // 用户在初始化的时候声明 visible: false
426 this.changeVisible(false);
427 }
428 };
429 /**
430 * 清空当前 Geometry,配置项仍保留,但是内部创建的对象全部清空。
431 * @override
432 */
433 Geometry.prototype.clear = function () {
434 var _a = this, container = _a.container, geometryLabel = _a.geometryLabel, offscreenGroup = _a.offscreenGroup;
435 if (container) {
436 container.clear();
437 }
438 if (geometryLabel) {
439 geometryLabel.clear();
440 }
441 if (offscreenGroup) {
442 offscreenGroup.clear();
443 }
444 // 属性恢复至出厂状态
445 this.scaleDefs = undefined;
446 this.attributes = {};
447 this.scales = {};
448 this.elementsMap = {};
449 this.lastElementsMap = {};
450 this.elements = [];
451 this.adjusts = {};
452 this.dataArray = null;
453 this.beforeMappingData = null;
454 this.lastAttributeOption = undefined;
455 this.defaultSize = undefined;
456 this.idFields = [];
457 this.groupScales = undefined;
458 this.hasSorted = false;
459 this.isCoordinateChanged = false;
460 };
461 /**
462 * 销毁 Geometry 实例。
463 */
464 Geometry.prototype.destroy = function () {
465 this.clear();
466 var container = this.container;
467 container.remove(true);
468 if (this.offscreenGroup) {
469 this.offscreenGroup.remove(true);
470 this.offscreenGroup = null;
471 }
472 if (this.geometryLabel) {
473 this.geometryLabel.destroy();
474 this.geometryLabel = null;
475 }
476 this.theme = undefined;
477 this.shapeFactory = undefined;
478 _super.prototype.destroy.call(this);
479 };
480 /**
481 * 获取决定分组的图形属性对应的 scale 实例。
482 * @returns
483 */
484 Geometry.prototype.getGroupScales = function () {
485 return this.groupScales;
486 };
487 /**
488 * 根据名字获取图形属性实例。
489 */
490 Geometry.prototype.getAttribute = function (name) {
491 return this.attributes[name];
492 };
493 /** 获取 x 轴对应的 scale 实例。 */
494 Geometry.prototype.getXScale = function () {
495 return this.getAttribute('position').scales[0];
496 };
497 /** 获取 y 轴对应的 scale 实例。 */
498 Geometry.prototype.getYScale = function () {
499 return this.getAttribute('position').scales[1];
500 };
501 /**
502 * 获取决定分组的图形属性实例。
503 */
504 Geometry.prototype.getGroupAttributes = function () {
505 var rst = [];
506 util_1.each(this.attributes, function (attr) {
507 if (constant_1.GROUP_ATTRS.includes(attr.type)) {
508 rst.push(attr);
509 }
510 });
511 return rst;
512 };
513 /** 获取图形属性默认的映射值。 */
514 Geometry.prototype.getDefaultValue = function (attrName) {
515 var value;
516 var attr = this.getAttribute(attrName);
517 if (attr && util_1.isEmpty(attr.scales)) {
518 // 获取映射至常量的值
519 value = attr.values[0];
520 }
521 return value;
522 };
523 /**
524 * 获取该数据发生图形映射后对应的 Attribute 图形空间数据。
525 * @param attr Attribute 图形属性实例。
526 * @param obj 需要进行映射的原始数据。
527 * @returns
528 */
529 Geometry.prototype.getAttributeValues = function (attr, obj) {
530 var params = [];
531 var scales = attr.scales;
532 for (var index = 0, length_2 = scales.length; index < length_2; index++) {
533 var scale = scales[index];
534 var field = scale.field;
535 if (scale.isIdentity) {
536 params.push(scale.values);
537 }
538 else {
539 params.push(obj[field]);
540 }
541 }
542 return attr.mapping.apply(attr, params);
543 };
544 Geometry.prototype.getAdjust = function (adjustType) {
545 return this.adjusts[adjustType];
546 };
547 /**
548 * 获取 shape 对应的 marker 样式。
549 * @param shapeName shape 具体名字
550 * @param cfg marker 信息
551 * @returns
552 */
553 Geometry.prototype.getShapeMarker = function (shapeName, cfg) {
554 var shapeFactory = this.getShapeFactory();
555 return shapeFactory.getMarker(shapeName, cfg);
556 };
557 /**
558 * 根据一定的规则查找 Geometry 的 Elements。
559 *
560 * ```typescript
561 * getElementsBy((element) => {
562 * const data = element.getData();
563 *
564 * return data.a === 'a';
565 * });
566 * ```
567 *
568 * @param condition 定义查找规则的回调函数。
569 * @returns
570 */
571 Geometry.prototype.getElementsBy = function (condition) {
572 return this.elements.filter(function (element) {
573 return condition(element);
574 });
575 };
576 /**
577 * 获取数据对应的唯一 id。
578 * @param data Element 对应的绘制数据
579 * @returns
580 */
581 Geometry.prototype.getElementId = function (data) {
582 data = util_1.isArray(data) ? data[0] : data;
583 var originData = data[constant_1.FIELD_ORIGIN];
584 // 如果用户声明了使用哪些字段作为 id 值
585 if (this.idFields.length) {
586 var elementId = originData[this.idFields[0]];
587 for (var index = 1; index < this.idFields.length; index++) {
588 elementId += '-' + originData[this.idFields[index]];
589 }
590 return elementId;
591 }
592 var type = this.type;
593 var xScale = this.getXScale();
594 var yScale = this.getYScale();
595 var xField = xScale.field || 'x';
596 var yField = yScale.field || 'y';
597 var yVal = originData[yField];
598 var xVal;
599 if (xScale.type === 'identity') {
600 xVal = xScale.values[0];
601 }
602 else {
603 xVal = originData[xField];
604 }
605 var id;
606 if (type === 'interval' || type === 'schema') {
607 id = "" + xVal;
608 }
609 else if (type === 'line' || type === 'area' || type === 'path') {
610 id = type;
611 }
612 else {
613 id = xVal + "-" + yVal;
614 }
615 var groupScales = this.groupScales;
616 if (util_1.isEmpty(groupScales)) {
617 groupScales = util_1.get(this.getAttribute('color'), 'scales', []);
618 }
619 for (var index = 0, length_3 = groupScales.length; index < length_3; index++) {
620 var groupScale = groupScales[index];
621 var field = groupScale.field;
622 id = id + "-" + originData[field];
623 }
624 // 用户在进行 dodge 类型的 adjust 调整的时候设置了 dodgeBy 属性
625 var dodgeAdjust = this.getAdjust('dodge');
626 if (dodgeAdjust) {
627 var dodgeBy = dodgeAdjust.dodgeBy;
628 if (dodgeBy) {
629 id = id + "-" + originData[dodgeBy];
630 }
631 }
632 if (this.getAdjust('jitter')) {
633 id = id + "-" + data.x + "-" + data.y;
634 }
635 return id;
636 };
637 /**
638 * 获取所有需要创建 scale 的字段名称。
639 */
640 Geometry.prototype.getScaleFields = function () {
641 var fields = [];
642 var tmpMap = {};
643 var _a = this, attributeOption = _a.attributeOption, labelOption = _a.labelOption, tooltipOption = _a.tooltipOption;
644 // 获取图形属性上的 fields
645 for (var attributeType in attributeOption) {
646 if (attributeOption.hasOwnProperty(attributeType)) {
647 var eachOpt = attributeOption[attributeType];
648 if (eachOpt.fields) {
649 helper_1.uniq(eachOpt.fields, fields, tmpMap);
650 }
651 else if (eachOpt.values) {
652 // 考虑 size(10), shape('circle') 等场景
653 helper_1.uniq(eachOpt.values, fields, tmpMap);
654 }
655 }
656 }
657 // 获取 label 上的字段
658 if (labelOption && labelOption.fields) {
659 helper_1.uniq(labelOption.fields, fields, tmpMap);
660 }
661 // 获取 tooltip 上的字段
662 if (util_1.isObject(tooltipOption) && tooltipOption.fields) {
663 helper_1.uniq(tooltipOption.fields, fields, tmpMap);
664 }
665 return fields;
666 };
667 /**
668 * 显示或者隐藏 geometry。
669 * @param visible
670 */
671 Geometry.prototype.changeVisible = function (visible) {
672 _super.prototype.changeVisible.call(this, visible);
673 var elements = this.elements;
674 for (var index = 0, length_4 = elements.length; index < length_4; index++) {
675 var element = elements[index];
676 element.changeVisible(visible);
677 }
678 if (visible) {
679 if (this.container) {
680 this.container.show();
681 }
682 if (this.labelsContainer) {
683 this.labelsContainer.show();
684 }
685 }
686 else {
687 if (this.container) {
688 this.container.hide();
689 }
690 if (this.labelsContainer) {
691 this.labelsContainer.hide();
692 }
693 }
694 };
695 /**
696 * 获取当前配置中的所有分组 & 分类的字段。
697 * @return fields string[]
698 */
699 Geometry.prototype.getGroupFields = function () {
700 var groupFields = [];
701 var tmpMap = {}; // 用于去重过滤
702 for (var index = 0, length_5 = constant_1.GROUP_ATTRS.length; index < length_5; index++) {
703 var attributeName = constant_1.GROUP_ATTRS[index];
704 var cfg = this.attributeOption[attributeName];
705 if (cfg && cfg.fields) {
706 helper_1.uniq(cfg.fields, groupFields, tmpMap);
707 }
708 }
709 return groupFields;
710 };
711 /**
712 * 获得图形的 x y 字段。
713 */
714 Geometry.prototype.getXYFields = function () {
715 var _a = this.attributeOption.position.fields, x = _a[0], y = _a[1];
716 return [x, y];
717 };
718 /**
719 * 获取该 Geometry 下所有生成的 shapes。
720 * @returns shapes
721 */
722 Geometry.prototype.getShapes = function () {
723 return this.elements.map(function (element) { return element.shape; });
724 };
725 /**
726 * 获取虚拟 Group。
727 * @returns
728 */
729 Geometry.prototype.getOffscreenGroup = function () {
730 if (!this.offscreenGroup) {
731 var GroupCtor = this.container.getGroupBase(); // 获取分组的构造函数
732 this.offscreenGroup = new GroupCtor({});
733 }
734 return this.offscreenGroup;
735 };
736 // 对数据进行排序
737 Geometry.prototype.sort = function (mappingArray) {
738 if (!this.hasSorted) {
739 // 未发生过排序
740 var xScale_1 = this.getXScale();
741 var xField_1 = xScale_1.field;
742 for (var index = 0; index < mappingArray.length; index++) {
743 var itemArr = mappingArray[index];
744 itemArr.sort(function (obj1, obj2) {
745 return xScale_1.translate(obj1[constant_1.FIELD_ORIGIN][xField_1]) - xScale_1.translate(obj2[constant_1.FIELD_ORIGIN][xField_1]);
746 });
747 }
748 }
749 this.hasSorted = true;
750 };
751 /**
752 * 调整度量范围。主要针对发生层叠以及一些特殊需求的 Geometry,比如 Interval 下的柱状图 Y 轴默认从 0 开始。
753 */
754 Geometry.prototype.adjustScale = function () {
755 var yScale = this.getYScale();
756 // 如果数据发生过 stack adjust,需要调整下 yScale 的数据范围
757 if (yScale && this.getAdjust('stack')) {
758 this.updateStackRange(yScale, this.beforeMappingData);
759 }
760 };
761 /**
762 * 获取当前 Geometry 对应的 Shape 工厂实例。
763 */
764 Geometry.prototype.getShapeFactory = function () {
765 var shapeType = this.shapeType;
766 if (!base_2.getShapeFactory(shapeType)) {
767 return;
768 }
769 if (!this.shapeFactory) {
770 this.shapeFactory = util_1.clone(base_2.getShapeFactory(shapeType)); // 防止多个 view 共享一个 shapeFactory 实例,导致 coordinate 被篡改
771 }
772 // 因为这里缓存了 shapeFactory,但是外部可能会变更 coordinate,导致无法重新设置到 shapeFactory 中
773 this.shapeFactory.coordinate = this.coordinate;
774 // theme 原因同上
775 this.shapeFactory.theme = this.theme.geometries[shapeType] || {};
776 return this.shapeFactory;
777 };
778 /**
779 * 获取每个 Shape 对应的关键点数据。
780 * @param obj 经过分组 -> 数字化 -> adjust 调整后的数据记录
781 * @returns
782 */
783 Geometry.prototype.createShapePointsCfg = function (obj) {
784 var xScale = this.getXScale();
785 var yScale = this.getYScale();
786 var x = this.normalizeValues(obj[xScale.field], xScale);
787 var y; // 存在没有 y 的情况
788 if (yScale) {
789 y = this.normalizeValues(obj[yScale.field], yScale);
790 }
791 else {
792 y = obj.y ? obj.y : 0.1;
793 }
794 return {
795 x: x,
796 y: y,
797 y0: yScale ? yScale.scale(this.getYMinValue()) : undefined,
798 };
799 };
800 /**
801 * 创建 Element 实例。
802 * @param mappingDatum Element 对应的绘制数据
803 * @param [isUpdate] 是否处于更新阶段
804 * @returns element 返回创建的 Element 实例
805 */
806 Geometry.prototype.createElement = function (mappingDatum, isUpdate) {
807 if (isUpdate === void 0) { isUpdate = false; }
808 var container = this.container;
809 var shapeCfg = this.getDrawCfg(mappingDatum); // 获取绘制图形的配置信息
810 var shapeFactory = this.getShapeFactory();
811 var element = new element_1.default({
812 shapeFactory: shapeFactory,
813 container: container,
814 offscreenGroup: this.getOffscreenGroup(),
815 });
816 element.animate = this.animateOption;
817 element.geometry = this;
818 element.draw(shapeCfg, isUpdate); // 绘制
819 return element;
820 };
821 /**
822 * 获取每条数据对应的图形绘制数据。
823 * @param mappingDatum 映射后的数据
824 * @returns draw cfg
825 */
826 Geometry.prototype.getDrawCfg = function (mappingDatum) {
827 var originData = mappingDatum[constant_1.FIELD_ORIGIN]; // 原始数据
828 var cfg = {
829 mappingData: mappingDatum,
830 data: originData,
831 x: mappingDatum.x,
832 y: mappingDatum.y,
833 color: mappingDatum.color,
834 size: mappingDatum.size,
835 isInCircle: this.coordinate.isPolar,
836 customInfo: this.customOption,
837 };
838 var shapeName = mappingDatum.shape;
839 if (!shapeName && this.getShapeFactory()) {
840 shapeName = this.getShapeFactory().defaultShapeType;
841 }
842 cfg.shape = shapeName;
843 // 获取默认样式
844 var theme = this.theme.geometries[this.shapeType];
845 cfg.defaultStyle = util_1.get(theme, [shapeName, 'default'], {}).style;
846 if (!cfg.defaultStyle && this.getShapeFactory()) {
847 cfg.defaultStyle = this.getShapeFactory().getDefaultStyle(theme);
848 }
849 var styleOption = this.styleOption;
850 if (styleOption) {
851 cfg.style = this.getStyleCfg(styleOption, originData);
852 }
853 if (this.generatePoints) {
854 cfg.points = mappingDatum.points;
855 cfg.nextPoints = mappingDatum.nextPoints;
856 }
857 return cfg;
858 };
859 /**
860 * 创建所有的 Elements。
861 * @param mappingData
862 * @param [isUpdate]
863 * @returns elements
864 */
865 Geometry.prototype.createElements = function (mappingData, index, isUpdate) {
866 if (isUpdate === void 0) { isUpdate = false; }
867 var _a = this, lastElementsMap = _a.lastElementsMap, elementsMap = _a.elementsMap, elements = _a.elements;
868 for (var subIndex = 0, length_6 = mappingData.length; subIndex < length_6; subIndex++) {
869 var mappingDatum = mappingData[subIndex];
870 var id = this.getElementId(mappingDatum);
871 if (elementsMap[id]) {
872 // 存在重复数据,则根据再根据 index 进行区分
873 id = id + "-" + index + "-" + subIndex;
874 }
875 var result = lastElementsMap[id];
876 if (!result) {
877 // 创建新的 element
878 result = this.createElement(mappingDatum, isUpdate);
879 }
880 else {
881 // element 已经创建
882 var currentShapeCfg = this.getDrawCfg(mappingDatum);
883 var preShapeCfg = result.getModel();
884 if (this.isCoordinateChanged || is_model_change_1.isModelChange(currentShapeCfg, preShapeCfg)) {
885 result.animate = this.animateOption;
886 // 通过绘制数据的变更来判断是否需要更新,因为用户有可能会修改图形属性映射
887 result.update(currentShapeCfg); // 更新对应的 element
888 }
889 delete lastElementsMap[id];
890 }
891 elements.push(result);
892 elementsMap[id] = result;
893 }
894 // 对 elements 的 zIndex 进行反序
895 if (this.zIndexReversed) {
896 var length_7 = elements.length;
897 elements.forEach(function (ele, idx) {
898 ele.shape.setZIndex(length_7 - idx);
899 });
900 }
901 return elements;
902 };
903 /**
904 * 获取渲染的 label 类型。
905 */
906 Geometry.prototype.getLabelType = function () {
907 var _a = this, labelOption = _a.labelOption, coordinate = _a.coordinate, type = _a.type;
908 var coordinateType = coordinate.type, isTransposed = coordinate.isTransposed;
909 var labelType = util_1.get(labelOption, ['cfg', 'type']);
910 if (!labelType) {
911 // 用户未定义,则进行默认的逻辑
912 if (coordinateType === 'polar') {
913 // 极坐标下使用通用的极坐标文本,转置则使用饼图
914 labelType = isTransposed ? 'pie' : 'polar';
915 }
916 else if (coordinateType === 'theta') {
917 // theta 坐标系下使用饼图文本
918 labelType = 'pie';
919 }
920 else if (type === 'interval' || type === 'polygon') {
921 labelType = 'interval';
922 }
923 else {
924 labelType = 'base';
925 }
926 }
927 return labelType;
928 };
929 /**
930 * 获取 Y 轴上的最小值。
931 */
932 Geometry.prototype.getYMinValue = function () {
933 var yScale = this.getYScale();
934 var min = yScale.min, max = yScale.max;
935 var value;
936 if (min >= 0) {
937 value = min;
938 }
939 else if (max <= 0) {
940 // 当值全位于负区间时,需要保证 ymin 在区域内,不可为 0
941 value = max;
942 }
943 else {
944 value = 0;
945 }
946 return value;
947 };
948 // 创建图形属性相关的配置项
949 Geometry.prototype.createAttrOption = function (attrName, field, cfg) {
950 if (util_1.isNil(field) || util_1.isObject(field)) {
951 if (util_1.isObject(field) && util_1.isEqual(Object.keys(field), ['values'])) {
952 // shape({ values: [ 'funnel' ] })
953 util_1.set(this.attributeOption, attrName, {
954 fields: field.values,
955 });
956 }
957 else {
958 util_1.set(this.attributeOption, attrName, field);
959 }
960 }
961 else {
962 var attrCfg = {};
963 if (util_1.isNumber(field)) {
964 // size(3)
965 attrCfg.values = [field];
966 }
967 else {
968 attrCfg.fields = parse_fields_1.parseFields(field);
969 }
970 if (cfg) {
971 if (util_1.isFunction(cfg)) {
972 attrCfg.callback = cfg;
973 }
974 else {
975 attrCfg.values = cfg;
976 }
977 }
978 util_1.set(this.attributeOption, attrName, attrCfg);
979 }
980 };
981 Geometry.prototype.initAttributes = function () {
982 var _this = this;
983 var _a = this, attributes = _a.attributes, attributeOption = _a.attributeOption, theme = _a.theme, shapeType = _a.shapeType;
984 this.groupScales = [];
985 var tmpMap = {};
986 var _loop_1 = function (attrType) {
987 if (attributeOption.hasOwnProperty(attrType)) {
988 var option = attributeOption[attrType];
989 if (!option) {
990 return { value: void 0 };
991 }
992 var attrCfg = tslib_1.__assign({}, option);
993 var callback = attrCfg.callback, values = attrCfg.values, _a = attrCfg.fields, fields = _a === void 0 ? [] : _a;
994 // 获取每一个字段对应的 scale
995 var scales = fields.map(function (field) {
996 var scale = _this.scales[field];
997 if (scale.isCategory && !tmpMap[field] && constant_1.GROUP_ATTRS.includes(attrType)) {
998 _this.groupScales.push(scale);
999 tmpMap[field] = true;
1000 }
1001 return scale;
1002 });
1003 attrCfg.scales = scales;
1004 if (attrType !== 'position' && scales.length === 1 && scales[0].type === 'identity') {
1005 // 用户在图形通道上声明了常量字段 color('red'), size(5)
1006 attrCfg.values = scales[0].values;
1007 }
1008 else if (!callback && !values) {
1009 // 用户没有指定任何规则,则使用默认的映射规则
1010 if (attrType === 'size') {
1011 attrCfg.values = theme.sizes;
1012 }
1013 else if (attrType === 'shape') {
1014 attrCfg.values = theme.shapes[shapeType] || [];
1015 }
1016 else if (attrType === 'color') {
1017 if (scales.length) {
1018 // 根据数值个数使用对应的色板
1019 attrCfg.values = scales[0].values.length <= 10 ? theme.colors10 : theme.colors20;
1020 }
1021 else {
1022 attrCfg.values = theme.colors10;
1023 }
1024 }
1025 }
1026 var AttributeCtor = attr_1.getAttribute(attrType);
1027 attributes[attrType] = new AttributeCtor(attrCfg);
1028 }
1029 };
1030 // 遍历每一个 attrOption,各自创建 Attribute 实例
1031 for (var attrType in attributeOption) {
1032 var state_1 = _loop_1(attrType);
1033 if (typeof state_1 === "object")
1034 return state_1.value;
1035 }
1036 };
1037 // 处理数据:分组 -> 数字化 -> adjust 调整
1038 Geometry.prototype.processData = function (data) {
1039 this.hasSorted = false;
1040 var scales = this.getAttribute('position').scales;
1041 var categoryScales = scales.filter(function (scale) { return scale.isCategory; });
1042 var groupedArray = this.groupData(data); // 数据分组
1043 var beforeAdjust = [];
1044 for (var i = 0, len = groupedArray.length; i < len; i++) {
1045 var subData = groupedArray[i];
1046 var arr = [];
1047 for (var j = 0, subLen = subData.length; j < subLen; j++) {
1048 var originData = subData[j];
1049 var item = {};
1050 // tslint:disable-next-line: forin
1051 for (var k in originData) {
1052 item[k] = originData[k];
1053 }
1054 item[constant_1.FIELD_ORIGIN] = originData;
1055 // 将分类数据翻译成数据, 仅对位置相关的度量进行数字化处理
1056 for (var _i = 0, categoryScales_1 = categoryScales; _i < categoryScales_1.length; _i++) {
1057 var scale = categoryScales_1[_i];
1058 var field = scale.field;
1059 item[field] = scale.translate(item[field]);
1060 }
1061 arr.push(item);
1062 }
1063 beforeAdjust.push(arr);
1064 }
1065 var dataArray = this.adjustData(beforeAdjust); // 进行 adjust 数据调整
1066 this.beforeMappingData = dataArray;
1067 return dataArray;
1068 };
1069 // 调整数据
1070 Geometry.prototype.adjustData = function (dataArray) {
1071 var adjustOption = this.adjustOption;
1072 var _a = this, intervalPadding = _a.intervalPadding, dodgePadding = _a.dodgePadding, theme = _a.theme;
1073 // 兼容theme配置
1074 var maxColumnWidth = this.maxColumnWidth || theme.maxColumnWidth;
1075 var minColumnWidth = this.minColumnWidth || theme.minColumnWidth;
1076 var columnWidthRatio = this.columnWidthRatio || theme.columnWidthRatio;
1077 var result = dataArray;
1078 if (adjustOption) {
1079 var xScale = this.getXScale();
1080 var yScale = this.getYScale();
1081 var xField = xScale.field;
1082 var yField = yScale ? yScale.field : null;
1083 var xDimensionLength = coordinate_1.getXDimensionLength(this.coordinate);
1084 var groupNum = xScale.values.length;
1085 // 传入size计算相关参数,默认宽度、最大最小宽度约束
1086 var sizeAttr = this.getAttribute('size');
1087 var defaultSize = void 0;
1088 if (sizeAttr) {
1089 defaultSize = sizeAttr.values[0];
1090 }
1091 for (var i = 0, len = adjustOption.length; i < len; i++) {
1092 var adjust = adjustOption[i];
1093 var adjustCfg = tslib_1.__assign({ xField: xField,
1094 yField: yField,
1095 intervalPadding: intervalPadding,
1096 dodgePadding: dodgePadding,
1097 xDimensionLength: xDimensionLength,
1098 groupNum: groupNum,
1099 defaultSize: defaultSize,
1100 maxColumnWidth: maxColumnWidth,
1101 minColumnWidth: minColumnWidth,
1102 columnWidthRatio: columnWidthRatio }, adjust);
1103 var type = adjust.type;
1104 if (type === 'dodge') {
1105 var adjustNames = [];
1106 if (xScale.isCategory || xScale.type === 'identity') {
1107 adjustNames.push('x');
1108 }
1109 else if (!yScale) {
1110 adjustNames.push('y');
1111 }
1112 else {
1113 throw new Error('dodge is not support linear attribute, please use category attribute!');
1114 }
1115 adjustCfg.adjustNames = adjustNames;
1116 // 每个分组内每条柱子的宽度占比,用户不可指定,用户需要通过 columnWidthRatio 指定
1117 // 兼容theme配置
1118 adjustCfg.dodgeRatio = columnWidthRatio;
1119 }
1120 else if (type === 'stack') {
1121 var coordinate = this.coordinate;
1122 if (!yScale) {
1123 // 一维的情况下获取高度和默认size
1124 adjustCfg.height = coordinate.getHeight();
1125 var size = this.getDefaultValue('size') || 3;
1126 adjustCfg.size = size;
1127 }
1128 // 不进行 transpose 时,用户又没有设置这个参数时,默认从上向下
1129 if (!coordinate.isTransposed && util_1.isNil(adjustCfg.reverseOrder)) {
1130 adjustCfg.reverseOrder = true;
1131 }
1132 }
1133 var adjustCtor = adjust_1.getAdjust(type);
1134 var adjustInstance = new adjustCtor(adjustCfg);
1135 result = adjustInstance.process(result);
1136 this.adjusts[type] = adjustInstance;
1137 }
1138 }
1139 return result;
1140 };
1141 // 对数据进行分组
1142 Geometry.prototype.groupData = function (data) {
1143 var groupScales = this.getGroupScales();
1144 var scaleDefs = this.scaleDefs;
1145 var appendConditions = {};
1146 var groupFields = [];
1147 for (var index = 0; index < groupScales.length; index++) {
1148 var scale = groupScales[index];
1149 var field = scale.field;
1150 groupFields.push(field);
1151 if (util_1.get(scaleDefs, [field, 'values'])) {
1152 // 用户通过 view.scale() 接口指定了 values 属性
1153 appendConditions[field] = scaleDefs[field].values;
1154 }
1155 }
1156 return group_data_1.group(data, groupFields, appendConditions);
1157 };
1158 // 更新发生层叠后的数据对应的度量范围
1159 Geometry.prototype.updateStackRange = function (scale, dataArray) {
1160 var mergeArray = util_1.flatten(dataArray);
1161 var field = scale.field;
1162 var min = scale.min;
1163 var max = scale.max;
1164 for (var index = 0; index < mergeArray.length; index++) {
1165 var obj = mergeArray[index];
1166 var tmpMin = Math.min.apply(null, obj[field]);
1167 var tmpMax = Math.max.apply(null, obj[field]);
1168 if (tmpMin < min) {
1169 min = tmpMin;
1170 }
1171 if (tmpMax > max) {
1172 max = tmpMax;
1173 }
1174 }
1175 var scaleDefs = this.scaleDefs;
1176 var cfg = {};
1177 if (min < scale.min && !util_1.get(scaleDefs, [field, 'min'])) {
1178 // 用户如果在列定义中定义了 min,则以用户定义的为准
1179 cfg.min = min;
1180 }
1181 if (max > scale.max && !util_1.get(scaleDefs, [field, 'max'])) {
1182 // 用户如果在列定义中定义了 max
1183 cfg.max = max;
1184 }
1185 scale.change(cfg);
1186 };
1187 // 将数据映射至图形空间前的操作:排序以及关键点的生成
1188 Geometry.prototype.beforeMapping = function (beforeMappingData) {
1189 // 当初加 clone 是因为 points 的引用关系,导致更新失败,可是现在貌似复现不出来了,所以暂时不进行 clone
1190 // const source = clone(beforeMappingData);
1191 var source = beforeMappingData;
1192 if (this.sortable) {
1193 this.sort(source);
1194 }
1195 if (this.generatePoints) {
1196 // 需要生成关键点
1197 for (var index = 0, length_8 = source.length; index < length_8; index++) {
1198 var currentData = source[index];
1199 this.generateShapePoints(currentData);
1200 var nextData = source[index + 1];
1201 if (nextData) {
1202 this.generateShapePoints(nextData);
1203 currentData[0].nextPoints = nextData[0].points;
1204 }
1205 }
1206 }
1207 return source;
1208 };
1209 // 生成 shape 的关键点
1210 Geometry.prototype.generateShapePoints = function (data) {
1211 var shapeFactory = this.getShapeFactory();
1212 var shapeAttr = this.getAttribute('shape');
1213 for (var index = 0; index < data.length; index++) {
1214 var obj = data[index];
1215 var cfg = this.createShapePointsCfg(obj);
1216 var shape = shapeAttr ? this.getAttributeValues(shapeAttr, obj) : null;
1217 var points = shapeFactory.getShapePoints(shape, cfg);
1218 obj.points = points;
1219 }
1220 };
1221 // 将数据归一化
1222 Geometry.prototype.normalizeValues = function (values, scale) {
1223 var rst = [];
1224 if (util_1.isArray(values)) {
1225 for (var index = 0; index < values.length; index++) {
1226 var value = values[index];
1227 rst.push(scale.scale(value));
1228 }
1229 }
1230 else {
1231 rst = scale.scale(values);
1232 }
1233 return rst;
1234 };
1235 // 将数据映射至图形空间
1236 Geometry.prototype.mapping = function (data) {
1237 var attributes = this.attributes;
1238 var mappingData = [];
1239 for (var index = 0; index < data.length; index++) {
1240 var record = data[index];
1241 var newRecord = {
1242 _origin: record[constant_1.FIELD_ORIGIN],
1243 points: record.points,
1244 nextPoints: record.nextPoints,
1245 };
1246 for (var k in attributes) {
1247 if (attributes.hasOwnProperty(k)) {
1248 var attr = attributes[k];
1249 var names = attr.names;
1250 var values = this.getAttributeValues(attr, record);
1251 if (names.length > 1) {
1252 // position 之类的生成多个字段的属性
1253 for (var j = 0; j < values.length; j += 1) {
1254 var val = values[j];
1255 var name_1 = names[j];
1256 newRecord[name_1] = util_1.isArray(val) && val.length === 1 ? val[0] : val; // 只有一个值时返回第一个属性值
1257 }
1258 }
1259 else {
1260 // values.length === 1 的判断是以下情况,获取用户设置的图形属性值
1261 // shape('a', ['dot', 'dash']), color('a', ['red', 'yellow'])
1262 newRecord[names[0]] = values.length === 1 ? values[0] : values;
1263 }
1264 }
1265 }
1266 this.convertPoint(newRecord); // 将 x、y 转换成画布坐标
1267 mappingData.push(newRecord);
1268 }
1269 return mappingData;
1270 };
1271 // 将归一化的坐标值转换成画布坐标
1272 Geometry.prototype.convertPoint = function (mappingRecord) {
1273 var x = mappingRecord.x, y = mappingRecord.y;
1274 var rstX;
1275 var rstY;
1276 var obj;
1277 var coordinate = this.coordinate;
1278 if (util_1.isArray(x) && util_1.isArray(y)) {
1279 rstX = [];
1280 rstY = [];
1281 for (var i = 0, j = 0, xLen = x.length, yLen = y.length; i < xLen && j < yLen; i += 1, j += 1) {
1282 obj = coordinate.convert({
1283 x: x[i],
1284 y: y[j],
1285 });
1286 rstX.push(obj.x);
1287 rstY.push(obj.y);
1288 }
1289 }
1290 else if (util_1.isArray(y)) {
1291 rstY = [];
1292 for (var index = 0; index < y.length; index++) {
1293 var yVal = y[index];
1294 obj = coordinate.convert({
1295 x: x,
1296 y: yVal,
1297 });
1298 if (rstX && rstX !== obj.x) {
1299 if (!util_1.isArray(rstX)) {
1300 rstX = [rstX];
1301 }
1302 rstX.push(obj.x);
1303 }
1304 else {
1305 rstX = obj.x;
1306 }
1307 rstY.push(obj.y);
1308 }
1309 }
1310 else if (util_1.isArray(x)) {
1311 rstX = [];
1312 for (var index = 0; index < x.length; index++) {
1313 var xVal = x[index];
1314 obj = coordinate.convert({
1315 x: xVal,
1316 y: y,
1317 });
1318 if (rstY && rstY !== obj.y) {
1319 if (!util_1.isArray(rstY)) {
1320 rstY = [rstY];
1321 }
1322 rstY.push(obj.y);
1323 }
1324 else {
1325 rstY = obj.y;
1326 }
1327 rstX.push(obj.x);
1328 }
1329 }
1330 else {
1331 var point = coordinate.convert({
1332 x: x,
1333 y: y,
1334 });
1335 rstX = point.x;
1336 rstY = point.y;
1337 }
1338 mappingRecord.x = rstX;
1339 mappingRecord.y = rstY;
1340 };
1341 // 获取 style 配置
1342 Geometry.prototype.getStyleCfg = function (styleOption, originData) {
1343 var _a = styleOption.fields, fields = _a === void 0 ? [] : _a, callback = styleOption.callback, cfg = styleOption.cfg;
1344 if (cfg) {
1345 // 用户直接配置样式属性
1346 return cfg;
1347 }
1348 var params = fields.map(function (field) {
1349 return originData[field];
1350 });
1351 return callback.apply(void 0, params);
1352 };
1353 Geometry.prototype.setCfg = function (cfg) {
1354 var _this = this;
1355 var coordinate = cfg.coordinate, data = cfg.data, theme = cfg.theme, scaleDefs = cfg.scaleDefs;
1356 if (coordinate) {
1357 this.coordinate = coordinate;
1358 }
1359 if (data) {
1360 this.data = data;
1361 }
1362 if (scaleDefs) {
1363 this.scaleDefs = scaleDefs;
1364 this.idFields = [];
1365 util_1.each(scaleDefs, function (scaleDef, field) {
1366 if (scaleDef && scaleDef.key) {
1367 _this.idFields.push(field);
1368 }
1369 });
1370 }
1371 if (theme) {
1372 this.theme = this.userTheme ? util_1.deepMix({}, theme, this.userTheme) : theme; // 支持 geometry 层级的主题设置
1373 }
1374 };
1375 Geometry.prototype.renderLabels = function (mappingArray, isUpdate) {
1376 if (isUpdate === void 0) { isUpdate = false; }
1377 var geometryLabel = this.geometryLabel;
1378 if (!geometryLabel) {
1379 // 初次创建
1380 var labelType = this.getLabelType();
1381 var GeometryLabelsCtor = label_1.getGeometryLabel(labelType);
1382 geometryLabel = new GeometryLabelsCtor(this);
1383 this.geometryLabel = geometryLabel;
1384 }
1385 geometryLabel.render(mappingArray, isUpdate);
1386 // 将 label 同 element 进行关联
1387 var labelsMap = geometryLabel.labelsRenderer.shapesMap;
1388 util_1.each(this.elementsMap, function (element, id) {
1389 var labels = filterLabelsById(id, labelsMap); // element 实例同 label 进行绑定
1390 if (labels.length) {
1391 element.labelShape = labels;
1392 for (var i = 0; i < labels.length; i++) {
1393 var label = labels[i];
1394 var labelChildren = label.getChildren();
1395 for (var j = 0; j < labelChildren.length; j++) {
1396 var child = labelChildren[j];
1397 child.cfg.name = ['element', 'label'];
1398 child.cfg.element = element;
1399 }
1400 }
1401 }
1402 });
1403 };
1404 /**
1405 * 是否需要进行群组入场动画
1406 * 规则:
1407 * 1. 如果发生更新,则不进行
1408 * 2. 如果用户关闭 geometry 动画,则不进行
1409 * 3. 如果用户关闭了 appear 动画,则不进行
1410 * 4. 如果用户配置了 appear.animation,则不进行
1411 */
1412 Geometry.prototype.canDoGroupAnimation = function (isUpdate) {
1413 return (!isUpdate &&
1414 this.animateOption &&
1415 (util_1.get(this.animateOption, 'appear') === undefined ||
1416 (util_1.get(this.animateOption, 'appear') && util_1.get(this.animateOption, ['appear', 'animation']) === undefined)));
1417 };
1418 return Geometry;
1419}(base_1.default));
1420exports.default = Geometry;
1421//# sourceMappingURL=base.js.map
\No newline at end of file