UNPKG

618 kBJavaScriptView Raw
1(function (global, factory) {
2 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
3 typeof define === 'function' && define.amd ? define(['exports'], factory) :
4 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.F2 = {}));
5}(this, (function (exports) { 'use strict';
6
7 function getDefaultExportFromCjs (x) {
8 return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
9 }
10
11 function createCommonjsModule(fn, basedir, module) {
12 return module = {
13 path: basedir,
14 exports: {},
15 require: function (path, base) {
16 return commonjsRequire(path, (base === undefined || base === null) ? module.path : base);
17 }
18 }, fn(module, module.exports), module.exports;
19 }
20
21 function commonjsRequire () {
22 throw new Error('Dynamic requires are not currently supported by @rollup/plugin-commonjs');
23 }
24
25 var defineProperty = createCommonjsModule(function (module) {
26 function _defineProperty(obj, key, value) {
27 if (key in obj) {
28 Object.defineProperty(obj, key, {
29 value: value,
30 enumerable: true,
31 configurable: true,
32 writable: true
33 });
34 } else {
35 obj[key] = value;
36 }
37
38 return obj;
39 }
40
41 module.exports = _defineProperty, module.exports.__esModule = true, module.exports["default"] = module.exports;
42 });
43
44 var _defineProperty = /*@__PURE__*/getDefaultExportFromCjs(defineProperty);
45
46 var objectSpread2 = createCommonjsModule(function (module) {
47 function ownKeys(object, enumerableOnly) {
48 var keys = Object.keys(object);
49
50 if (Object.getOwnPropertySymbols) {
51 var symbols = Object.getOwnPropertySymbols(object);
52 enumerableOnly && (symbols = symbols.filter(function (sym) {
53 return Object.getOwnPropertyDescriptor(object, sym).enumerable;
54 })), keys.push.apply(keys, symbols);
55 }
56
57 return keys;
58 }
59
60 function _objectSpread2(target) {
61 for (var i = 1; i < arguments.length; i++) {
62 var source = null != arguments[i] ? arguments[i] : {};
63 i % 2 ? ownKeys(Object(source), !0).forEach(function (key) {
64 defineProperty(target, key, source[key]);
65 }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) {
66 Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
67 });
68 }
69
70 return target;
71 }
72
73 module.exports = _objectSpread2, module.exports.__esModule = true, module.exports["default"] = module.exports;
74 });
75
76 var _objectSpread = /*@__PURE__*/getDefaultExportFromCjs(objectSpread2);
77
78 var isArrayLike = function (value) {
79 /**
80 * isArrayLike([1, 2, 3]) => true
81 * isArrayLike(document.body.children) => true
82 * isArrayLike('abc') => true
83 * isArrayLike(Function) => false
84 */
85 return value !== null && typeof value !== 'function' && isFinite(value.length);
86 };
87
88 var filter = function (arr, func) {
89 if (!isArrayLike(arr)) {
90 return arr;
91 }
92 var result = [];
93 for (var index = 0; index < arr.length; index++) {
94 var value = arr[index];
95 if (func(value, index)) {
96 result.push(value);
97 }
98 }
99 return result;
100 };
101
102 var toString = {}.toString;
103 var isType = function (value, type) { return toString.call(value) === '[object ' + type + ']'; };
104
105 /**
106 * 是否为函数
107 * @param {*} fn 对象
108 * @return {Boolean} 是否函数
109 */
110 var isFunction = (function (value) {
111 return isType(value, 'Function');
112 });
113
114 // isFinite,
115 var isNil = function (value) {
116 /**
117 * isNil(null) => true
118 * isNil() => true
119 */
120 return value === null || value === undefined;
121 };
122
123 var isArray = (function (value) {
124 return Array.isArray ?
125 Array.isArray(value) :
126 isType(value, 'Array');
127 });
128
129 var isObject = (function (value) {
130 /**
131 * isObject({}) => true
132 * isObject([1, 2, 3]) => true
133 * isObject(Function) => true
134 * isObject(null) => false
135 */
136 var type = typeof value;
137 return value !== null && type === 'object' || type === 'function';
138 });
139
140 function each(elements, func) {
141 if (!elements) {
142 return;
143 }
144 var rst;
145 if (isArray(elements)) {
146 for (var i = 0, len = elements.length; i < len; i++) {
147 rst = func(elements[i], i);
148 if (rst === false) {
149 break;
150 }
151 }
152 }
153 else if (isObject(elements)) {
154 for (var k in elements) {
155 if (elements.hasOwnProperty(k)) {
156 rst = func(elements[k], k);
157 if (rst === false) {
158 break;
159 }
160 }
161 }
162 }
163 }
164
165 var keys = Object.keys ? function (obj) { return Object.keys(obj); } : function (obj) {
166 var result = [];
167 each(obj, function (value, key) {
168 if (!(isFunction(obj) && key === 'prototype')) {
169 result.push(key);
170 }
171 });
172 return result;
173 };
174
175 function isMatch(obj, attrs) {
176 var _keys = keys(attrs);
177 var length = _keys.length;
178 if (isNil(obj))
179 return !length;
180 for (var i = 0; i < length; i += 1) {
181 var key = _keys[i];
182 if (attrs[key] !== obj[key] || !(key in obj)) {
183 return false;
184 }
185 }
186 return true;
187 }
188
189 var isObjectLike = function (value) {
190 /**
191 * isObjectLike({}) => true
192 * isObjectLike([1, 2, 3]) => true
193 * isObjectLike(Function) => false
194 * isObjectLike(null) => false
195 */
196 return typeof value === 'object' && value !== null;
197 };
198
199 var isPlainObject = function (value) {
200 /**
201 * isObjectLike(new Foo) => false
202 * isObjectLike([1, 2, 3]) => false
203 * isObjectLike({ x: 0, y: 0 }) => true
204 * isObjectLike(Object.create(null)) => true
205 */
206 if (!isObjectLike(value) || !isType(value, 'Object')) {
207 return false;
208 }
209 if (Object.getPrototypeOf(value) === null) {
210 return true;
211 }
212 var proto = value;
213 while (Object.getPrototypeOf(proto) !== null) {
214 proto = Object.getPrototypeOf(proto);
215 }
216 return Object.getPrototypeOf(value) === proto;
217 };
218
219 function find(arr, predicate) {
220 if (!isArray(arr))
221 return null;
222 var _predicate;
223 if (isFunction(predicate)) {
224 _predicate = predicate;
225 }
226 if (isPlainObject(predicate)) {
227 _predicate = function (a) { return isMatch(a, predicate); };
228 }
229 if (_predicate) {
230 for (var i = 0; i < arr.length; i += 1) {
231 if (_predicate(arr[i])) {
232 return arr[i];
233 }
234 }
235 }
236 return null;
237 }
238
239 function findIndex(arr, predicate, fromIndex) {
240 if (fromIndex === void 0) { fromIndex = 0; }
241 for (var i = fromIndex; i < arr.length; i++) {
242 if (predicate(arr[i], i)) {
243 // 找到终止循环
244 return i;
245 }
246 }
247 return -1;
248 }
249
250 /**
251 * Flattens `array` a single level deep.
252 *
253 * @param {Array} arr The array to flatten.
254 * @return {Array} Returns the new flattened array.
255 * @example
256 *
257 * flatten([1, [2, [3, [4]], 5]]); // => [1, 2, [3, [4]], 5]
258 */
259 var flatten = function (arr) {
260 if (!isArray(arr)) {
261 return [];
262 }
263 var rst = [];
264 for (var i = 0; i < arr.length; i++) {
265 rst = rst.concat(arr[i]);
266 }
267 return rst;
268 };
269
270 /**
271 * @param {Array} arr The array to iterate over.
272 * @return {*} Returns the maximum value.
273 * @example
274 *
275 * max([1, 2]);
276 * // => 2
277 *
278 * max([]);
279 * // => undefined
280 *
281 * const data = new Array(1250010).fill(1).map((d,idx) => idx);
282 *
283 * max(data);
284 * // => 1250010
285 * // Math.max(...data) will encounter "Maximum call stack size exceeded" error
286 */
287 var getMax = (function (arr) {
288 if (!isArray(arr)) {
289 return undefined;
290 }
291 return arr.reduce(function (prev, curr) {
292 return Math.max(prev, curr);
293 }, arr[0]);
294 });
295
296 /**
297 * @param {Array} arr The array to iterate over.
298 * @return {*} Returns the minimum value.
299 * @example
300 *
301 * min([1, 2]);
302 * // => 1
303 *
304 * min([]);
305 * // => undefined
306 *
307 * const data = new Array(1250010).fill(1).map((d,idx) => idx);
308 *
309 * min(data);
310 * // => 1250010
311 * // Math.min(...data) will encounter "Maximum call stack size exceeded" error
312 */
313 var getMin = (function (arr) {
314 if (!isArray(arr)) {
315 return undefined;
316 }
317 return arr.reduce(function (prev, curr) {
318 return Math.min(prev, curr);
319 }, arr[0]);
320 });
321
322 var getRange = function (values) {
323 // 存在 NaN 时,min,max 判定会出问题
324 var filterValues = values.filter(function (v) { return !isNaN(v); });
325 if (!filterValues.length) {
326 // 如果没有数值则直接返回0
327 return {
328 min: 0,
329 max: 0,
330 };
331 }
332 if (isArray(values[0])) {
333 var tmp = [];
334 for (var i = 0; i < values.length; i++) {
335 tmp = tmp.concat(values[i]);
336 }
337 filterValues = tmp;
338 }
339 var max = getMax(filterValues);
340 var min = getMin(filterValues);
341 return {
342 min: min,
343 max: max,
344 };
345 };
346
347 var reduce = function (arr, fn, init) {
348 if (!isArray(arr) && !isPlainObject(arr)) {
349 return arr;
350 }
351 var result = init;
352 each(arr, function (data, i) {
353 result = fn(result, data, i);
354 });
355 return result;
356 };
357
358 var isString = (function (str) {
359 return isType(str, 'String');
360 });
361
362 var valuesOfKey = (function (data, name) {
363 var rst = [];
364 var tmpMap = {};
365 for (var i = 0; i < data.length; i++) {
366 var obj = data[i];
367 var value = obj[name];
368 if (!isNil(value)) {
369 // flatten
370 if (!isArray(value)) {
371 value = [value];
372 }
373 for (var j = 0; j < value.length; j++) {
374 var val = value[j];
375 // unique
376 if (!tmpMap[val]) {
377 rst.push(val);
378 tmpMap[val] = true;
379 }
380 }
381 }
382 }
383 return rst;
384 });
385
386 function head(o) {
387 if (isArrayLike(o)) {
388 return o[0];
389 }
390 return undefined;
391 }
392
393 function last(o) {
394 if (isArrayLike(o)) {
395 var arr = o;
396 return arr[arr.length - 1];
397 }
398 return undefined;
399 }
400
401 var hasOwnProperty = Object.prototype.hasOwnProperty;
402 function groupBy(data, condition) {
403 if (!condition || !isArray(data)) {
404 return {};
405 }
406 var result = {};
407 // 兼容方法和 字符串的写法
408 var predicate = isFunction(condition) ? condition : function (item) { return item[condition]; };
409 var key;
410 for (var i = 0; i < data.length; i++) {
411 var item = data[i];
412 key = predicate(item);
413 if (hasOwnProperty.call(result, key)) {
414 result[key].push(item);
415 }
416 else {
417 result[key] = [item];
418 }
419 }
420 return result;
421 }
422
423 /**
424 * 将数据分组成 map
425 * @param data
426 * @param condition
427 */
428 function groupToMap(data, condition) {
429 if (!condition) {
430 return {
431 0: data,
432 };
433 }
434 if (!isFunction(condition)) {
435 // 如果是字符串,则按照 a*b 风格成数组
436 var paramscondition_1 = isArray(condition) ? condition : condition.replace(/\s+/g, '').split('*');
437 condition = function (row) {
438 var unique = '_'; // 避免出现数字作为Key的情况,会进行按照数字的排序
439 // 根据字段列表的值,拼接成 key
440 for (var i = 0, l = paramscondition_1.length; i < l; i++) {
441 unique += row[paramscondition_1[i]] && row[paramscondition_1[i]].toString();
442 }
443 return unique;
444 };
445 }
446 return groupBy(data, condition);
447 }
448
449 var group = (function (data, condition) {
450 if (!condition) {
451 // 没有条件,则自身改成数组
452 return [data];
453 }
454 var groups = groupToMap(data, condition);
455 var array = [];
456 for (var i in groups) {
457 array.push(groups[i]);
458 }
459 return array;
460 });
461
462 var fixedBase = function (v, base) {
463 var str = base.toString();
464 var index = str.indexOf('.');
465 if (index === -1) {
466 return Math.round(v);
467 }
468 var length = str.substr(index + 1).length;
469 if (length > 20) {
470 length = 20;
471 }
472 return parseFloat(v.toFixed(length));
473 };
474
475 /**
476 * 判断是否数字
477 * @return {Boolean} 是否数字
478 */
479 var isNumber = function (value) {
480 return isType(value, 'Number');
481 };
482
483 var PRECISION = 0.00001; // numbers less than this is considered as 0
484 function isNumberEqual(a, b, precision) {
485 if (precision === void 0) { precision = PRECISION; }
486 return Math.abs((a - b)) < precision;
487 }
488
489 // @ts-ignore
490 var values = Object.values ? function (obj) { return Object.values(obj); } : function (obj) {
491 var result = [];
492 each(obj, function (value, key) {
493 if (!(isFunction(obj) && key === 'prototype')) {
494 result.push(value);
495 }
496 });
497 return result;
498 };
499
500 var toString$1 = (function (value) {
501 if (isNil(value))
502 return '';
503 return value.toString();
504 });
505
506 function substitute(str, o) {
507 if (!str || !o) {
508 return str;
509 }
510 return str.replace(/\\?\{([^{}]+)\}/g, function (match, name) {
511 if (match.charAt(0) === '\\') {
512 return match.slice(1);
513 }
514 return (o[name] === undefined) ? '' : o[name];
515 });
516 }
517
518 var upperFirst = function (value) {
519 var str = toString$1(value);
520 return str.charAt(0).toUpperCase() + str.substring(1);
521 };
522
523 var toString$2 = {}.toString;
524 var getType = function (value) {
525 return toString$2.call(value).replace(/^\[object /, '').replace(/]$/, '');
526 };
527
528 /**
529 * 是否是布尔类型
530 *
531 * @param {Object} value 测试的值
532 * @return {Boolean}
533 */
534 var isBoolean = function (value) {
535 return isType(value, 'Boolean');
536 };
537
538 var isDate = function (value) {
539 return isType(value, 'Date');
540 };
541
542 var objectProto = Object.prototype;
543 var isPrototype = function (value) {
544 var Ctor = value && value.constructor;
545 var proto = (typeof Ctor === 'function' && Ctor.prototype) || objectProto;
546 return value === proto;
547 };
548
549 var isUndefined = function (value) {
550 return value === undefined;
551 };
552
553 // FIXME: Mutable param should be forbidden in static lang.
554 function _mix(dist, obj) {
555 for (var key in obj) {
556 if (obj.hasOwnProperty(key) && key !== 'constructor' && obj[key] !== undefined) {
557 dist[key] = obj[key];
558 }
559 }
560 }
561 function mix(dist, src1, src2, src3) {
562 if (src1)
563 _mix(dist, src1);
564 if (src2)
565 _mix(dist, src2);
566 if (src3)
567 _mix(dist, src3);
568 return dist;
569 }
570
571 var clone = function (obj) {
572 if (typeof obj !== 'object' || obj === null) {
573 return obj;
574 }
575 var rst;
576 if (isArray(obj)) {
577 rst = [];
578 for (var i = 0, l = obj.length; i < l; i++) {
579 if (typeof obj[i] === 'object' && obj[i] != null) {
580 rst[i] = clone(obj[i]);
581 }
582 else {
583 rst[i] = obj[i];
584 }
585 }
586 }
587 else {
588 rst = {};
589 for (var k in obj) {
590 if (typeof obj[k] === 'object' && obj[k] != null) {
591 rst[k] = clone(obj[k]);
592 }
593 else {
594 rst[k] = obj[k];
595 }
596 }
597 }
598 return rst;
599 };
600
601 /**
602 * _.memoize(calColor);
603 * _.memoize(calColor, (...args) => args[0]);
604 * @param f
605 * @param resolver
606 */
607 var memoize = (function (f, resolver) {
608 if (!isFunction(f)) {
609 throw new TypeError('Expected a function');
610 }
611 var memoized = function () {
612 var args = [];
613 for (var _i = 0; _i < arguments.length; _i++) {
614 args[_i] = arguments[_i];
615 }
616 // 使用方法构造 key,如果不存在 resolver,则直接取第一个参数作为 key
617 var key = resolver ? resolver.apply(this, args) : args[0];
618 var cache = memoized.cache;
619 if (cache.has(key)) {
620 return cache.get(key);
621 }
622 var result = f.apply(this, args);
623 // 缓存起来
624 cache.set(key, result);
625 return result;
626 };
627 memoized.cache = new Map();
628 return memoized;
629 });
630
631 var MAX_MIX_LEVEL = 5;
632 function _deepMix(dist, src, level, maxLevel) {
633 level = level || 0;
634 maxLevel = maxLevel || MAX_MIX_LEVEL;
635 for (var key in src) {
636 if (src.hasOwnProperty(key)) {
637 var value = src[key];
638 if (value !== null && isPlainObject(value)) {
639 if (!isPlainObject(dist[key])) {
640 dist[key] = {};
641 }
642 if (level < maxLevel) {
643 _deepMix(dist[key], value, level + 1, maxLevel);
644 }
645 else {
646 dist[key] = src[key];
647 }
648 }
649 else if (isArray(value)) {
650 dist[key] = [];
651 dist[key] = dist[key].concat(value);
652 }
653 else if (value !== undefined) {
654 dist[key] = value;
655 }
656 }
657 }
658 }
659 // todo 重写
660 var deepMix = function (rst) {
661 var args = [];
662 for (var _i = 1; _i < arguments.length; _i++) {
663 args[_i - 1] = arguments[_i];
664 }
665 for (var i = 0; i < args.length; i += 1) {
666 _deepMix(rst, args[i]);
667 }
668 return rst;
669 };
670
671 var indexOf = function (arr, obj) {
672 if (!isArrayLike(arr)) {
673 return -1;
674 }
675 var m = Array.prototype.indexOf;
676 if (m) {
677 return m.call(arr, obj);
678 }
679 var index = -1;
680 for (var i = 0; i < arr.length; i++) {
681 if (arr[i] === obj) {
682 index = i;
683 break;
684 }
685 }
686 return index;
687 };
688
689 var hasOwnProperty$1 = Object.prototype.hasOwnProperty;
690 function isEmpty(value) {
691 /**
692 * isEmpty(null) => true
693 * isEmpty() => true
694 * isEmpty(true) => true
695 * isEmpty(1) => true
696 * isEmpty([1, 2, 3]) => false
697 * isEmpty('abc') => false
698 * isEmpty({ a: 1 }) => false
699 */
700 if (isNil(value)) {
701 return true;
702 }
703 if (isArrayLike(value)) {
704 return !value.length;
705 }
706 var type = getType(value);
707 if (type === 'Map' || type === 'Set') {
708 return !value.size;
709 }
710 if (isPrototype(value)) {
711 return !Object.keys(value).length;
712 }
713 for (var key in value) {
714 if (hasOwnProperty$1.call(value, key)) {
715 return false;
716 }
717 }
718 return true;
719 }
720
721 var map = function (arr, func) {
722 if (!isArrayLike(arr)) {
723 // @ts-ignore
724 return arr;
725 }
726 var result = [];
727 for (var index = 0; index < arr.length; index++) {
728 var value = arr[index];
729 result.push(func(value, index));
730 }
731 return result;
732 };
733
734 var identity = function (v) { return v; };
735 var mapValues = (function (object, func) {
736 if (func === void 0) { func = identity; }
737 var r = {};
738 if (isObject(object) && !isNil(object)) {
739 Object.keys(object).forEach(function (key) {
740 // @ts-ignore
741 r[key] = func(object[key], key);
742 });
743 }
744 return r;
745 });
746
747 /**
748 * https://github.com/developit/dlv/blob/master/index.js
749 * @param obj
750 * @param key
751 * @param defaultValue
752 */
753 var get = (function (obj, key, defaultValue) {
754 var p = 0;
755 var keyArr = isString(key) ? key.split('.') : key;
756 while (obj && p < keyArr.length) {
757 obj = obj[keyArr[p++]];
758 }
759 return (obj === undefined || p < keyArr.length) ? defaultValue : obj;
760 });
761
762 var hasOwnProperty$2 = Object.prototype.hasOwnProperty;
763 var pick = (function (object, keys) {
764 if (object === null || !isPlainObject(object)) {
765 return {};
766 }
767 var result = {};
768 each(keys, function (key) {
769 if (hasOwnProperty$2.call(object, key)) {
770 result[key] = object[key];
771 }
772 });
773 return result;
774 });
775
776 var omit = (function (obj, keys) {
777 return reduce(obj, function (r, curr, key) {
778 if (!keys.includes(key)) {
779 r[key] = curr;
780 }
781 return r;
782 }, {});
783 });
784
785 function size(o) {
786 if (isNil(o)) {
787 return 0;
788 }
789 if (isArrayLike(o)) {
790 return o.length;
791 }
792 return Object.keys(o).length;
793 }
794
795 /******************************************************************************
796 Copyright (c) Microsoft Corporation.
797
798 Permission to use, copy, modify, and/or distribute this software for any
799 purpose with or without fee is hereby granted.
800
801 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
802 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
803 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
804 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
805 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
806 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
807 PERFORMANCE OF THIS SOFTWARE.
808 ***************************************************************************** */
809 /* global Reflect, Promise */
810
811 var extendStatics = function(d, b) {
812 extendStatics = Object.setPrototypeOf ||
813 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
814 function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
815 return extendStatics(d, b);
816 };
817
818 function __extends(d, b) {
819 if (typeof b !== "function" && b !== null)
820 throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
821 extendStatics(d, b);
822 function __() { this.constructor = d; }
823 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
824 }
825
826 var __assign = function() {
827 __assign = Object.assign || function __assign(t) {
828 for (var s, i = 1, n = arguments.length; i < n; i++) {
829 s = arguments[i];
830 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
831 }
832 return t;
833 };
834 return __assign.apply(this, arguments);
835 };
836
837 /** @deprecated */
838 function __spreadArrays() {
839 for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
840 for (var r = Array(s), k = 0, i = 0; i < il; i++)
841 for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
842 r[k] = a[j];
843 return r;
844 }
845
846 var ctx;
847 /**
848 * 计算文本的宽度
849 */
850 memoize(function (text, font) {
851 if (font === void 0) { font = {}; }
852 var fontSize = font.fontSize, fontFamily = font.fontFamily, fontWeight = font.fontWeight, fontStyle = font.fontStyle, fontVariant = font.fontVariant;
853 if (!ctx) {
854 ctx = document.createElement('canvas').getContext('2d');
855 }
856 ctx.font = [fontStyle, fontVariant, fontWeight, fontSize + "px", fontFamily].join(' ');
857 return ctx.measureText(isString(text) ? text : '').width;
858 }, function (text, font) {
859 if (font === void 0) { font = {}; }
860 return __spreadArrays([text], values(font)).join('');
861 });
862
863 /**
864 * k-v 存储
865 */
866 var default_1 = /** @class */ (function () {
867 function default_1() {
868 this.map = {};
869 }
870 default_1.prototype.has = function (key) {
871 return this.map[key] !== undefined;
872 };
873 default_1.prototype.get = function (key, def) {
874 var v = this.map[key];
875 return v === undefined ? def : v;
876 };
877 default_1.prototype.set = function (key, value) {
878 this.map[key] = value;
879 };
880 default_1.prototype.clear = function () {
881 this.map = {};
882 };
883 default_1.prototype.delete = function (key) {
884 delete this.map[key];
885 };
886 default_1.prototype.size = function () {
887 return Object.keys(this.map).length;
888 };
889 return default_1;
890 }());
891
892 function cloneElement(element, props) {
893 if (!element) return element;
894 return _objectSpread(_objectSpread({}, element), {}, {
895 props: _objectSpread(_objectSpread({}, element.props), props)
896 });
897 }
898
899 function map$1(children, fn) {
900 if (!children) {
901 return fn(children);
902 }
903
904 if (isArray(children)) {
905 return children.map(function (child) {
906 return map$1(child, fn);
907 });
908 }
909
910 return fn(children);
911 }
912
913 function compareArray(nextElements, lastElements, callback) {
914 var keyed = {};
915 var nextLength = nextElements.length;
916 var lastLength = lastElements.length;
917
918 for (var i = 0, len = lastLength; i < len; i++) {
919 var element = lastElements[i];
920
921 if (element && !isNil(element.key)) {
922 var key = element.key;
923 keyed[key] = element;
924 }
925 } // 比较元素
926
927
928 for (var _i = 0, _len = Math.max(nextLength, lastLength); _i < _len; _i++) {
929 var _element = nextElements[_i];
930
931 if (!_element) {
932 compare(_element, lastElements[_i], callback);
933 continue;
934 }
935
936 var _key = _element.key; // 有key值定义
937
938 if (!isNil(_element.key)) {
939 var lastElement = keyed[_key];
940 if (lastElement) delete keyed[_key];
941 compare(_element, lastElement, callback);
942 continue;
943 }
944
945 compare(_element, lastElements[_i], callback);
946 } // 说明是删除的元素
947
948
949 Object.keys(keyed).forEach(function (key) {
950 compare(null, keyed[key], callback);
951 });
952 } // 比较2棵树
953
954
955 function compare(nextElement, lastElement, callback) {
956 // 有一个为空
957 if (!nextElement || !lastElement) {
958 callback(nextElement, lastElement);
959 return;
960 }
961
962 if (isArray(nextElement) || isArray(lastElement)) {
963 var nextElementArray = isArray(nextElement) ? nextElement : [nextElement];
964 var lastElementArray = isArray(lastElement) ? lastElement : [lastElement];
965 compareArray(nextElementArray, lastElementArray, callback);
966 return;
967 }
968
969 callback(nextElement, lastElement);
970 }
971
972 function toArray(element) {
973 if (!element) {
974 return element;
975 }
976
977 if (!isArray(element)) {
978 return [element];
979 }
980
981 var newArray = [];
982
983 for (var i = 0, len = element.length; i < len; i++) {
984 var item = element[i];
985
986 if (isArray(item)) {
987 // @ts-ignore
988 newArray = newArray.concat(toArray(item));
989 } else {
990 newArray.push(item);
991 }
992 }
993
994 return newArray;
995 }
996
997 var Children = {
998 cloneElement: cloneElement,
999 map: map$1,
1000 toArray: toArray,
1001 compare: compare
1002 };
1003
1004 var classCallCheck = createCommonjsModule(function (module) {
1005 function _classCallCheck(instance, Constructor) {
1006 if (!(instance instanceof Constructor)) {
1007 throw new TypeError("Cannot call a class as a function");
1008 }
1009 }
1010
1011 module.exports = _classCallCheck, module.exports.__esModule = true, module.exports["default"] = module.exports;
1012 });
1013
1014 var _classCallCheck = /*@__PURE__*/getDefaultExportFromCjs(classCallCheck);
1015
1016 var createClass = createCommonjsModule(function (module) {
1017 function _defineProperties(target, props) {
1018 for (var i = 0; i < props.length; i++) {
1019 var descriptor = props[i];
1020 descriptor.enumerable = descriptor.enumerable || false;
1021 descriptor.configurable = true;
1022 if ("value" in descriptor) descriptor.writable = true;
1023 Object.defineProperty(target, descriptor.key, descriptor);
1024 }
1025 }
1026
1027 function _createClass(Constructor, protoProps, staticProps) {
1028 if (protoProps) _defineProperties(Constructor.prototype, protoProps);
1029 if (staticProps) _defineProperties(Constructor, staticProps);
1030 Object.defineProperty(Constructor, "prototype", {
1031 writable: false
1032 });
1033 return Constructor;
1034 }
1035
1036 module.exports = _createClass, module.exports.__esModule = true, module.exports["default"] = module.exports;
1037 });
1038
1039 var _createClass = /*@__PURE__*/getDefaultExportFromCjs(createClass);
1040
1041 var Component = /*#__PURE__*/function () {
1042 function Component(props, context, updater) {
1043 _classCallCheck(this, Component);
1044
1045 this.destroyed = false;
1046 this.props = props;
1047 this.state = {};
1048 this.context = context;
1049 this.updater = updater;
1050 }
1051
1052 _createClass(Component, [{
1053 key: "willMount",
1054 value: function willMount() {}
1055 }, {
1056 key: "didMount",
1057 value: function didMount() {}
1058 }, {
1059 key: "willReceiveProps",
1060 value: function willReceiveProps(_props, context) {}
1061 }, {
1062 key: "willUpdate",
1063 value: function willUpdate() {}
1064 }, {
1065 key: "didUpdate",
1066 value: function didUpdate() {}
1067 }, {
1068 key: "render",
1069 value: function render() {
1070 return null;
1071 }
1072 }, {
1073 key: "didUnmount",
1074 value: function didUnmount() {}
1075 }, {
1076 key: "setState",
1077 value: function setState(partialState, callback) {
1078 this.updater.enqueueSetState(this, partialState, callback);
1079 }
1080 }, {
1081 key: "forceUpdate",
1082 value: function forceUpdate(callback) {
1083 this.updater.enqueueForceUpdate(this, {}, callback);
1084 }
1085 }, {
1086 key: "setAnimate",
1087 value: function setAnimate(animate) {
1088 this.animate = animate;
1089 }
1090 }, {
1091 key: "destroy",
1092 value: function destroy() {
1093 this.destroyed = true;
1094 }
1095 }]);
1096
1097 return Component;
1098 }(); // 标识是否是组件
1099 // @ts-ignore
1100
1101
1102 Component.prototype.isF2Component = true;
1103
1104 var assertThisInitialized = createCommonjsModule(function (module) {
1105 function _assertThisInitialized(self) {
1106 if (self === void 0) {
1107 throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
1108 }
1109
1110 return self;
1111 }
1112
1113 module.exports = _assertThisInitialized, module.exports.__esModule = true, module.exports["default"] = module.exports;
1114 });
1115
1116 var _assertThisInitialized = /*@__PURE__*/getDefaultExportFromCjs(assertThisInitialized);
1117
1118 var setPrototypeOf = createCommonjsModule(function (module) {
1119 function _setPrototypeOf(o, p) {
1120 module.exports = _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) {
1121 o.__proto__ = p;
1122 return o;
1123 }, module.exports.__esModule = true, module.exports["default"] = module.exports;
1124 return _setPrototypeOf(o, p);
1125 }
1126
1127 module.exports = _setPrototypeOf, module.exports.__esModule = true, module.exports["default"] = module.exports;
1128 });
1129
1130 var inherits = createCommonjsModule(function (module) {
1131 function _inherits(subClass, superClass) {
1132 if (typeof superClass !== "function" && superClass !== null) {
1133 throw new TypeError("Super expression must either be null or a function");
1134 }
1135
1136 subClass.prototype = Object.create(superClass && superClass.prototype, {
1137 constructor: {
1138 value: subClass,
1139 writable: true,
1140 configurable: true
1141 }
1142 });
1143 Object.defineProperty(subClass, "prototype", {
1144 writable: false
1145 });
1146 if (superClass) setPrototypeOf(subClass, superClass);
1147 }
1148
1149 module.exports = _inherits, module.exports.__esModule = true, module.exports["default"] = module.exports;
1150 });
1151
1152 var _inherits = /*@__PURE__*/getDefaultExportFromCjs(inherits);
1153
1154 var getPrototypeOf = createCommonjsModule(function (module) {
1155 function _getPrototypeOf(o) {
1156 module.exports = _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) {
1157 return o.__proto__ || Object.getPrototypeOf(o);
1158 }, module.exports.__esModule = true, module.exports["default"] = module.exports;
1159 return _getPrototypeOf(o);
1160 }
1161
1162 module.exports = _getPrototypeOf, module.exports.__esModule = true, module.exports["default"] = module.exports;
1163 });
1164
1165 var _getPrototypeOf = /*@__PURE__*/getDefaultExportFromCjs(getPrototypeOf);
1166
1167 var isNativeReflectConstruct = createCommonjsModule(function (module) {
1168 function _isNativeReflectConstruct() {
1169 if (typeof Reflect === "undefined" || !Reflect.construct) return false;
1170 if (Reflect.construct.sham) return false;
1171 if (typeof Proxy === "function") return true;
1172
1173 try {
1174 Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
1175 return true;
1176 } catch (e) {
1177 return false;
1178 }
1179 }
1180
1181 module.exports = _isNativeReflectConstruct, module.exports.__esModule = true, module.exports["default"] = module.exports;
1182 });
1183
1184 var _typeof_1 = createCommonjsModule(function (module) {
1185 function _typeof(obj) {
1186 "@babel/helpers - typeof";
1187
1188 return (module.exports = _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) {
1189 return typeof obj;
1190 } : function (obj) {
1191 return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
1192 }, module.exports.__esModule = true, module.exports["default"] = module.exports), _typeof(obj);
1193 }
1194
1195 module.exports = _typeof, module.exports.__esModule = true, module.exports["default"] = module.exports;
1196 });
1197
1198 var _typeof = /*@__PURE__*/getDefaultExportFromCjs(_typeof_1);
1199
1200 var possibleConstructorReturn = createCommonjsModule(function (module) {
1201 var _typeof = _typeof_1["default"];
1202
1203
1204
1205 function _possibleConstructorReturn(self, call) {
1206 if (call && (_typeof(call) === "object" || typeof call === "function")) {
1207 return call;
1208 } else if (call !== void 0) {
1209 throw new TypeError("Derived constructors may only return object or undefined");
1210 }
1211
1212 return assertThisInitialized(self);
1213 }
1214
1215 module.exports = _possibleConstructorReturn, module.exports.__esModule = true, module.exports["default"] = module.exports;
1216 });
1217
1218 var _possibleConstructorReturn = /*@__PURE__*/getDefaultExportFromCjs(possibleConstructorReturn);
1219
1220 var createSuper = createCommonjsModule(function (module) {
1221 function _createSuper(Derived) {
1222 var hasNativeReflectConstruct = isNativeReflectConstruct();
1223 return function _createSuperInternal() {
1224 var Super = getPrototypeOf(Derived),
1225 result;
1226
1227 if (hasNativeReflectConstruct) {
1228 var NewTarget = getPrototypeOf(this).constructor;
1229 result = Reflect.construct(Super, arguments, NewTarget);
1230 } else {
1231 result = Super.apply(this, arguments);
1232 }
1233
1234 return possibleConstructorReturn(this, result);
1235 };
1236 }
1237
1238 module.exports = _createSuper, module.exports.__esModule = true, module.exports["default"] = module.exports;
1239 });
1240
1241 var _createSuper = /*@__PURE__*/getDefaultExportFromCjs(createSuper);
1242
1243 var Timeline = /*#__PURE__*/function (_Component) {
1244 _inherits(Timeline, _Component);
1245
1246 var _super = _createSuper(Timeline);
1247
1248 function Timeline(props) {
1249 var _this;
1250
1251 _classCallCheck(this, Timeline);
1252
1253 _this = _super.call(this, props);
1254
1255 _this.next = function () {
1256 var _assertThisInitialize = _assertThisInitialized(_this),
1257 state = _assertThisInitialize.state,
1258 props = _assertThisInitialize.props;
1259
1260 var index = state.index,
1261 count = state.count,
1262 delay = state.delay;
1263 var loop = props.loop;
1264 var next = loop ? (index + 1) % count : index + 1;
1265
1266 if (next < count) {
1267 setTimeout(function () {
1268 _this.setState({
1269 index: next
1270 });
1271 }, delay || 0);
1272 }
1273 };
1274
1275 var delay = props.delay,
1276 _props$start = props.start,
1277 start = _props$start === void 0 ? 0 : _props$start,
1278 children = props.children;
1279 var count = Children.toArray(children).length;
1280 _this.state = {
1281 delay: delay,
1282 count: count,
1283 index: start
1284 };
1285 return _this;
1286 }
1287
1288 _createClass(Timeline, [{
1289 key: "didMount",
1290 value: function didMount() {
1291 var context = this.context;
1292 var root = context.root;
1293 root.on('animationEnd', this.next);
1294 }
1295 }, {
1296 key: "didUnmount",
1297 value: function didUnmount() {
1298 var context = this.context;
1299 var root = context.root;
1300 root.off('animationEnd', this.next);
1301 }
1302 }, {
1303 key: "render",
1304 value: function render() {
1305 var state = this.state,
1306 props = this.props;
1307 var children = props.children;
1308 var index = state.index;
1309 var childrenArray = Children.toArray(children);
1310 return childrenArray[index];
1311 }
1312 }]);
1313
1314 return Timeline;
1315 }(Component);
1316
1317 var Matrix = {
1318 generateDefault: function generateDefault() {
1319 return [1, 0, 0, 1, 0, 0];
1320 },
1321 isChanged: function isChanged(m) {
1322 return m[0] !== 1 || m[1] !== 0 || m[2] !== 0 || m[3] !== 1 || m[4] !== 0 || m[5] !== 0;
1323 },
1324 multiply: function multiply(m1, m2) {
1325 var m11 = m1[0] * m2[0] + m1[2] * m2[1];
1326 var m12 = m1[1] * m2[0] + m1[3] * m2[1];
1327 var m21 = m1[0] * m2[2] + m1[2] * m2[3];
1328 var m22 = m1[1] * m2[2] + m1[3] * m2[3];
1329 var dx = m1[0] * m2[4] + m1[2] * m2[5] + m1[4];
1330 var dy = m1[1] * m2[4] + m1[3] * m2[5] + m1[5];
1331 return [m11, m12, m21, m22, dx, dy];
1332 },
1333 scale: function scale(out, m, v) {
1334 out[0] = m[0] * v[0];
1335 out[1] = m[1] * v[0];
1336 out[2] = m[2] * v[1];
1337 out[3] = m[3] * v[1];
1338 out[4] = m[4];
1339 out[5] = m[5];
1340 return out;
1341 },
1342 rotate: function rotate(out, m, radian) {
1343 var c = Math.cos(radian);
1344 var s = Math.sin(radian);
1345 var m11 = m[0] * c + m[2] * s;
1346 var m12 = m[1] * c + m[3] * s;
1347 var m21 = m[0] * -s + m[2] * c;
1348 var m22 = m[1] * -s + m[3] * c;
1349 out[0] = m11;
1350 out[1] = m12;
1351 out[2] = m21;
1352 out[3] = m22;
1353 out[4] = m[4];
1354 out[5] = m[5];
1355 return out;
1356 },
1357 translate: function translate(out, m, v) {
1358 out[0] = m[0];
1359 out[1] = m[1];
1360 out[2] = m[2];
1361 out[3] = m[3];
1362 out[4] = m[4] + m[0] * v[0] + m[2] * v[1];
1363 out[5] = m[5] + m[1] * v[0] + m[3] * v[1];
1364 return out;
1365 },
1366 transform: function transform(m, actions) {
1367 var out = [].concat(m);
1368
1369 for (var i = 0, len = actions.length; i < len; i++) {
1370 var action = actions[i];
1371
1372 switch (action[0]) {
1373 case 't':
1374 Matrix.translate(out, out, [action[1], action[2]]);
1375 break;
1376
1377 case 's':
1378 Matrix.scale(out, out, [action[1], action[2]]);
1379 break;
1380
1381 case 'r':
1382 Matrix.rotate(out, out, action[1]);
1383 break;
1384 }
1385 }
1386
1387 return out;
1388 }
1389 };
1390
1391 /**
1392 * 2 Dimensional Vector
1393 * @module vector2
1394 */
1395 var Vector2 = {
1396 /**
1397 * Creates a new, empty vector2
1398 *
1399 * @return {vector2} a new 2D vector
1400 */
1401 create: function create() {
1402 return [0, 0];
1403 },
1404
1405 /**
1406 * Calculates the length of a vector2
1407 *
1408 * @param {vector2} v vector to calculate length of
1409 * @return {Number} length of v
1410 */
1411 length: function length(v) {
1412 var x = v[0];
1413 var y = v[1];
1414 return Math.sqrt(x * x + y * y);
1415 },
1416
1417 /**
1418 * Normalize a vector2
1419 *
1420 * @param {vector2} out the receiving vector
1421 * @param {vector2} v vector to normalize
1422 * @return {vector2} out
1423 */
1424 normalize: function normalize(out, v) {
1425 var len = this.length(v);
1426
1427 if (len === 0) {
1428 out[0] = 0;
1429 out[1] = 0;
1430 } else {
1431 out[0] = v[0] / len;
1432 out[1] = v[1] / len;
1433 }
1434
1435 return out;
1436 },
1437
1438 /**
1439 * Adds two vector2's
1440 *
1441 * @param {vector2} out the receiving vector
1442 * @param {vector2} v1 the first operand
1443 * @param {vector2} v2 the second operand
1444 * @return {vector2} out
1445 */
1446 add: function add(out, v1, v2) {
1447 out[0] = v1[0] + v2[0];
1448 out[1] = v1[1] + v2[1];
1449 return out;
1450 },
1451
1452 /**
1453 * Subtracts vector v2 from vector v1
1454 *
1455 * @param {vector2} out the receiving vector
1456 * @param {vector2} v1 the first operand
1457 * @param {vector2} v2 the second operand
1458 * @return {vector2} out
1459 */
1460 sub: function sub(out, v1, v2) {
1461 out[0] = v1[0] - v2[0];
1462 out[1] = v1[1] - v2[1];
1463 return out;
1464 },
1465
1466 /**
1467 * Scales a vector2 by a scalar number
1468 *
1469 * @param {vector2} out the receiving vector
1470 * @param {vector2} v the vector to scale
1471 * @param {Number} s amount to scale the vector by
1472 * @return {vector2} out
1473 */
1474 scale: function scale(out, v, s) {
1475 out[0] = v[0] * s;
1476 out[1] = v[1] * s;
1477 return out;
1478 },
1479
1480 /**
1481 * Calculates the dot product of two vector2's
1482 *
1483 * @param {vector2} v1 the first operand
1484 * @param {vector2} v2 the second operand
1485 * @return {Number} dot product of v1 and v2
1486 */
1487 dot: function dot(v1, v2) {
1488 return v1[0] * v2[0] + v1[1] * v2[1];
1489 },
1490
1491 /**
1492 * Calculates the direction of two vector2's
1493 *
1494 * @param {vector2} v1 the first operand
1495 * @param {vector2} v2 the second operand
1496 * @return {Boolean} the direction of v1 and v2
1497 */
1498 direction: function direction(v1, v2) {
1499 return v1[0] * v2[1] - v2[0] * v1[1];
1500 },
1501
1502 /**
1503 * Calculates the angle of two vector2's
1504 *
1505 * @param {vector2} v1 the first operand
1506 * @param {vector2} v2 the second operand
1507 * @return {Number} angle of v1 and v2
1508 */
1509 angle: function angle(v1, v2) {
1510 var theta = this.dot(v1, v2) / (this.length(v1) * this.length(v2));
1511 return Math.acos(theta);
1512 },
1513
1514 /**
1515 * Calculates the angle of two vector2's with direction
1516 *
1517 * @param {vector2} v1 the first operand
1518 * @param {vector2} v2 the second operand
1519 * @param {Boolean} direction the direction of two vector2's
1520 * @return {Number} angle of v1 and v2
1521 */
1522 angleTo: function angleTo(v1, v2, direction) {
1523 var angle = this.angle(v1, v2);
1524 var angleLargeThanPI = this.direction(v1, v2) >= 0;
1525
1526 if (direction) {
1527 if (angleLargeThanPI) {
1528 return Math.PI * 2 - angle;
1529 }
1530
1531 return angle;
1532 }
1533
1534 if (angleLargeThanPI) {
1535 return angle;
1536 }
1537
1538 return Math.PI * 2 - angle;
1539 },
1540
1541 /**
1542 * whether a vector2 is zero vector
1543 *
1544 * @param {vector2} v vector to calculate
1545 * @return {Boolean} is or not a zero vector
1546 */
1547 zero: function zero(v) {
1548 return v[0] === 0 && v[1] === 0;
1549 },
1550
1551 /**
1552 * Calculates the euclidian distance between two vector2's
1553 *
1554 * @param {vector2} v1 the first operand
1555 * @param {vector2} v2 the second operand
1556 * @return {Number} distance between a and b
1557 */
1558 distance: function distance(v1, v2) {
1559 var x = v2[0] - v1[0];
1560 var y = v2[1] - v1[1];
1561 return Math.sqrt(x * x + y * y);
1562 },
1563
1564 /**
1565 * Creates a new vector2 initialized with values from an existing vector
1566 *
1567 * @param {vector2} v vector to clone
1568 * @return {Array} a new 2D vector
1569 */
1570 clone: function clone(v) {
1571 return [v[0], v[1]];
1572 },
1573
1574 /**
1575 * Return the minimum of two vector2's
1576 *
1577 * @param {vector2} out the receiving vector
1578 * @param {vector2} v1 the first operand
1579 * @param {vector2} v2 the second operand
1580 * @return {vector2} out
1581 */
1582 min: function min(out, v1, v2) {
1583 out[0] = Math.min(v1[0], v2[0]);
1584 out[1] = Math.min(v1[1], v2[1]);
1585 return out;
1586 },
1587
1588 /**
1589 * Return the maximum of two vector2's
1590 *
1591 * @param {vector2} out the receiving vector
1592 * @param {vector2} v1 the first operand
1593 * @param {vector2} v2 the second operand
1594 * @return {vector2} out
1595 */
1596 max: function max(out, v1, v2) {
1597 out[0] = Math.max(v1[0], v2[0]);
1598 out[1] = Math.max(v1[1], v2[1]);
1599 return out;
1600 },
1601
1602 /**
1603 * Transforms the vector2 with a mat2d
1604 *
1605 * @param {vector2} out the receiving vector
1606 * @param {vector2} v the vector to transform
1607 * @param {mat2d} m matrix to transform with
1608 * @return {vector2} out
1609 */
1610 transformMat2d: function transformMat2d(out, v, m) {
1611 var x = v[0];
1612 var y = v[1];
1613 out[0] = m[0] * x + m[2] * y + m[4];
1614 out[1] = m[1] * x + m[3] * y + m[5];
1615 return out;
1616 }
1617 };
1618
1619 /**
1620 * @fileOverview convert the line to curve
1621 * @author dxq613@gmail.com
1622 */
1623
1624 function getPoint(v) {
1625 return [v.x, v.y];
1626 }
1627
1628 function smoothBezier(points, smooth, isLoop, constraint) {
1629 var cps = [];
1630 var prevPoint;
1631 var nextPoint;
1632 var hasConstraint = !!constraint;
1633 var min;
1634 var max;
1635 var point;
1636 var len;
1637 var l;
1638 var i;
1639
1640 if (hasConstraint) {
1641 min = [Infinity, Infinity];
1642 max = [-Infinity, -Infinity];
1643
1644 for (i = 0, l = points.length; i < l; i++) {
1645 point = getPoint(points[i]);
1646 Vector2.min(min, min, point);
1647 Vector2.max(max, max, point);
1648 }
1649
1650 Vector2.min(min, min, constraint[0]);
1651 Vector2.max(max, max, constraint[1]);
1652 }
1653
1654 for (i = 0, len = points.length; i < len; i++) {
1655 point = getPoint(points[i]);
1656
1657 if (isLoop) {
1658 prevPoint = getPoint(points[i ? i - 1 : len - 1]);
1659 nextPoint = getPoint(points[(i + 1) % len]);
1660 } else {
1661 if (i === 0 || i === len - 1) {
1662 cps.push([point[0], point[1]]);
1663 continue;
1664 } else {
1665 prevPoint = getPoint(points[i - 1]);
1666 nextPoint = getPoint(points[i + 1]);
1667 }
1668 }
1669
1670 var v = Vector2.sub([], nextPoint, prevPoint);
1671 Vector2.scale(v, v, smooth);
1672 var d0 = Vector2.distance(point, prevPoint);
1673 var d1 = Vector2.distance(point, nextPoint);
1674 var sum = d0 + d1;
1675
1676 if (sum !== 0) {
1677 d0 /= sum;
1678 d1 /= sum;
1679 }
1680
1681 var v1 = Vector2.scale([], v, -d0);
1682 var v2 = Vector2.scale([], v, d1);
1683 var cp0 = Vector2.add([], point, v1);
1684 var cp1 = Vector2.add([], point, v2);
1685
1686 if (hasConstraint) {
1687 Vector2.max(cp0, cp0, min);
1688 Vector2.min(cp0, cp0, max);
1689 Vector2.max(cp1, cp1, min);
1690 Vector2.min(cp1, cp1, max);
1691 }
1692
1693 cps.push([cp0[0], cp0[1]]);
1694 cps.push([cp1[0], cp1[1]]);
1695 }
1696
1697 if (isLoop) {
1698 cps.push(cps.shift());
1699 }
1700
1701 return cps;
1702 }
1703
1704 function catmullRom2bezier(pointList, z, constraint) {
1705 var isLoop = !!z;
1706 var controlPointList = smoothBezier(pointList, 0.4, isLoop, constraint);
1707 var len = pointList.length;
1708 var d1 = [];
1709 var cp1;
1710 var cp2;
1711 var p;
1712
1713 for (var i = 0; i < len - 1; i++) {
1714 cp1 = controlPointList[i * 2];
1715 cp2 = controlPointList[i * 2 + 1];
1716 p = pointList[i + 1];
1717 d1.push(['C', cp1[0], cp1[1], cp2[0], cp2[1], p.x, p.y]);
1718 }
1719
1720 if (isLoop) {
1721 cp1 = controlPointList[len];
1722 cp2 = controlPointList[len + 1];
1723 p = pointList[0];
1724 d1.push(['C', cp1[0], cp1[1], cp2[0], cp2[1], p.x, p.y]);
1725 }
1726
1727 return d1;
1728 }
1729
1730 var start = Vector2.create();
1731 var end = Vector2.create();
1732 var extremity = Vector2.create();
1733
1734 function getCubicBezierXYatT(startPt, controlPt1, controlPt2, endPt, T) {
1735 var x = CubicN(T, startPt.x, controlPt1.x, controlPt2.x, endPt.x);
1736 var y = CubicN(T, startPt.y, controlPt1.y, controlPt2.y, endPt.y);
1737 return {
1738 x: x,
1739 y: y
1740 };
1741 } // cubic helper formula at T distance
1742
1743
1744 function CubicN(T, a, b, c, d) {
1745 var t2 = T * T;
1746 var t3 = t2 * T;
1747 return a + (-a * 3 + T * (3 * a - a * T)) * T + (3 * b + T * (-6 * b + b * 3 * T)) * T + (c * 3 - c * 3 * T) * t2 + d * t3;
1748 }
1749
1750 function cubicBezierBounds(c) {
1751 var minX = Infinity;
1752 var maxX = -Infinity;
1753 var minY = Infinity;
1754 var maxY = -Infinity;
1755 var s = {
1756 x: c[0],
1757 y: c[1]
1758 };
1759 var c1 = {
1760 x: c[2],
1761 y: c[3]
1762 };
1763 var c2 = {
1764 x: c[4],
1765 y: c[5]
1766 };
1767 var e = {
1768 x: c[6],
1769 y: c[7]
1770 };
1771
1772 for (var t = 0; t < 100; t++) {
1773 var pt = getCubicBezierXYatT(s, c1, c2, e, t / 100);
1774
1775 if (pt.x < minX) {
1776 minX = pt.x;
1777 }
1778
1779 if (pt.x > maxX) {
1780 maxX = pt.x;
1781 }
1782
1783 if (pt.y < minY) {
1784 minY = pt.y;
1785 }
1786
1787 if (pt.y > maxY) {
1788 maxY = pt.y;
1789 }
1790 }
1791
1792 return {
1793 minX: minX,
1794 minY: minY,
1795 maxX: maxX,
1796 maxY: maxY
1797 };
1798 }
1799
1800 function getBBoxFromPoints(points, lineWidth) {
1801 if (points.length === 0) {
1802 return;
1803 }
1804
1805 var p = points[0];
1806 var left = p.x;
1807 var right = p.x;
1808 var top = p.y;
1809 var bottom = p.y;
1810 var len = points.length;
1811
1812 for (var i = 1; i < len; i++) {
1813 p = points[i];
1814 left = Math.min(left, p.x);
1815 right = Math.max(right, p.x);
1816 top = Math.min(top, p.y);
1817 bottom = Math.max(bottom, p.y);
1818 }
1819
1820 lineWidth = lineWidth / 2 || 0;
1821 return {
1822 minX: left - lineWidth,
1823 minY: top - lineWidth,
1824 maxX: right + lineWidth,
1825 maxY: bottom + lineWidth
1826 };
1827 }
1828
1829 function getBBoxFromLine(x0, y0, x1, y1, lineWidth) {
1830 lineWidth = lineWidth / 2 || 0;
1831 return {
1832 minX: Math.min(x0, x1) - lineWidth,
1833 minY: Math.min(y0, y1) - lineWidth,
1834 maxX: Math.max(x0, x1) + lineWidth,
1835 maxY: Math.max(y0, y1) + lineWidth
1836 };
1837 }
1838
1839 function getBBoxFromArc(x, y, r, startAngle, endAngle, anticlockwise) {
1840 var diff = Math.abs(startAngle - endAngle);
1841
1842 if (diff % (Math.PI * 2) < 1e-4 && diff > 1e-4) {
1843 // Is a circle
1844 return {
1845 minX: x - r,
1846 minY: y - r,
1847 maxX: x + r,
1848 maxY: y + r
1849 };
1850 }
1851
1852 start[0] = Math.cos(startAngle) * r + x;
1853 start[1] = Math.sin(startAngle) * r + y;
1854 end[0] = Math.cos(endAngle) * r + x;
1855 end[1] = Math.sin(endAngle) * r + y;
1856 var min = [0, 0];
1857 var max = [0, 0];
1858 Vector2.min(min, start, end);
1859 Vector2.max(max, start, end); // Thresh to [0, Math.PI * 2]
1860
1861 startAngle = startAngle % (Math.PI * 2);
1862
1863 if (startAngle < 0) {
1864 startAngle = startAngle + Math.PI * 2;
1865 }
1866
1867 endAngle = endAngle % (Math.PI * 2);
1868
1869 if (endAngle < 0) {
1870 endAngle = endAngle + Math.PI * 2;
1871 }
1872
1873 if (startAngle > endAngle && !anticlockwise) {
1874 endAngle += Math.PI * 2;
1875 } else if (startAngle < endAngle && anticlockwise) {
1876 startAngle += Math.PI * 2;
1877 }
1878
1879 if (anticlockwise) {
1880 var tmp = endAngle;
1881 endAngle = startAngle;
1882 startAngle = tmp;
1883 }
1884
1885 for (var angle = 0; angle < endAngle; angle += Math.PI / 2) {
1886 if (angle > startAngle) {
1887 extremity[0] = Math.cos(angle) * r + x;
1888 extremity[1] = Math.sin(angle) * r + y;
1889 Vector2.min(min, extremity, min);
1890 Vector2.max(max, extremity, max);
1891 }
1892 }
1893
1894 return {
1895 minX: min[0],
1896 minY: min[1],
1897 maxX: max[0],
1898 maxY: max[1]
1899 };
1900 }
1901
1902 function getBBoxFromBezierGroup(points, lineWidth) {
1903 var minX = Infinity;
1904 var maxX = -Infinity;
1905 var minY = Infinity;
1906 var maxY = -Infinity;
1907
1908 for (var i = 0, len = points.length; i < len; i++) {
1909 var bbox = cubicBezierBounds(points[i]);
1910
1911 if (bbox.minX < minX) {
1912 minX = bbox.minX;
1913 }
1914
1915 if (bbox.maxX > maxX) {
1916 maxX = bbox.maxX;
1917 }
1918
1919 if (bbox.minY < minY) {
1920 minY = bbox.minY;
1921 }
1922
1923 if (bbox.maxY > maxY) {
1924 maxY = bbox.maxY;
1925 }
1926 }
1927
1928 lineWidth = lineWidth / 2 || 0;
1929 return {
1930 minX: minX - lineWidth,
1931 minY: minY - lineWidth,
1932 maxX: maxX + lineWidth,
1933 maxY: maxY + lineWidth
1934 };
1935 }
1936
1937 function _classCallCheck$1(instance, Constructor) {
1938 if (!(instance instanceof Constructor)) {
1939 throw new TypeError("Cannot call a class as a function");
1940 }
1941 }
1942
1943 function _defineProperties(target, props) {
1944 for (var i = 0; i < props.length; i++) {
1945 var descriptor = props[i];
1946 descriptor.enumerable = descriptor.enumerable || false;
1947 descriptor.configurable = true;
1948 if ("value" in descriptor) descriptor.writable = true;
1949 Object.defineProperty(target, descriptor.key, descriptor);
1950 }
1951 }
1952
1953 function _createClass$1(Constructor, protoProps, staticProps) {
1954 if (protoProps) _defineProperties(Constructor.prototype, protoProps);
1955 if (staticProps) _defineProperties(Constructor, staticProps);
1956 Object.defineProperty(Constructor, "prototype", {
1957 writable: false
1958 });
1959 return Constructor;
1960 }
1961
1962 function _setPrototypeOf(o, p) {
1963 _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) {
1964 o.__proto__ = p;
1965 return o;
1966 };
1967 return _setPrototypeOf(o, p);
1968 }
1969
1970 function _inherits$1(subClass, superClass) {
1971 if (typeof superClass !== "function" && superClass !== null) {
1972 throw new TypeError("Super expression must either be null or a function");
1973 }
1974
1975 subClass.prototype = Object.create(superClass && superClass.prototype, {
1976 constructor: {
1977 value: subClass,
1978 writable: true,
1979 configurable: true
1980 }
1981 });
1982 Object.defineProperty(subClass, "prototype", {
1983 writable: false
1984 });
1985 if (superClass) _setPrototypeOf(subClass, superClass);
1986 }
1987
1988 function _getPrototypeOf$1(o) {
1989 _getPrototypeOf$1 = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) {
1990 return o.__proto__ || Object.getPrototypeOf(o);
1991 };
1992 return _getPrototypeOf$1(o);
1993 }
1994
1995 function _isNativeReflectConstruct() {
1996 if (typeof Reflect === "undefined" || !Reflect.construct) return false;
1997 if (Reflect.construct.sham) return false;
1998 if (typeof Proxy === "function") return true;
1999
2000 try {
2001 Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
2002 return true;
2003 } catch (e) {
2004 return false;
2005 }
2006 }
2007
2008 function _typeof$1(obj) {
2009 "@babel/helpers - typeof";
2010
2011 return _typeof$1 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) {
2012 return typeof obj;
2013 } : function (obj) {
2014 return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
2015 }, _typeof$1(obj);
2016 }
2017
2018 function _assertThisInitialized$1(self) {
2019 if (self === void 0) {
2020 throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
2021 }
2022
2023 return self;
2024 }
2025
2026 function _possibleConstructorReturn$1(self, call) {
2027 if (call && (_typeof$1(call) === "object" || typeof call === "function")) {
2028 return call;
2029 } else if (call !== void 0) {
2030 throw new TypeError("Derived constructors may only return object or undefined");
2031 }
2032
2033 return _assertThisInitialized$1(self);
2034 }
2035
2036 function _createSuper$1(Derived) {
2037 var hasNativeReflectConstruct = _isNativeReflectConstruct();
2038 return function _createSuperInternal() {
2039 var Super = _getPrototypeOf$1(Derived),
2040 result;
2041
2042 if (hasNativeReflectConstruct) {
2043 var NewTarget = _getPrototypeOf$1(this).constructor;
2044 result = Reflect.construct(Super, arguments, NewTarget);
2045 } else {
2046 result = Super.apply(this, arguments);
2047 }
2048
2049 return _possibleConstructorReturn$1(this, result);
2050 };
2051 }
2052
2053 var EventEmit = /*#__PURE__*/function () {
2054 function EventEmit() {
2055 _classCallCheck$1(this, EventEmit);
2056
2057 this.__events = {};
2058 }
2059
2060 _createClass$1(EventEmit, [{
2061 key: "on",
2062 value: function on(type, listener) {
2063 if (!type || !listener) {
2064 return;
2065 }
2066
2067 var events = this.__events[type] || [];
2068 events.push(listener);
2069 this.__events[type] = events;
2070 }
2071 }, {
2072 key: "emit",
2073 value: function emit(type, e) {
2074 var _this = this;
2075
2076 if (isObject(type)) {
2077 e = type;
2078 type = e && e.type;
2079 }
2080
2081 if (!type) {
2082 return;
2083 }
2084
2085 var events = this.__events[type];
2086
2087 if (!events || !events.length) {
2088 return;
2089 }
2090
2091 events.forEach(function (listener) {
2092 listener.call(_this, e);
2093 });
2094 }
2095 }, {
2096 key: "off",
2097 value: function off(type, listener) {
2098 var __events = this.__events;
2099 var events = __events[type];
2100
2101 if (!events || !events.length) {
2102 return;
2103 } // 如果没有指定方法,则删除所有项
2104
2105
2106 if (!listener) {
2107 delete __events[type];
2108 return;
2109 } // 删除指定的 listener
2110
2111
2112 for (var i = 0, len = events.length; i < len; i++) {
2113 if (events[i] === listener) {
2114 events.splice(i, 1);
2115 i--;
2116 }
2117 }
2118 }
2119 }]);
2120
2121 return EventEmit;
2122 }();
2123
2124 /**
2125 * Detects support for options object argument in addEventListener.
2126 * https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Safely_detecting_option_support
2127 * @private
2128 */
2129
2130 var supportsEventListenerOptions = function () {
2131 var supports = false;
2132
2133 try {
2134 var options = Object.defineProperty({}, 'passive', {
2135 get: function get() {
2136 supports = true;
2137 }
2138 });
2139 window.addEventListener('e', null, options);
2140 } catch (e) {// continue regardless of error
2141 }
2142
2143 return supports;
2144 }(); // Default passive to true as expected by Chrome for 'touchstart' and 'touchend' events.
2145 /* global wx, my */
2146 // weixin miniprogram
2147 // @ts-ignore
2148
2149 var isWx = (typeof wx === "undefined" ? "undefined" : _typeof$1(wx)) === 'object' && typeof wx.getSystemInfoSync === 'function'; // ant miniprogram
2150 // @ts-ignore
2151
2152 var isMy = (typeof my === "undefined" ? "undefined" : _typeof$1(my)) === 'object' && typeof my.getSystemInfoSync === 'function'; // in node
2153 // @ts-ignore
2154
2155 var isNode = (typeof global === "undefined" ? "undefined" : _typeof$1(global)) && !(typeof window === "undefined" ? "undefined" : _typeof$1(window)); // in browser
2156
2157 function isCanvasElement(el) {
2158 if (!el || _typeof$1(el) !== 'object') return false;
2159
2160 if (el.nodeType === 1 && el.nodeName) {
2161 // HTMLCanvasElement
2162 return true;
2163 } // CanvasElement
2164
2165
2166 return !!el.isCanvasElement;
2167 }
2168
2169 function getPixelRatio() {
2170 return window && window.devicePixelRatio || 1;
2171 }
2172
2173 function getStyle(el, property) {
2174 return el.currentStyle ? el.currentStyle[property] : document.defaultView.getComputedStyle(el, null).getPropertyValue(property);
2175 }
2176
2177 function getWidth(el) {
2178 var width = getStyle(el, 'width');
2179
2180 if (width === 'auto') {
2181 width = el.offsetWidth;
2182 }
2183
2184 return parseFloat(width);
2185 }
2186
2187 function getHeight(el) {
2188 var height = getStyle(el, 'height');
2189
2190 if (height === 'auto') {
2191 height = el.offsetHeight;
2192 }
2193
2194 return parseFloat(height);
2195 }
2196
2197 function getDomById(id) {
2198 if (!id) {
2199 return null;
2200 }
2201
2202 return document.getElementById(id);
2203 }
2204
2205 function getRelativePosition(point, canvas) {
2206 var canvasDom = canvas.get('el');
2207 if (!canvasDom) return point;
2208
2209 var _canvasDom$getBoundin = canvasDom.getBoundingClientRect(),
2210 top = _canvasDom$getBoundin.top,
2211 left = _canvasDom$getBoundin.left;
2212
2213 var paddingLeft = parseFloat(getStyle(canvasDom, 'padding-left'));
2214 var paddingTop = parseFloat(getStyle(canvasDom, 'padding-top'));
2215 var mouseX = point.x - left - paddingLeft;
2216 var mouseY = point.y - top - paddingTop;
2217 return {
2218 x: mouseX,
2219 y: mouseY
2220 };
2221 }
2222
2223 function landscapePoint(point, canvas) {
2224 var landscape = canvas.get('landscape');
2225
2226 if (!landscape) {
2227 return point;
2228 }
2229
2230 if (isFunction(landscape)) {
2231 return landscape(point, canvas);
2232 } // 默认顺时针旋转90度
2233
2234
2235 var height = canvas.get('height');
2236 var x = point.y;
2237 var y = height - point.x;
2238 return {
2239 x: x,
2240 y: y
2241 };
2242 }
2243
2244 function convertPoints(ev, canvas) {
2245 var touches = ev.touches; // 认为是mouse事件
2246
2247 if (!touches) {
2248 var point = getRelativePosition({
2249 x: ev.clientX,
2250 y: ev.clientY
2251 }, canvas);
2252 return [landscapePoint(point, canvas)];
2253 } // 单指 touchend 后,touchs 会变空,最后的触点要从changedTouches里拿
2254
2255
2256 if (!touches.length) {
2257 // 为了防止万一,加个空逻辑
2258 touches = ev.changedTouches || [];
2259 }
2260
2261 var points = [];
2262
2263 for (var i = 0, len = touches.length; i < len; i++) {
2264 var touch = touches[i]; // x, y: 相对canvas原点的位置,clientX, clientY 相对于可视窗口的位置
2265
2266 var x = touch.x,
2267 y = touch.y,
2268 clientX = touch.clientX,
2269 clientY = touch.clientY;
2270
2271 var _point = void 0; // 小程序环境会有x,y
2272
2273
2274 if (isNumber(x) || isNumber(y)) {
2275 _point = {
2276 x: x,
2277 y: y
2278 };
2279 } else {
2280 // 浏览器环境再计算下canvas的相对位置
2281 _point = getRelativePosition({
2282 x: clientX,
2283 y: clientY
2284 }, canvas);
2285 }
2286
2287 points.push(landscapePoint(_point, canvas));
2288 }
2289
2290 return points;
2291 }
2292
2293 function measureText(text, font, ctx) {
2294 if (!ctx) {
2295 ctx = document.createElement('canvas').getContext('2d');
2296 }
2297
2298 ctx.font = font || '12px sans-serif';
2299 return ctx.measureText(text);
2300 }
2301
2302 var convertPoints$1 = convertPoints; // 计算滑动的方向
2303
2304 var calcDirection = function calcDirection(start, end) {
2305 var xDistance = end.x - start.x;
2306 var yDistance = end.y - start.y; // x 的距离大于y 说明是横向,否则就是纵向
2307
2308 if (Math.abs(xDistance) > Math.abs(yDistance)) {
2309 return xDistance > 0 ? 'right' : 'left';
2310 }
2311
2312 return yDistance > 0 ? 'down' : 'up';
2313 }; // 计算2点之间的距离
2314
2315
2316 var calcDistance = function calcDistance(point1, point2) {
2317 var xDistance = Math.abs(point2.x - point1.x);
2318 var yDistance = Math.abs(point2.y - point1.y);
2319 return Math.sqrt(xDistance * xDistance + yDistance * yDistance);
2320 };
2321
2322 var getCenter = function getCenter(point1, point2) {
2323 var x = point1.x + (point2.x - point1.x) / 2;
2324 var y = point1.y + (point2.y - point1.y) / 2;
2325 return {
2326 x: x,
2327 y: y
2328 };
2329 };
2330
2331 var PRESS_DELAY = 250;
2332
2333 var EventController = /*#__PURE__*/function () {
2334 function EventController(_ref) {
2335 var _this = this;
2336
2337 var canvas = _ref.canvas,
2338 el = _ref.el;
2339
2340 _classCallCheck$1(this, EventController);
2341
2342 this._click = function (ev) {
2343 var points = convertPoints$1(ev, _this.canvas);
2344 ev.points = points;
2345
2346 _this.emitEvent('click', ev);
2347 };
2348
2349 this._start = function (ev) {
2350 var points = convertPoints$1(ev, _this.canvas);
2351
2352 if (!points) {
2353 return;
2354 }
2355
2356 ev.points = points;
2357
2358 _this.emitEvent('touchstart', ev); // 防止上次的内容没有清理掉,重新reset下
2359
2360
2361 _this.reset(); // 记录touch start 的时间
2362
2363
2364 _this.startTime = Date.now(); // 记录touch start 的点
2365
2366 _this.startPoints = points;
2367
2368 if (points.length > 1) {
2369 _this.startDistance = calcDistance(points[0], points[1]);
2370 _this.center = getCenter(points[0], points[1]);
2371 } else {
2372 // 如果touchstart后停顿250ms, 则也触发press事件
2373 _this.pressTimeout = setTimeout(function () {
2374 // 这里固定触发press事件
2375 var eventType = 'press';
2376 var direction = 'none';
2377 ev.direction = direction;
2378
2379 _this.emitStart(eventType, ev);
2380
2381 _this.emitEvent(eventType, ev);
2382
2383 _this.eventType = eventType;
2384 _this.direction = direction;
2385 }, PRESS_DELAY);
2386 }
2387 };
2388
2389 this._move = function (ev) {
2390 var points = convertPoints$1(ev, _this.canvas);
2391 if (!points) return;
2392
2393 _this.clearPressTimeout();
2394
2395 ev.points = points;
2396
2397 _this.emitEvent('touchmove', ev);
2398
2399 var startPoints = _this.startPoints;
2400 if (!startPoints) return; // 多指触控
2401
2402 if (points.length > 1) {
2403 // touchstart的距离
2404 var startDistance = _this.startDistance;
2405 var currentDistance = calcDistance(points[0], points[1]);
2406 ev.zoom = currentDistance / startDistance;
2407 ev.center = _this.center; // 触发缩放事件
2408
2409 _this.emitStart('pinch', ev);
2410
2411 _this.emitEvent('pinch', ev);
2412 } else {
2413 var deltaX = points[0].x - startPoints[0].x;
2414 var deltaY = points[0].y - startPoints[0].y;
2415 var direction = _this.direction || calcDirection(startPoints[0], points[0]);
2416 _this.direction = direction; // 获取press或者pan的事件类型
2417 // press 按住滑动, pan表示平移
2418 // 如果start后立刻move,则触发pan, 如果有停顿,则触发press
2419
2420 var eventType = _this.getEventType(points);
2421
2422 ev.direction = direction;
2423 ev.deltaX = deltaX;
2424 ev.deltaY = deltaY;
2425
2426 _this.emitStart(eventType, ev);
2427
2428 _this.emitEvent(eventType, ev); // 记录最后2次move的时间和坐标,为了给swipe事件用
2429
2430
2431 var prevMoveTime = _this.lastMoveTime;
2432 var now = Date.now(); // 最后2次的时间间隔一定要大于0,否则swipe没发计算
2433
2434 if (now - prevMoveTime > 0) {
2435 _this.prevMoveTime = prevMoveTime;
2436 _this.prevMovePoints = _this.lastMovePoints;
2437 _this.lastMoveTime = now;
2438 _this.lastMovePoints = points;
2439 }
2440 }
2441 };
2442
2443 this._end = function (ev) {
2444 var points = convertPoints$1(ev, _this.canvas);
2445 ev.points = points;
2446
2447 _this.emitEnd(ev);
2448
2449 _this.emitEvent('touchend', ev); // swipe事件处理, 在touchend之后触发
2450
2451
2452 var lastMoveTime = _this.lastMoveTime;
2453 var now = Date.now(); // 做这个判断是为了最后一次touchmove后到end前,还有一个停顿的过程
2454 // 100 是拍的一个值,理论这个值会很短,一般不卡顿的话在10ms以内
2455
2456 if (now - lastMoveTime < 100) {
2457 var prevMoveTime = _this.prevMoveTime || _this.startTime;
2458 var intervalTime = lastMoveTime - prevMoveTime; // 时间间隔一定要大于0, 否则计算没意义
2459
2460 if (intervalTime > 0) {
2461 var prevMovePoints = _this.prevMovePoints || _this.startPoints;
2462 var lastMovePoints = _this.lastMovePoints; // move速率
2463
2464 var velocity = calcDistance(prevMovePoints[0], lastMovePoints[0]) / intervalTime; // 0.3 是参考hammerjs的设置
2465
2466 if (velocity > 0.3) {
2467 ev.velocity = velocity;
2468 ev.direction = calcDirection(prevMovePoints[0], lastMovePoints[0]);
2469 ev.velocityX = (lastMovePoints[0].x - prevMovePoints[0].x) / intervalTime;
2470 ev.velocityY = (lastMovePoints[0].y - prevMovePoints[0].y) / intervalTime;
2471
2472 _this.emitEvent('swipe', ev);
2473 }
2474 }
2475 }
2476
2477 _this.reset();
2478
2479 var touches = ev.touches; // 当多指只释放了1指时也会触发end, 这时重新触发一次start
2480
2481 if (touches && touches.length > 0) {
2482 _this._start(ev);
2483 }
2484 };
2485
2486 this._cancel = function (ev) {
2487 _this.emitEvent('touchcancel', ev);
2488
2489 _this.reset();
2490 }; // canvasEl
2491
2492
2493 this.canvas = canvas;
2494 this.delegateEvent(el); // 用来记录当前触发的事件
2495
2496 this.processEvent = {};
2497 }
2498
2499 _createClass$1(EventController, [{
2500 key: "delegateEvent",
2501 value: function delegateEvent(canvasEl) {
2502 // 代理这几个事件
2503 canvasEl.addEventListener('click', this._click);
2504 canvasEl.addEventListener('touchstart', this._start);
2505 canvasEl.addEventListener('touchmove', this._move);
2506 canvasEl.addEventListener('touchend', this._end);
2507 canvasEl.addEventListener('touchcancel', this._cancel);
2508 }
2509 }, {
2510 key: "emitEvent",
2511 value: function emitEvent(type, ev) {
2512 var canvas = this.canvas;
2513 canvas.emit(type, ev);
2514 }
2515 }, {
2516 key: "getEventType",
2517 value: function getEventType(points) {
2518 var eventType = this.eventType,
2519 canvas = this.canvas,
2520 startTime = this.startTime,
2521 startPoints = this.startPoints;
2522
2523 if (eventType) {
2524 return eventType;
2525 }
2526
2527 var type;
2528 var panEventListeners = canvas.__events.pan; // 如果没有pan事件的监听,默认都是press
2529
2530 if (!panEventListeners || !panEventListeners.length) {
2531 type = 'press';
2532 } else {
2533 // 如果有pan事件的处理,press则需要停顿250ms, 且移动距离小于10
2534 var now = Date.now();
2535
2536 if (now - startTime > PRESS_DELAY && calcDistance(startPoints[0], points[0]) < 10) {
2537 type = 'press';
2538 } else {
2539 type = 'pan';
2540 }
2541 }
2542
2543 this.eventType = type;
2544 return type;
2545 }
2546 }, {
2547 key: "enable",
2548 value: function enable(eventType) {
2549 this.processEvent[eventType] = true;
2550 } // 是否进行中的事件
2551
2552 }, {
2553 key: "isProcess",
2554 value: function isProcess(eventType) {
2555 return this.processEvent[eventType];
2556 } // 触发start事件
2557
2558 }, {
2559 key: "emitStart",
2560 value: function emitStart(type, ev) {
2561 if (this.isProcess(type)) {
2562 return;
2563 }
2564
2565 this.enable(type);
2566 this.emitEvent("".concat(type, "start"), ev);
2567 } // 触发end事件
2568
2569 }, {
2570 key: "emitEnd",
2571 value: function emitEnd(ev) {
2572 var _this2 = this;
2573
2574 var processEvent = this.processEvent;
2575 Object.keys(processEvent).forEach(function (type) {
2576 _this2.emitEvent("".concat(type, "end"), ev);
2577
2578 delete processEvent[type];
2579 });
2580 }
2581 }, {
2582 key: "clearPressTimeout",
2583 value: function clearPressTimeout() {
2584 if (this.pressTimeout) {
2585 clearTimeout(this.pressTimeout);
2586 this.pressTimeout = null;
2587 }
2588 }
2589 }, {
2590 key: "reset",
2591 value: function reset() {
2592 this.clearPressTimeout();
2593 this.startTime = 0;
2594 this.startPoints = null;
2595 this.startDistance = 0;
2596 this.direction = null;
2597 this.eventType = null;
2598 this.pinch = false;
2599 this.prevMoveTime = 0;
2600 this.prevMovePoints = null;
2601 this.lastMoveTime = 0;
2602 this.lastMovePoints = null;
2603 }
2604 }]);
2605
2606 return EventController;
2607 }();
2608
2609 var CanvasElement = /*#__PURE__*/function (_EventEmit) {
2610 _inherits$1(CanvasElement, _EventEmit);
2611
2612 var _super = _createSuper$1(CanvasElement);
2613 /* eslint-enable */
2614
2615
2616 function CanvasElement(ctx) {
2617 var _this;
2618
2619 _classCallCheck$1(this, CanvasElement);
2620
2621 _this = _super.call(this);
2622 _this.context = ctx; // canvas实际的宽高 (width/height) * pixelRatio
2623 // 有可能是 node canvas 创建的 context 对象
2624
2625 var canvas = ctx.canvas || {};
2626 _this.width = canvas.width || 0;
2627 _this.height = canvas.height || 0;
2628 _this.style = {};
2629 _this.currentStyle = {};
2630 _this.attrs = {}; // 用来标识是CanvasElement实例
2631
2632 _this.isCanvasElement = true;
2633 return _this;
2634 }
2635
2636 _createClass$1(CanvasElement, [{
2637 key: "getContext",
2638 value: function
2639 /* type */
2640 getContext() {
2641 return this.context;
2642 }
2643 }, {
2644 key: "getBoundingClientRect",
2645 value: function getBoundingClientRect() {
2646 var width = this.width;
2647 var height = this.height; // 默认都处理成可视窗口的顶部位置
2648
2649 return {
2650 top: 0,
2651 right: width,
2652 bottom: height,
2653 left: 0
2654 };
2655 }
2656 }, {
2657 key: "setAttribute",
2658 value: function setAttribute(key, value) {
2659 this.attrs[key] = value;
2660 }
2661 }, {
2662 key: "addEventListener",
2663 value: function addEventListener(type, listener) {
2664 this.on(type, listener);
2665 }
2666 }, {
2667 key: "removeEventListener",
2668 value: function removeEventListener(type, listener) {
2669 this.off(type, listener);
2670 }
2671 }, {
2672 key: "dispatchEvent",
2673 value: function dispatchEvent(type, e) {
2674 this.emit(type, e);
2675 }
2676 }]);
2677
2678 return CanvasElement;
2679 }(EventEmit);
2680
2681 function supportEventListener(canvas) {
2682 if (!canvas) {
2683 return false;
2684 } // 非 HTMLCanvasElement
2685
2686
2687 if (canvas.nodeType !== 1 || !canvas.nodeName || canvas.nodeName.toLowerCase() !== 'canvas') {
2688 return false;
2689 } // 微信小程序canvas.getContext('2d')时也是CanvasRenderingContext2D
2690 // 也会有ctx.canvas, 而且nodeType也是1,所以还要在看下是否支持addEventListener
2691
2692
2693 var support = false;
2694
2695 try {
2696 canvas.addEventListener('eventTest', function () {
2697 support = true;
2698 });
2699 canvas.dispatchEvent(new Event('eventTest'));
2700 } catch (error) {
2701 support = false;
2702 }
2703
2704 return support;
2705 }
2706
2707 var CanvasElement$1 = {
2708 create: function create(ctx) {
2709 if (!ctx) {
2710 return null;
2711 }
2712
2713 if (supportEventListener(ctx.canvas)) {
2714 return ctx.canvas;
2715 }
2716
2717 return new CanvasElement(ctx);
2718 }
2719 };
2720
2721 function remove(arr, obj) {
2722 if (!arr) {
2723 return;
2724 }
2725
2726 var index = arr.indexOf(obj);
2727
2728 if (index !== -1) {
2729 arr.splice(index, 1);
2730 }
2731 }
2732
2733 function _defineProperty$1(obj, key, value) {
2734 if (key in obj) {
2735 Object.defineProperty(obj, key, {
2736 value: value,
2737 enumerable: true,
2738 configurable: true,
2739 writable: true
2740 });
2741 } else {
2742 obj[key] = value;
2743 }
2744
2745 return obj;
2746 }
2747
2748 function ownKeys(object, enumerableOnly) {
2749 var keys = Object.keys(object);
2750
2751 if (Object.getOwnPropertySymbols) {
2752 var symbols = Object.getOwnPropertySymbols(object);
2753 enumerableOnly && (symbols = symbols.filter(function (sym) {
2754 return Object.getOwnPropertyDescriptor(object, sym).enumerable;
2755 })), keys.push.apply(keys, symbols);
2756 }
2757
2758 return keys;
2759 }
2760
2761 function _objectSpread2(target) {
2762 for (var i = 1; i < arguments.length; i++) {
2763 var source = null != arguments[i] ? arguments[i] : {};
2764 i % 2 ? ownKeys(Object(source), !0).forEach(function (key) {
2765 _defineProperty$1(target, key, source[key]);
2766 }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) {
2767 Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
2768 });
2769 }
2770
2771 return target;
2772 }
2773
2774 function _mod(n, m) {
2775 return (n % m + m) % m;
2776 }
2777
2778 function _addStop(steps, gradient) {
2779 each(steps, function (item) {
2780 item = item.split(':');
2781 gradient.addColorStop(Number(item[0]), item[1]);
2782 });
2783 } // the string format: 'l(0) 0:#ffffff 0.5:#7ec2f3 1:#1890ff'
2784
2785
2786 function _parseLineGradient(color, shape, context) {
2787 var arr = color.split(' ');
2788 var angle = arr[0].slice(2, arr[0].length - 1);
2789 angle = _mod(parseFloat(angle) * Math.PI / 180, Math.PI * 2);
2790 var steps = arr.slice(1);
2791
2792 var _shape$getBBox = shape.getBBox(),
2793 minX = _shape$getBBox.minX,
2794 minY = _shape$getBBox.minY,
2795 maxX = _shape$getBBox.maxX,
2796 maxY = _shape$getBBox.maxY;
2797
2798 var start;
2799 var end;
2800
2801 if (angle >= 0 && angle < 0.5 * Math.PI) {
2802 start = {
2803 x: minX,
2804 y: minY
2805 };
2806 end = {
2807 x: maxX,
2808 y: maxY
2809 };
2810 } else if (0.5 * Math.PI <= angle && angle < Math.PI) {
2811 start = {
2812 x: maxX,
2813 y: minY
2814 };
2815 end = {
2816 x: minX,
2817 y: maxY
2818 };
2819 } else if (Math.PI <= angle && angle < 1.5 * Math.PI) {
2820 start = {
2821 x: maxX,
2822 y: maxY
2823 };
2824 end = {
2825 x: minX,
2826 y: minY
2827 };
2828 } else {
2829 start = {
2830 x: minX,
2831 y: maxY
2832 };
2833 end = {
2834 x: maxX,
2835 y: minY
2836 };
2837 }
2838
2839 var tanTheta = Math.tan(angle);
2840 var tanTheta2 = tanTheta * tanTheta;
2841 var x = (end.x - start.x + tanTheta * (end.y - start.y)) / (tanTheta2 + 1) + start.x;
2842 var y = tanTheta * (end.x - start.x + tanTheta * (end.y - start.y)) / (tanTheta2 + 1) + start.y;
2843 var gradient = context.createLinearGradient(start.x, start.y, x, y);
2844
2845 _addStop(steps, gradient);
2846
2847 return gradient;
2848 } // the string format: 'r(0.5, 0.5, 0.1) 0:#ffffff 1:#1890ff'
2849
2850
2851 function _parseRadialGradient(color, shape, context) {
2852 var arr = color.split(' ');
2853 var circleCfg = arr[0].slice(2, arr[0].length - 1);
2854 circleCfg = circleCfg.split(',');
2855 var fx = parseFloat(circleCfg[0]);
2856 var fy = parseFloat(circleCfg[1]);
2857 var fr = parseFloat(circleCfg[2]);
2858 var steps = arr.slice(1); // if radius is 0, no gradient, stroke with the last color
2859
2860 if (fr === 0) {
2861 var _color = steps[steps.length - 1];
2862 return _color.split(':')[1];
2863 }
2864
2865 var _shape$getBBox2 = shape.getBBox(),
2866 width = _shape$getBBox2.width,
2867 height = _shape$getBBox2.height,
2868 minX = _shape$getBBox2.minX,
2869 minY = _shape$getBBox2.minY;
2870
2871 var r = Math.sqrt(width * width + height * height) / 2;
2872 var gradient = context.createRadialGradient(minX + width * fx, minY + height * fy, fr * r, minX + width / 2, minY + height / 2, r);
2873
2874 _addStop(steps, gradient);
2875
2876 return gradient;
2877 }
2878
2879 function parseStyle(color, shape, context) {
2880 if (color[1] === '(') {
2881 try {
2882 var firstCode = color[0];
2883
2884 if (firstCode === 'l') {
2885 return _parseLineGradient(color, shape, context);
2886 } else if (firstCode === 'r') {
2887 return _parseRadialGradient(color, shape, context);
2888 }
2889 } catch (ev) {
2890 console.error('error in parsing gradient string, please check if there are any extra whitespaces.');
2891 console.error(ev);
2892 }
2893 }
2894
2895 return color;
2896 }
2897
2898 var ALIAS_ATTRS_MAP = {
2899 stroke: 'strokeStyle',
2900 fill: 'fillStyle',
2901 opacity: 'globalAlpha'
2902 };
2903 var SHAPE_ATTRS = ['fillStyle', 'font', 'globalAlpha', 'lineCap', 'lineWidth', 'lineJoin', 'miterLimit', 'shadowBlur', 'shadowColor', 'shadowOffsetX', 'shadowOffsetY', 'strokeStyle', 'textAlign', 'textBaseline', 'lineDash', 'shadow' // 兼容支付宝小程序
2904 ];
2905 var CLIP_SHAPES = ['circle', 'sector', 'polygon', 'rect', 'polyline', 'custom'];
2906
2907 var Element = /*#__PURE__*/function () {
2908 function Element(cfg) {
2909 _classCallCheck$1(this, Element);
2910
2911 this._initProperties();
2912
2913 mix(this._attrs, cfg);
2914 var attrs = this._attrs.attrs;
2915
2916 if (attrs) {
2917 this.initAttrs(attrs);
2918 }
2919
2920 this.initTransform();
2921 }
2922
2923 _createClass$1(Element, [{
2924 key: "_initProperties",
2925 value: function _initProperties() {
2926 this._attrs = _objectSpread2(_objectSpread2({}, this._attrs), {}, {
2927 zIndex: 0,
2928 visible: true,
2929 destroyed: false
2930 });
2931 }
2932 }, {
2933 key: "get",
2934 value: function get(name) {
2935 return this._attrs[name];
2936 }
2937 }, {
2938 key: "set",
2939 value: function set(name, value) {
2940 this._attrs[name] = value;
2941 }
2942 }, {
2943 key: "isGroup",
2944 value: function isGroup() {
2945 return this.get('isGroup');
2946 }
2947 }, {
2948 key: "isShape",
2949 value: function isShape() {
2950 return this.get('isShape');
2951 }
2952 }, {
2953 key: "initAttrs",
2954 value: function initAttrs(attrs) {
2955 this.attr(mix(this.getDefaultAttrs(), attrs));
2956 }
2957 }, {
2958 key: "getDefaultAttrs",
2959 value: function getDefaultAttrs() {
2960 return {};
2961 }
2962 }, {
2963 key: "_setAttr",
2964 value: function _setAttr(name, value) {
2965 var attrs = this._attrs.attrs;
2966
2967 if (name === 'clip') {
2968 value = this._setAttrClip(value);
2969 } else {
2970 var alias = ALIAS_ATTRS_MAP[name];
2971
2972 if (alias) {
2973 attrs[alias] = value;
2974 }
2975 }
2976
2977 attrs[name] = value;
2978 }
2979 }, {
2980 key: "_getAttr",
2981 value: function _getAttr(name) {
2982 var _this$_attrs, _this$_attrs$attrs;
2983
2984 return (_this$_attrs = this._attrs) === null || _this$_attrs === void 0 ? void 0 : (_this$_attrs$attrs = _this$_attrs.attrs) === null || _this$_attrs$attrs === void 0 ? void 0 : _this$_attrs$attrs[name];
2985 }
2986 }, {
2987 key: "_afterAttrsSet",
2988 value: function _afterAttrsSet() {}
2989 }, {
2990 key: "_setAttrClip",
2991 value: function _setAttrClip(clip) {
2992 if (clip && CLIP_SHAPES.indexOf(clip._attrs.type) > -1) {
2993 if (clip.get('canvas') === null) {
2994 clip = _objectSpread2({}, clip);
2995 }
2996
2997 clip.set('parent', this.get('parent'));
2998 clip.set('context', this.get('context'));
2999 return clip;
3000 }
3001
3002 return null;
3003 }
3004 }, {
3005 key: "attr",
3006 value: function attr(name, value) {
3007 if (this.get('destroyed')) return null;
3008 var argumentsLen = arguments.length;
3009
3010 if (argumentsLen === 0) {
3011 return this._attrs.attrs;
3012 }
3013
3014 if (isObject(name)) {
3015 this._attrs.bbox = null;
3016
3017 for (var k in name) {
3018 this._setAttr(k, name[k]);
3019 }
3020
3021 if (this._afterAttrsSet) {
3022 this._afterAttrsSet();
3023 }
3024
3025 return this;
3026 }
3027
3028 if (argumentsLen === 2) {
3029 this._attrs.bbox = null;
3030
3031 this._setAttr(name, value);
3032
3033 if (this._afterAttrsSet) {
3034 this._afterAttrsSet();
3035 }
3036
3037 return this;
3038 }
3039
3040 return this._getAttr(name);
3041 }
3042 }, {
3043 key: "getParent",
3044 value: function getParent() {
3045 return this.get('parent');
3046 }
3047 }, {
3048 key: "draw",
3049 value: function draw(context) {
3050 if (this.get('destroyed')) {
3051 return;
3052 }
3053
3054 if (this.get('visible')) {
3055 this.setContext(context);
3056 this.drawInner(context);
3057 this.restoreContext(context);
3058 }
3059 }
3060 }, {
3061 key: "setContext",
3062 value: function setContext(context) {
3063 var clip = this._attrs.attrs.clip;
3064 context.save();
3065
3066 if (clip && !clip._attrs.destroyed) {
3067 clip.resetTransform(context);
3068 clip.createPath(context);
3069 context.clip();
3070 }
3071
3072 this.resetContext(context);
3073 this.resetTransform(context);
3074 }
3075 }, {
3076 key: "restoreContext",
3077 value: function restoreContext(context) {
3078 context.restore();
3079 }
3080 }, {
3081 key: "resetContext",
3082 value: function resetContext(context) {
3083 var elAttrs = this._attrs.attrs;
3084
3085 for (var k in elAttrs) {
3086 if (SHAPE_ATTRS.indexOf(k) > -1) {
3087 var v = elAttrs[k];
3088
3089 if ((k === 'fillStyle' || k === 'strokeStyle') && v) {
3090 v = parseStyle(v, this, context);
3091 }
3092
3093 if (k === 'lineDash' && context.setLineDash && isArray(v)) {
3094 context.setLineDash(v);
3095 } else {
3096 context[k] = v;
3097 }
3098 }
3099 }
3100 }
3101 }, {
3102 key: "hasFill",
3103 value: function hasFill() {
3104 return this.get('canFill') && this._attrs.attrs.fillStyle;
3105 }
3106 }, {
3107 key: "hasStroke",
3108 value: function hasStroke() {
3109 return this.get('canStroke') && this._attrs.attrs.strokeStyle;
3110 }
3111 }, {
3112 key: "drawInner",
3113 value: function drawInner(_context) {}
3114 }, {
3115 key: "show",
3116 value: function show() {
3117 this.set('visible', true);
3118 return this;
3119 }
3120 }, {
3121 key: "hide",
3122 value: function hide() {
3123 this.set('visible', false);
3124 return this;
3125 }
3126 }, {
3127 key: "isVisible",
3128 value: function isVisible() {
3129 return this.get('visible');
3130 }
3131 }, {
3132 key: "getAriaLabel",
3133 value: function getAriaLabel() {
3134 var _this$_attrs2 = this._attrs,
3135 destroyed = _this$_attrs2.destroyed,
3136 visible = _this$_attrs2.visible,
3137 isShape = _this$_attrs2.isShape,
3138 aria = _this$_attrs2.aria;
3139
3140 if (destroyed || !visible || isShape && !aria) {
3141 return;
3142 }
3143
3144 return this._getAriaLabel();
3145 }
3146 }, {
3147 key: "_getAriaLabel",
3148 value: function _getAriaLabel() {
3149 return this._attrs.ariaLabel;
3150 }
3151 }, {
3152 key: "_removeFromParent",
3153 value: function _removeFromParent() {
3154 var parent = this.get('parent');
3155
3156 if (parent) {
3157 var children = parent.get('children');
3158 remove(children, this);
3159 }
3160
3161 return this;
3162 }
3163 }, {
3164 key: "remove",
3165 value: function remove(destroy) {
3166 if (destroy) {
3167 this.destroy();
3168 } else {
3169 this._removeFromParent();
3170 }
3171 }
3172 }, {
3173 key: "destroy",
3174 value: function destroy() {
3175 var destroyed = this.get('destroyed');
3176
3177 if (destroyed) {
3178 return null;
3179 }
3180
3181 this._removeFromParent();
3182
3183 this._attrs = {};
3184 this.set('destroyed', true);
3185 }
3186 }, {
3187 key: "getBBox",
3188 value: function getBBox() {
3189 return {
3190 minX: 0,
3191 maxX: 0,
3192 minY: 0,
3193 maxY: 0,
3194 width: 0,
3195 height: 0
3196 };
3197 }
3198 }, {
3199 key: "initTransform",
3200 value: function initTransform() {
3201 var attrs = this._attrs.attrs;
3202
3203 if (!attrs) {
3204 attrs = {};
3205 }
3206
3207 if (!attrs.matrix) {
3208 attrs.matrix = [1, 0, 0, 1, 0, 0];
3209 }
3210
3211 this._attrs.attrs = attrs;
3212 }
3213 }, {
3214 key: "getMatrix",
3215 value: function getMatrix() {
3216 return this._attrs.attrs.matrix;
3217 }
3218 }, {
3219 key: "setMatrix",
3220 value: function setMatrix(m) {
3221 this._attrs.attrs.matrix = [m[0], m[1], m[2], m[3], m[4], m[5]];
3222 }
3223 }, {
3224 key: "transform",
3225 value: function transform(actions) {
3226 var matrix = this._attrs.attrs.matrix;
3227 this._attrs.attrs.matrix = Matrix.transform(matrix, actions);
3228 return this;
3229 }
3230 }, {
3231 key: "setTransform",
3232 value: function setTransform(actions) {
3233 this._attrs.attrs.matrix = [1, 0, 0, 1, 0, 0];
3234 return this.transform(actions);
3235 }
3236 }, {
3237 key: "translate",
3238 value: function translate(x, y) {
3239 var matrix = this._attrs.attrs.matrix;
3240 Matrix.translate(matrix, matrix, [x, y]);
3241 }
3242 }, {
3243 key: "rotate",
3244 value: function rotate(rad) {
3245 var matrix = this._attrs.attrs.matrix;
3246 Matrix.rotate(matrix, matrix, rad);
3247 }
3248 }, {
3249 key: "scale",
3250 value: function scale(sx, sy) {
3251 var matrix = this._attrs.attrs.matrix;
3252 Matrix.scale(matrix, matrix, [sx, sy]);
3253 }
3254 }, {
3255 key: "moveTo",
3256 value: function moveTo(x, y) {
3257 var cx = this._attrs.x || 0;
3258 var cy = this._attrs.y || 0;
3259 this.translate(x - cx, y - cy);
3260 this.set('x', x);
3261 this.set('y', y);
3262 }
3263 }, {
3264 key: "apply",
3265 value: function apply(v) {
3266 var m = this._attrs.attrs.matrix;
3267 Vector2.transformMat2d(v, v, m);
3268 return this;
3269 }
3270 }, {
3271 key: "resetTransform",
3272 value: function resetTransform(context) {
3273 var mo = this._attrs.attrs.matrix;
3274
3275 if (Matrix.isChanged(mo)) {
3276 context.transform(mo[0], mo[1], mo[2], mo[3], mo[4], mo[5]);
3277 }
3278 }
3279 }, {
3280 key: "isDestroyed",
3281 value: function isDestroyed() {
3282 return this.get('destroyed');
3283 }
3284 }]);
3285
3286 return Element;
3287 }();
3288
3289 var Shape = /*#__PURE__*/function (_Element) {
3290 _inherits$1(Shape, _Element);
3291
3292 var _super = _createSuper$1(Shape);
3293
3294 function Shape() {
3295 _classCallCheck$1(this, Shape);
3296
3297 return _super.apply(this, arguments);
3298 }
3299
3300 _createClass$1(Shape, [{
3301 key: "_initProperties",
3302 value:
3303 /* eslint-enable */
3304 function _initProperties() {
3305 this._attrs = _objectSpread2(_objectSpread2({}, this._attrs), {}, {
3306 zIndex: 0,
3307 visible: true,
3308 destroyed: false,
3309 isShape: true,
3310 attrs: {}
3311 });
3312 }
3313 }, {
3314 key: "getType",
3315 value: function getType() {
3316 return this._attrs.type;
3317 }
3318 }, {
3319 key: "drawInner",
3320 value: function drawInner(context) {
3321 var attrs = this.get('attrs');
3322 this.createPath(context);
3323 var originOpacity = context.globalAlpha;
3324
3325 if (this.hasFill()) {
3326 var fillOpacity = attrs.fillOpacity;
3327
3328 if (!isNil(fillOpacity) && fillOpacity !== 1) {
3329 context.globalAlpha = fillOpacity;
3330 context.fill();
3331 context.globalAlpha = originOpacity;
3332 } else {
3333 context.fill();
3334 }
3335 }
3336
3337 if (this.hasStroke()) {
3338 var lineWidth = attrs.lineWidth;
3339
3340 if (lineWidth > 0) {
3341 var strokeOpacity = attrs.strokeOpacity;
3342
3343 if (!isNil(strokeOpacity) && strokeOpacity !== 1) {
3344 context.globalAlpha = strokeOpacity;
3345 }
3346
3347 context.stroke();
3348 }
3349 }
3350 }
3351 }, {
3352 key: "getBBox",
3353 value: function getBBox() {
3354 var bbox = this._attrs.bbox;
3355
3356 if (!bbox) {
3357 bbox = this.calculateBox();
3358
3359 if (bbox) {
3360 bbox.x = bbox.minX;
3361 bbox.y = bbox.minY;
3362 bbox.width = bbox.maxX - bbox.minX;
3363 bbox.height = bbox.maxY - bbox.minY;
3364 }
3365
3366 this._attrs.bbox = bbox;
3367 }
3368
3369 return bbox;
3370 }
3371 }, {
3372 key: "calculateBox",
3373 value: function calculateBox() {
3374 return null;
3375 }
3376 }, {
3377 key: "createPath",
3378 value: function createPath(_context) {}
3379 }]);
3380
3381 return Shape;
3382 }(Element);
3383
3384 function _superPropBase(object, property) {
3385 while (!Object.prototype.hasOwnProperty.call(object, property)) {
3386 object = _getPrototypeOf$1(object);
3387 if (object === null) break;
3388 }
3389
3390 return object;
3391 }
3392
3393 function _get() {
3394 if (typeof Reflect !== "undefined" && Reflect.get) {
3395 _get = Reflect.get.bind();
3396 } else {
3397 _get = function _get(target, property, receiver) {
3398 var base = _superPropBase(target, property);
3399 if (!base) return;
3400 var desc = Object.getOwnPropertyDescriptor(base, property);
3401
3402 if (desc.get) {
3403 return desc.get.call(arguments.length < 3 ? target : receiver);
3404 }
3405
3406 return desc.value;
3407 };
3408 }
3409
3410 return _get.apply(this, arguments);
3411 }
3412
3413 function parsePadding(padding) {
3414 var top = 0;
3415 var right = 0;
3416 var bottom = 0;
3417 var left = 0;
3418
3419 if (isNumber(padding)) {
3420 top = bottom = left = right = padding;
3421 } else if (isArray(padding)) {
3422 top = padding[0];
3423 right = !isNil(padding[1]) ? padding[1] : padding[0];
3424 bottom = !isNil(padding[2]) ? padding[2] : padding[0];
3425 left = !isNil(padding[3]) ? padding[3] : right;
3426 }
3427
3428 return [top, right, bottom, left];
3429 } // 为了处理radius 大于 width 或 height 的场景
3430
3431
3432 function parseRadius(radius, width, height) {
3433 radius = parsePadding(radius); // 都为0
3434
3435 if (!radius[0] && !radius[1] && !radius[2] && !radius[3]) {
3436 return radius;
3437 }
3438
3439 var minWidth = Math.max(radius[0] + radius[1], radius[2] + radius[3]);
3440 var minHeight = Math.max(radius[0] + radius[3], radius[1] + radius[2]);
3441 var scale = Math.min(width / minWidth, height / minHeight);
3442
3443 if (scale < 1) {
3444 return radius.map(function (r) {
3445 return r * scale;
3446 });
3447 }
3448
3449 return radius;
3450 }
3451
3452 var Rect = /*#__PURE__*/function (_Shape) {
3453 _inherits$1(Rect, _Shape);
3454
3455 var _super = _createSuper$1(Rect);
3456
3457 function Rect() {
3458 _classCallCheck$1(this, Rect);
3459
3460 return _super.apply(this, arguments);
3461 }
3462
3463 _createClass$1(Rect, [{
3464 key: "_initProperties",
3465 value: function _initProperties() {
3466 _get(_getPrototypeOf$1(Rect.prototype), "_initProperties", this).call(this);
3467
3468 this._attrs.canFill = true;
3469 this._attrs.canStroke = true;
3470 this._attrs.type = 'rect';
3471 }
3472 }, {
3473 key: "getDefaultAttrs",
3474 value: function getDefaultAttrs() {
3475 return {
3476 x: 0,
3477 y: 0,
3478 width: 0,
3479 height: 0,
3480 radius: 0,
3481 lineWidth: 0
3482 };
3483 }
3484 }, {
3485 key: "createRadiusPath",
3486 value: function createRadiusPath(context, x, y, width, height, radius) {
3487 radius = parseRadius(radius, width, height);
3488 context.moveTo(x + radius[0], y);
3489 context.lineTo(x + width - radius[1], y);
3490 context.arc(x + width - radius[1], y + radius[1], radius[1], -Math.PI / 2, 0, false);
3491 context.lineTo(x + width, y + height - radius[2]);
3492 context.arc(x + width - radius[2], y + height - radius[2], radius[2], 0, Math.PI / 2, false);
3493 context.lineTo(x + radius[3], y + height);
3494 context.arc(x + radius[3], y + height - radius[3], radius[3], Math.PI / 2, Math.PI, false);
3495 context.lineTo(x, y + radius[0]);
3496 context.arc(x + radius[0], y + radius[0], radius[0], Math.PI, Math.PI * 3 / 2, false);
3497 context.closePath();
3498 }
3499 }, {
3500 key: "createPath",
3501 value: function createPath(context) {
3502 var attrs = this.get('attrs');
3503 var x = attrs.x,
3504 y = attrs.y,
3505 width = attrs.width,
3506 height = attrs.height,
3507 radius = attrs.radius;
3508 context.beginPath();
3509
3510 if (!radius || !(width * height)) {
3511 context.rect(x, y, width, height);
3512 } else {
3513 this.createRadiusPath(context, x, y, width, height, radius);
3514 }
3515 }
3516 }, {
3517 key: "calculateBox",
3518 value: function calculateBox() {
3519 var attrs = this.get('attrs');
3520 var x = attrs.x,
3521 y = attrs.y,
3522 width = attrs.width,
3523 height = attrs.height;
3524 return {
3525 minX: x,
3526 minY: y,
3527 maxX: x + width,
3528 maxY: y + height
3529 };
3530 }
3531 }]);
3532
3533 return Rect;
3534 }(Shape);
3535
3536 var imageCaches = {};
3537
3538 var ImageShape = /*#__PURE__*/function (_Rect) {
3539 _inherits$1(ImageShape, _Rect);
3540
3541 var _super = _createSuper$1(ImageShape);
3542
3543 function ImageShape() {
3544 _classCallCheck$1(this, ImageShape);
3545
3546 return _super.apply(this, arguments);
3547 }
3548
3549 _createClass$1(ImageShape, [{
3550 key: "_initProperties",
3551 value: function _initProperties() {
3552 _get(_getPrototypeOf$1(ImageShape.prototype), "_initProperties", this).call(this);
3553
3554 this._attrs.canFill = false;
3555 this._attrs.canStroke = false;
3556 this._attrs.loading = false;
3557 this._attrs.image = null;
3558 this._attrs.type = 'image';
3559 }
3560 }, {
3561 key: "draw",
3562 value: function draw(context) {
3563 var _this = this; // 如果图片还在loading中直接返回,等下次绘制
3564
3565
3566 if (this.get('loading')) {
3567 return;
3568 } // 如果已经有image对象,直接绘制,会调用createPath绘制
3569
3570
3571 var image = this.get('image');
3572
3573 if (image) {
3574 _get(_getPrototypeOf$1(ImageShape.prototype), "draw", this).call(this, context);
3575
3576 return;
3577 }
3578
3579 var attrs = this.get('attrs');
3580 var src = attrs.src;
3581
3582 if (src) {
3583 var cacheImage = this.get('cacheImage'); // 如果有缓存,则直接从缓存中拿
3584
3585 if (cacheImage && imageCaches[src]) {
3586 this.set('image', imageCaches[src]);
3587 this.draw(context);
3588 return;
3589 }
3590
3591 var _image = null;
3592 var canvas = this.get('canvas');
3593
3594 if (canvas && canvas.get('createImage')) {
3595 var createImage = canvas.get('createImage');
3596 _image = createImage();
3597 } else if (window.Image) {
3598 _image = new Image();
3599 }
3600
3601 if (_image) {
3602 this.set('loading', true); // 设置跨域, 等同于 image.crossOrigin = 'anonymous'
3603
3604 _image.crossOrigin = '';
3605
3606 _image.onload = function () {
3607 _this.set('loading', false);
3608
3609 _this.set('image', _image); // this.draw(context);
3610 // 这里需要调用 canvas.draw 进行重新绘制,否则 image 会一直在最上层
3611
3612
3613 canvas.draw();
3614 }; // src 一定要在 crossOrigin 之后,否则 toDataURL 就会报 SecurityError
3615
3616
3617 _image.src = src; // 设置全局缓存
3618
3619 if (cacheImage) {
3620 imageCaches[src] = _image;
3621 }
3622 }
3623 }
3624 }
3625 }, {
3626 key: "createPath",
3627 value: function createPath(context) {
3628 var image = this.get('image');
3629 this.drawImage(context, image);
3630 }
3631 }, {
3632 key: "drawImage",
3633 value: function drawImage(context, image) {
3634 var _this$_attrs = this._attrs,
3635 attrs = _this$_attrs.attrs,
3636 destroyed = _this$_attrs.destroyed;
3637
3638 if (destroyed) {
3639 return;
3640 }
3641
3642 var x = attrs.x,
3643 y = attrs.y,
3644 width = attrs.width,
3645 height = attrs.height,
3646 sx = attrs.sx,
3647 sy = attrs.sy,
3648 swidth = attrs.swidth,
3649 sheight = attrs.sheight,
3650 radius = attrs.radius,
3651 fillOpacity = attrs.fillOpacity;
3652
3653 if (radius) {
3654 context.save();
3655 this.createRadiusPath(context, x, y, width, height, radius);
3656 context.clip();
3657 } // 设置透明度
3658
3659
3660 var originOpacity = context.globalAlpha;
3661
3662 if (!isNil(fillOpacity)) {
3663 context.globalAlpha = fillOpacity;
3664 }
3665
3666 if (!isNil(sx) && !isNil(sy) && !isNil(swidth) && !isNil(sheight)) {
3667 context.drawImage(image, sx, sy, swidth, sheight, x, y, width, height);
3668 } else {
3669 context.drawImage(image, x, y, width, height);
3670 }
3671
3672 context.globalAlpha = originOpacity;
3673
3674 if (radius) {
3675 // 因为 save 和 restore 会一定程度上影响绘图性能,所以只在必要是调用
3676 context.restore();
3677 }
3678 }
3679 }]);
3680
3681 return ImageShape;
3682 }(Rect);
3683
3684 var Circle = /*#__PURE__*/function (_Shape) {
3685 _inherits$1(Circle, _Shape);
3686
3687 var _super = _createSuper$1(Circle);
3688
3689 function Circle() {
3690 _classCallCheck$1(this, Circle);
3691
3692 return _super.apply(this, arguments);
3693 }
3694
3695 _createClass$1(Circle, [{
3696 key: "_initProperties",
3697 value: function _initProperties() {
3698 _get(_getPrototypeOf$1(Circle.prototype), "_initProperties", this).call(this);
3699
3700 this._attrs.canFill = true;
3701 this._attrs.canStroke = true;
3702 this._attrs.type = 'circle';
3703 }
3704 }, {
3705 key: "getDefaultAttrs",
3706 value: function getDefaultAttrs() {
3707 return {
3708 x: 0,
3709 y: 0,
3710 r: 0,
3711 lineWidth: 0
3712 };
3713 }
3714 }, {
3715 key: "createPath",
3716 value: function createPath(context) {
3717 var attrs = this.get('attrs');
3718 var x = attrs.x,
3719 y = attrs.y,
3720 r = attrs.r;
3721 context.beginPath();
3722 context.arc(x, y, r, 0, Math.PI * 2, false);
3723 context.closePath();
3724 }
3725 }, {
3726 key: "calculateBox",
3727 value: function calculateBox() {
3728 var attrs = this.get('attrs');
3729 var x = attrs.x,
3730 y = attrs.y,
3731 r = attrs.r;
3732 return {
3733 minX: x - r,
3734 maxX: x + r,
3735 minY: y - r,
3736 maxY: y + r
3737 };
3738 }
3739 }]);
3740
3741 return Circle;
3742 }(Shape);
3743
3744 var Line = /*#__PURE__*/function (_Shape) {
3745 _inherits$1(Line, _Shape);
3746
3747 var _super = _createSuper$1(Line);
3748
3749 function Line() {
3750 _classCallCheck$1(this, Line);
3751
3752 return _super.apply(this, arguments);
3753 }
3754
3755 _createClass$1(Line, [{
3756 key: "_initProperties",
3757 value: function _initProperties() {
3758 _get(_getPrototypeOf$1(Line.prototype), "_initProperties", this).call(this);
3759
3760 this._attrs.canStroke = true;
3761 this._attrs.type = 'line';
3762 }
3763 }, {
3764 key: "getDefaultAttrs",
3765 value: function getDefaultAttrs() {
3766 return {
3767 x1: 0,
3768 y1: 0,
3769 x2: 0,
3770 y2: 0,
3771 lineWidth: 1
3772 };
3773 }
3774 }, {
3775 key: "createPath",
3776 value: function createPath(context) {
3777 var attrs = this.get('attrs');
3778 var x1 = attrs.x1,
3779 y1 = attrs.y1,
3780 x2 = attrs.x2,
3781 y2 = attrs.y2;
3782 context.beginPath();
3783 context.moveTo(x1, y1);
3784 context.lineTo(x2, y2);
3785 }
3786 }, {
3787 key: "calculateBox",
3788 value: function calculateBox() {
3789 var attrs = this.get('attrs');
3790 var x1 = attrs.x1,
3791 y1 = attrs.y1,
3792 x2 = attrs.x2,
3793 y2 = attrs.y2,
3794 lineWidth = attrs.lineWidth;
3795 return getBBoxFromLine(x1, y1, x2, y2, lineWidth);
3796 }
3797 }]);
3798
3799 return Line;
3800 }(Shape);
3801
3802 var Polygon = /*#__PURE__*/function (_Shape) {
3803 _inherits$1(Polygon, _Shape);
3804
3805 var _super = _createSuper$1(Polygon);
3806
3807 function Polygon() {
3808 _classCallCheck$1(this, Polygon);
3809
3810 return _super.apply(this, arguments);
3811 }
3812
3813 _createClass$1(Polygon, [{
3814 key: "_initProperties",
3815 value: function _initProperties() {
3816 _get(_getPrototypeOf$1(Polygon.prototype), "_initProperties", this).call(this);
3817
3818 this._attrs.canFill = true;
3819 this._attrs.canStroke = true;
3820 this._attrs.type = 'polygon';
3821 }
3822 }, {
3823 key: "getDefaultAttrs",
3824 value: function getDefaultAttrs() {
3825 return {
3826 points: null,
3827 lineWidth: 0
3828 };
3829 }
3830 }, {
3831 key: "createPath",
3832 value: function createPath(context) {
3833 var attrs = this.get('attrs');
3834 var points = attrs.points;
3835 context.beginPath();
3836
3837 for (var i = 0, len = points.length; i < len; i++) {
3838 var point = points[i];
3839
3840 if (i === 0) {
3841 context.moveTo(point.x, point.y);
3842 } else {
3843 context.lineTo(point.x, point.y);
3844 }
3845 }
3846
3847 context.closePath();
3848 }
3849 }, {
3850 key: "calculateBox",
3851 value: function calculateBox() {
3852 var attrs = this.get('attrs');
3853 var points = attrs.points;
3854 return getBBoxFromPoints(points);
3855 }
3856 }]);
3857
3858 return Polygon;
3859 }(Shape);
3860
3861 function _filterPoints(points) {
3862 var filteredPoints = [];
3863
3864 for (var i = 0, len = points.length; i < len; i++) {
3865 var point = points[i];
3866
3867 if (!isNaN(point.x) && !isNaN(point.y)) {
3868 filteredPoints.push(point);
3869 }
3870 }
3871
3872 return filteredPoints;
3873 }
3874
3875 var Polyline = /*#__PURE__*/function (_Shape) {
3876 _inherits$1(Polyline, _Shape);
3877
3878 var _super = _createSuper$1(Polyline);
3879
3880 function Polyline() {
3881 _classCallCheck$1(this, Polyline);
3882
3883 return _super.apply(this, arguments);
3884 }
3885
3886 _createClass$1(Polyline, [{
3887 key: "_initProperties",
3888 value: function _initProperties() {
3889 _get(_getPrototypeOf$1(Polyline.prototype), "_initProperties", this).call(this);
3890
3891 this._attrs.canFill = true;
3892 this._attrs.canStroke = true;
3893 this._attrs.type = 'polyline';
3894 }
3895 }, {
3896 key: "getDefaultAttrs",
3897 value: function getDefaultAttrs() {
3898 return {
3899 points: null,
3900 lineWidth: 1,
3901 smooth: false
3902 };
3903 }
3904 }, {
3905 key: "createPath",
3906 value: function createPath(context) {
3907 var attrs = this.get('attrs');
3908 var points = attrs.points,
3909 smooth = attrs.smooth;
3910
3911 var filteredPoints = _filterPoints(points);
3912
3913 context.beginPath();
3914
3915 if (filteredPoints.length) {
3916 context.moveTo(filteredPoints[0].x, filteredPoints[0].y);
3917
3918 if (smooth) {
3919 var constaint = [[0, 0], [1, 1]];
3920 var sps = catmullRom2bezier(filteredPoints, false, constaint);
3921
3922 for (var i = 0, n = sps.length; i < n; i++) {
3923 var sp = sps[i];
3924 context.bezierCurveTo(sp[1], sp[2], sp[3], sp[4], sp[5], sp[6]);
3925 }
3926 } else {
3927 var _i;
3928
3929 var l;
3930
3931 for (_i = 1, l = filteredPoints.length - 1; _i < l; _i++) {
3932 context.lineTo(filteredPoints[_i].x, filteredPoints[_i].y);
3933 }
3934
3935 context.lineTo(filteredPoints[l].x, filteredPoints[l].y);
3936 }
3937 }
3938 }
3939 }, {
3940 key: "calculateBox",
3941 value: function calculateBox() {
3942 var attrs = this.get('attrs');
3943 var points = attrs.points,
3944 smooth = attrs.smooth,
3945 lineWidth = attrs.lineWidth;
3946
3947 var filteredPoints = _filterPoints(points);
3948
3949 if (smooth) {
3950 var newPoints = [];
3951 var constaint = [[0, 0], [1, 1]];
3952 var sps = catmullRom2bezier(filteredPoints, false, constaint);
3953
3954 for (var i = 0, n = sps.length; i < n; i++) {
3955 var sp = sps[i];
3956
3957 if (i === 0) {
3958 newPoints.push([filteredPoints[0].x, filteredPoints[0].y, sp[1], sp[2], sp[3], sp[4], sp[5], sp[6]]);
3959 } else {
3960 var lastPoint = sps[i - 1];
3961 newPoints.push([lastPoint[5], lastPoint[6], sp[1], sp[2], sp[3], sp[4], sp[5], sp[6]]);
3962 }
3963 }
3964
3965 return getBBoxFromBezierGroup(newPoints, lineWidth);
3966 }
3967
3968 return getBBoxFromPoints(filteredPoints, lineWidth);
3969 }
3970 }]);
3971
3972 return Polyline;
3973 }(Shape);
3974
3975 var Arc = /*#__PURE__*/function (_Shape) {
3976 _inherits$1(Arc, _Shape);
3977
3978 var _super = _createSuper$1(Arc);
3979
3980 function Arc() {
3981 _classCallCheck$1(this, Arc);
3982
3983 return _super.apply(this, arguments);
3984 }
3985
3986 _createClass$1(Arc, [{
3987 key: "_initProperties",
3988 value: function _initProperties() {
3989 _get(_getPrototypeOf$1(Arc.prototype), "_initProperties", this).call(this);
3990
3991 this._attrs.canStroke = true;
3992 this._attrs.canFill = true;
3993 this._attrs.type = 'arc';
3994 }
3995 }, {
3996 key: "getDefaultAttrs",
3997 value: function getDefaultAttrs() {
3998 return {
3999 x: 0,
4000 y: 0,
4001 r: 0,
4002 startAngle: 0,
4003 endAngle: Math.PI * 2,
4004 anticlockwise: false,
4005 lineWidth: 1
4006 };
4007 }
4008 }, {
4009 key: "createPath",
4010 value: function createPath(context) {
4011 var attrs = this.get('attrs');
4012 var x = attrs.x,
4013 y = attrs.y,
4014 r = attrs.r,
4015 startAngle = attrs.startAngle,
4016 endAngle = attrs.endAngle,
4017 anticlockwise = attrs.anticlockwise;
4018 context.beginPath();
4019
4020 if (startAngle !== endAngle) {
4021 context.arc(x, y, r, startAngle, endAngle, anticlockwise);
4022 }
4023 }
4024 }, {
4025 key: "calculateBox",
4026 value: function calculateBox() {
4027 var attrs = this.get('attrs');
4028 var x = attrs.x,
4029 y = attrs.y,
4030 r = attrs.r,
4031 startAngle = attrs.startAngle,
4032 endAngle = attrs.endAngle,
4033 anticlockwise = attrs.anticlockwise;
4034 return getBBoxFromArc(x, y, r, startAngle, endAngle, anticlockwise);
4035 }
4036 }]);
4037
4038 return Arc;
4039 }(Shape);
4040
4041 var Sector = /*#__PURE__*/function (_Shape) {
4042 _inherits$1(Sector, _Shape);
4043
4044 var _super = _createSuper$1(Sector);
4045
4046 function Sector() {
4047 _classCallCheck$1(this, Sector);
4048
4049 return _super.apply(this, arguments);
4050 }
4051
4052 _createClass$1(Sector, [{
4053 key: "_initProperties",
4054 value: function _initProperties() {
4055 _get(_getPrototypeOf$1(Sector.prototype), "_initProperties", this).call(this);
4056
4057 this._attrs.canFill = true;
4058 this._attrs.canStroke = true;
4059 this._attrs.type = 'sector';
4060 }
4061 }, {
4062 key: "getDefaultAttrs",
4063 value: function getDefaultAttrs() {
4064 return {
4065 x: 0,
4066 y: 0,
4067 lineWidth: 0,
4068 r: 0,
4069 r0: 0,
4070 startAngle: 0,
4071 endAngle: Math.PI * 2,
4072 anticlockwise: false
4073 };
4074 }
4075 }, {
4076 key: "createPath",
4077 value: function createPath(context) {
4078 var attrs = this.get('attrs');
4079 var x = attrs.x,
4080 y = attrs.y,
4081 startAngle = attrs.startAngle,
4082 r = attrs.r,
4083 r0 = attrs.r0,
4084 anticlockwise = attrs.anticlockwise; // 最大为整个圆
4085
4086 var endAngle = Math.min(attrs.endAngle, startAngle + Math.PI * 2);
4087 context.beginPath();
4088 var unitX = Math.cos(startAngle);
4089 var unitY = Math.sin(startAngle);
4090 context.moveTo(unitX * r0 + x, unitY * r0 + y);
4091 context.lineTo(unitX * r + x, unitY * r + y); // 当扇形的角度非常小的时候,就不进行弧线的绘制;或者整个只有1个扇形时,会出现end<0的情况不绘制
4092
4093 if (Math.abs(endAngle - startAngle) > 0.0001 || startAngle === 0 && endAngle < 0) {
4094 context.arc(x, y, r, startAngle, endAngle, anticlockwise);
4095 context.lineTo(Math.cos(endAngle) * r0 + x, Math.sin(endAngle) * r0 + y);
4096
4097 if (r0 !== 0) {
4098 context.arc(x, y, r0, endAngle, startAngle, !anticlockwise);
4099 }
4100 }
4101
4102 context.closePath();
4103 }
4104 }, {
4105 key: "calculateBox",
4106 value: function calculateBox() {
4107 var attrs = this.get('attrs');
4108 var x = attrs.x,
4109 y = attrs.y,
4110 r = attrs.r,
4111 r0 = attrs.r0,
4112 startAngle = attrs.startAngle,
4113 endAngle = attrs.endAngle,
4114 anticlockwise = attrs.anticlockwise;
4115 var outerBBox = getBBoxFromArc(x, y, r, startAngle, endAngle, anticlockwise);
4116 var innerBBox = getBBoxFromArc(x, y, r0, startAngle, endAngle, anticlockwise);
4117 return {
4118 minX: Math.min(outerBBox.minX, innerBBox.minX),
4119 minY: Math.min(outerBBox.minY, innerBBox.minY),
4120 maxX: Math.max(outerBBox.maxX, innerBBox.maxX),
4121 maxY: Math.max(outerBBox.maxY, innerBBox.maxY)
4122 };
4123 }
4124 }]);
4125
4126 return Sector;
4127 }(Shape);
4128
4129 var Rect$1 = {
4130 calcRotatedBox: function calcRotatedBox(_ref) {
4131 var width = _ref.width,
4132 height = _ref.height,
4133 rotate = _ref.rotate;
4134 var absRotate = Math.abs(rotate);
4135 return {
4136 width: Math.abs(width * Math.cos(absRotate) + height * Math.sin(absRotate)),
4137 height: Math.abs(height * Math.cos(absRotate) + width * Math.sin(absRotate))
4138 };
4139 }
4140 };
4141
4142 var measureText$1 = measureText;
4143 var textWidthCacheCounter = 0;
4144 var textWidthCache = {};
4145 var TEXT_CACHE_MAX = 5000;
4146
4147 var Text = /*#__PURE__*/function (_Shape) {
4148 _inherits$1(Text, _Shape);
4149
4150 var _super = _createSuper$1(Text);
4151
4152 function Text() {
4153 _classCallCheck$1(this, Text);
4154
4155 return _super.apply(this, arguments);
4156 }
4157
4158 _createClass$1(Text, [{
4159 key: "_initProperties",
4160 value: function _initProperties() {
4161 _get(_getPrototypeOf$1(Text.prototype), "_initProperties", this).call(this);
4162
4163 this._attrs.canFill = true;
4164 this._attrs.canStroke = true;
4165 this._attrs.type = 'text';
4166 }
4167 }, {
4168 key: "getDefaultAttrs",
4169 value: function getDefaultAttrs() {
4170 return {
4171 lineWidth: 0,
4172 lineCount: 1,
4173 fontSize: 12,
4174 fontFamily: '',
4175 fontStyle: 'normal',
4176 fontWeight: 'normal',
4177 fontVariant: 'normal',
4178 textAlign: 'start',
4179 textBaseline: 'bottom',
4180 lineHeight: null,
4181 textArr: null
4182 };
4183 }
4184 }, {
4185 key: "_getFontStyle",
4186 value: function _getFontStyle() {
4187 var attrs = this._attrs.attrs;
4188 var fontSize = attrs.fontSize,
4189 fontFamily = attrs.fontFamily,
4190 fontWeight = attrs.fontWeight,
4191 fontStyle = attrs.fontStyle,
4192 fontVariant = attrs.fontVariant;
4193 return "".concat(fontStyle, " ").concat(fontVariant, " ").concat(fontWeight, " ").concat(fontSize, "px ").concat(fontFamily);
4194 }
4195 }, {
4196 key: "_afterAttrsSet",
4197 value: function _afterAttrsSet() {
4198 var attrs = this._attrs.attrs;
4199 attrs.font = this._getFontStyle();
4200
4201 if (attrs.text) {
4202 var text = attrs.text;
4203 var textArr = null;
4204 var lineCount = 1;
4205
4206 if (isString(text) && text.indexOf('\n') !== -1) {
4207 textArr = text.split('\n');
4208 lineCount = textArr.length;
4209 }
4210
4211 attrs.lineCount = lineCount;
4212 attrs.textArr = textArr;
4213 }
4214
4215 this.set('attrs', attrs);
4216 }
4217 }, {
4218 key: "_getTextHeight",
4219 value: function _getTextHeight() {
4220 var attrs = this._attrs.attrs;
4221
4222 if (attrs.height) {
4223 return attrs.height;
4224 }
4225
4226 var lineCount = attrs.lineCount;
4227 var fontSize = attrs.fontSize * 1;
4228
4229 if (lineCount > 1) {
4230 var spaceingY = this._getSpaceingY();
4231
4232 return fontSize * lineCount + spaceingY * (lineCount - 1);
4233 }
4234
4235 return fontSize;
4236 }
4237 }, {
4238 key: "_getSpaceingY",
4239 value: function _getSpaceingY() {
4240 var attrs = this._attrs.attrs;
4241 var lineHeight = attrs.lineHeight;
4242 var fontSize = attrs.fontSize * 1;
4243 return lineHeight ? lineHeight - fontSize : fontSize * 0.14;
4244 }
4245 }, {
4246 key: "drawInner",
4247 value: function drawInner(context) {
4248 var attrs = this._attrs.attrs;
4249 var text = attrs.text;
4250 var x = attrs.x;
4251 var y = attrs.y;
4252
4253 if (isNil(text) || isNaN(x) || isNaN(y)) {
4254 // text will be 0
4255 return;
4256 }
4257
4258 var textArr = attrs.textArr;
4259 var fontSize = attrs.fontSize * 1;
4260
4261 var spaceingY = this._getSpaceingY();
4262
4263 if (attrs.rotate) {
4264 // do rotation
4265 context.translate(x, y);
4266 context.rotate(attrs.rotate);
4267 x = 0;
4268 y = 0;
4269 }
4270
4271 var textBaseline = attrs.textBaseline;
4272 var height;
4273
4274 if (textArr) {
4275 height = this._getTextHeight();
4276 }
4277
4278 var subY; // context.beginPath();
4279
4280 if (this.hasFill()) {
4281 var fillOpacity = attrs.fillOpacity;
4282
4283 if (!isNil(fillOpacity) && fillOpacity !== 1) {
4284 context.globalAlpha = fillOpacity;
4285 }
4286
4287 if (textArr) {
4288 for (var i = 0, len = textArr.length; i < len; i++) {
4289 var subText = textArr[i];
4290 subY = y + i * (spaceingY + fontSize) - height + fontSize; // bottom;
4291
4292 if (textBaseline === 'middle') {
4293 subY += height - fontSize - (height - fontSize) / 2;
4294 }
4295
4296 if (textBaseline === 'top') {
4297 subY += height - fontSize;
4298 }
4299
4300 context.fillText(subText, x, subY);
4301 }
4302 } else {
4303 context.fillText(text, x, y);
4304 }
4305 }
4306
4307 if (this.hasStroke()) {
4308 if (textArr) {
4309 for (var _i = 0, _len = textArr.length; _i < _len; _i++) {
4310 var _subText = textArr[_i];
4311 subY = y + _i * (spaceingY + fontSize) - height + fontSize; // bottom;
4312
4313 if (textBaseline === 'middle') {
4314 subY += height - fontSize - (height - fontSize) / 2;
4315 }
4316
4317 if (textBaseline === 'top') {
4318 subY += height - fontSize;
4319 }
4320
4321 context.strokeText(_subText, x, subY);
4322 }
4323 } else {
4324 context.strokeText(text, x, y);
4325 }
4326 }
4327 }
4328 }, {
4329 key: "_getAriaLabel",
4330 value: function _getAriaLabel() {
4331 return this._attrs.attrs.text;
4332 }
4333 }, {
4334 key: "calculateBox",
4335 value: function calculateBox() {
4336 var attrs = this._attrs.attrs;
4337 var x = attrs.x,
4338 y = attrs.y,
4339 textAlign = attrs.textAlign,
4340 textBaseline = attrs.textBaseline;
4341
4342 var width = this._getTextWidth(); // attrs.width
4343
4344
4345 if (!width) {
4346 return {
4347 minX: x,
4348 minY: y,
4349 maxX: x,
4350 maxY: y
4351 };
4352 }
4353
4354 var height = this._getTextHeight(); // attrs.height
4355
4356
4357 if (attrs.rotate) {
4358 var rotatedBox = Rect$1.calcRotatedBox({
4359 width: width,
4360 height: height,
4361 rotate: attrs.rotate
4362 });
4363 width = rotatedBox.width;
4364 height = rotatedBox.height;
4365 }
4366
4367 var point = {
4368 x: x,
4369 y: y - height
4370 }; // default textAlign: start, textBaseline: bottom
4371
4372 if (textAlign) {
4373 if (textAlign === 'end' || textAlign === 'right') {
4374 point.x -= width;
4375 } else if (textAlign === 'center') {
4376 point.x -= width / 2;
4377 }
4378 }
4379
4380 if (textBaseline) {
4381 if (textBaseline === 'top') {
4382 point.y += height;
4383 } else if (textBaseline === 'middle') {
4384 point.y += height / 2;
4385 }
4386 }
4387
4388 return {
4389 minX: point.x,
4390 minY: point.y,
4391 maxX: point.x + width,
4392 maxY: point.y + height
4393 };
4394 }
4395 }, {
4396 key: "_getTextWidth",
4397 value: function _getTextWidth() {
4398 var attrs = this._attrs.attrs;
4399
4400 if (attrs.width) {
4401 return attrs.width;
4402 }
4403
4404 var text = attrs.text;
4405 var context = this.get('context');
4406 if (isNil(text)) return undefined;
4407 var font = attrs.font;
4408 var textArr = attrs.textArr;
4409 var key = text + '' + font;
4410
4411 if (textWidthCache[key]) {
4412 return textWidthCache[key];
4413 }
4414
4415 var width = 0;
4416
4417 if (textArr) {
4418 for (var i = 0, length = textArr.length; i < length; i++) {
4419 var subText = textArr[i];
4420 width = Math.max(width, measureText$1(subText, font, context).width);
4421 }
4422 } else {
4423 width = measureText$1(text, font, context).width;
4424 }
4425
4426 if (textWidthCacheCounter > TEXT_CACHE_MAX) {
4427 textWidthCacheCounter = 0;
4428 textWidthCache = {};
4429 }
4430
4431 textWidthCacheCounter++;
4432 textWidthCache[key] = width;
4433 return width;
4434 }
4435 }]);
4436
4437 return Text;
4438 }(Shape);
4439
4440 var Custom = /*#__PURE__*/function (_Shape) {
4441 _inherits$1(Custom, _Shape);
4442
4443 var _super = _createSuper$1(Custom);
4444
4445 function Custom() {
4446 _classCallCheck$1(this, Custom);
4447
4448 return _super.apply(this, arguments);
4449 }
4450
4451 _createClass$1(Custom, [{
4452 key: "_initProperties",
4453 value: function _initProperties() {
4454 _get(_getPrototypeOf$1(Custom.prototype), "_initProperties", this).call(this);
4455
4456 this._attrs.canFill = true;
4457 this._attrs.canStroke = true;
4458 this._attrs.createPath = null;
4459 this._attrs.type = 'custom';
4460 }
4461 }, {
4462 key: "createPath",
4463 value: function createPath(context) {
4464 var createPath = this.get('createPath');
4465 createPath && createPath.call(this, context);
4466 }
4467 }, {
4468 key: "calculateBox",
4469 value: function calculateBox() {
4470 var calculateBox = this.get('calculateBox');
4471 return calculateBox && calculateBox.call(this);
4472 }
4473 }]);
4474
4475 return Custom;
4476 }(Shape);
4477
4478 var SYMBOLS = {
4479 circle: function circle(x, y, r, ctx) {
4480 ctx.arc(x, y, r, 0, Math.PI * 2, false);
4481 },
4482 square: function square(x, y, r, ctx) {
4483 ctx.moveTo(x - r, y - r);
4484 ctx.lineTo(x + r, y - r);
4485 ctx.lineTo(x + r, y + r);
4486 ctx.lineTo(x - r, y + r);
4487 ctx.closePath();
4488 }
4489 };
4490
4491 var Marker = /*#__PURE__*/function (_Shape) {
4492 _inherits$1(Marker, _Shape);
4493
4494 var _super = _createSuper$1(Marker);
4495
4496 function Marker() {
4497 _classCallCheck$1(this, Marker);
4498
4499 return _super.apply(this, arguments);
4500 }
4501
4502 _createClass$1(Marker, [{
4503 key: "_initProperties",
4504 value: function _initProperties() {
4505 _get(_getPrototypeOf$1(Marker.prototype), "_initProperties", this).call(this);
4506
4507 this._attrs.canFill = true;
4508 this._attrs.canStroke = true;
4509 this._attrs.type = 'marker';
4510 }
4511 }, {
4512 key: "getDefaultAttrs",
4513 value: function getDefaultAttrs() {
4514 return {
4515 x: 0,
4516 y: 0,
4517 lineWidth: 0
4518 };
4519 }
4520 }, {
4521 key: "createPath",
4522 value: function createPath(context) {
4523 var attrs = this.get('attrs');
4524 var x = attrs.x,
4525 y = attrs.y,
4526 radius = attrs.radius;
4527 var symbol = attrs.symbol || 'circle';
4528 var method;
4529
4530 if (isFunction(symbol)) {
4531 method = symbol;
4532 } else {
4533 method = SYMBOLS[symbol];
4534 }
4535
4536 context.beginPath();
4537 method(x, y, radius, context, this);
4538 }
4539 }, {
4540 key: "calculateBox",
4541 value: function calculateBox() {
4542 var attrs = this.get('attrs');
4543 var x = attrs.x,
4544 y = attrs.y,
4545 radius = attrs.radius;
4546 return {
4547 minX: x - radius,
4548 minY: y - radius,
4549 maxX: x + radius,
4550 maxY: y + radius
4551 };
4552 }
4553 }]);
4554
4555 return Marker;
4556 }(Shape);
4557
4558 Shape.Rect = Rect;
4559 Shape.Image = ImageShape;
4560 Shape.Circle = Circle;
4561 Shape.Line = Line;
4562 Shape.Polygon = Polygon;
4563 Shape.Polyline = Polyline;
4564 Shape.Arc = Arc;
4565 Shape.Sector = Sector;
4566 Shape.Text = Text;
4567 Shape.Custom = Custom;
4568 Shape.Marker = Marker;
4569
4570 var SHAPE_MAP = {};
4571 var INDEX = '_INDEX';
4572
4573 function getComparer(compare) {
4574 return function (left, right) {
4575 var result = compare(left, right);
4576 return result === 0 ? left[INDEX] - right[INDEX] : result;
4577 };
4578 }
4579
4580 var Container = {
4581 getGroupClass: function getGroupClass() {},
4582 getChildren: function getChildren() {
4583 return this.get('children');
4584 },
4585 addShape: function addShape(type) {
4586 var cfg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
4587 var shapeType = SHAPE_MAP[type];
4588
4589 if (!shapeType) {
4590 shapeType = upperFirst(type);
4591 SHAPE_MAP[type] = shapeType;
4592 }
4593
4594 var shape = new Shape[shapeType](cfg);
4595 this.add(shape);
4596 return shape;
4597 },
4598 addGroup: function addGroup(cfg) {
4599 var groupClass = this.getGroupClass();
4600 var rst = new groupClass(cfg);
4601 this.add(rst);
4602 return rst;
4603 },
4604 contain: function contain(item) {
4605 var children = this.get('children');
4606 return children.indexOf(item) > -1;
4607 },
4608 sort: function sort() {
4609 var children = this.get('children');
4610
4611 for (var i = 0, len = children.length; i < len; i++) {
4612 var child = children[i];
4613 child[INDEX] = i;
4614 }
4615
4616 children.sort(getComparer(function (obj1, obj2) {
4617 return obj1.get('zIndex') - obj2.get('zIndex');
4618 }));
4619 return this;
4620 },
4621 drawChildren: function drawChildren(context) {
4622 this.sort();
4623 var children = this.get('children');
4624
4625 for (var i = 0, len = children.length; i < len; i++) {
4626 var child = children[i];
4627 child.draw(context);
4628 }
4629
4630 return this;
4631 },
4632 clear: function clear() {
4633 var children = this.get('children') || [];
4634
4635 while (children.length !== 0) {
4636 children[children.length - 1].remove(true);
4637 }
4638
4639 return this;
4640 },
4641 add: function add(items) {
4642 var children = this.get('children');
4643
4644 if (!children) {
4645 children = [];
4646 this.set('children', children);
4647 }
4648
4649 if (!isArray(items)) {
4650 items = [items];
4651 }
4652
4653 for (var i = 0, len = items.length; i < len; i++) {
4654 var item = items[i];
4655 var parent = item.get('parent');
4656
4657 if (parent) {
4658 var descendants = parent.get('children');
4659 remove(descendants, item);
4660 }
4661
4662 this._setEvn(item);
4663
4664 children.push(item);
4665 }
4666
4667 return this;
4668 },
4669 _setEvn: function _setEvn(item) {
4670 var _this$_attrs = this._attrs,
4671 context = _this$_attrs.context,
4672 canvas = _this$_attrs.canvas,
4673 aria = _this$_attrs.aria;
4674 var _item$_attrs = item._attrs,
4675 isGroup = _item$_attrs.isGroup,
4676 type = _item$_attrs.type;
4677 item._attrs.parent = this;
4678 item._attrs.context = context;
4679 item._attrs.canvas = canvas; // 是否需要无障碍处理
4680
4681 if (aria && item._attrs.aria !== false) {
4682 item._attrs.aria = aria;
4683 }
4684
4685 if (type === 'text' && canvas && canvas.get('fontFamily') && !item._attrs.attrs.fontFamily) {
4686 item.attr('fontFamily', canvas.get('fontFamily'));
4687 }
4688
4689 var clip = item._attrs.attrs.clip;
4690
4691 if (clip) {
4692 clip._attrs.parent = this;
4693 clip._attrs.context = context;
4694 clip._attrs.canvas = canvas;
4695 }
4696
4697 if (isGroup) {
4698 var children = item._attrs.children;
4699
4700 for (var i = 0, len = children.length; i < len; i++) {
4701 item._setEvn(children[i]);
4702 }
4703 }
4704 },
4705 _getAriaLabel: function _getAriaLabel() {
4706 var _this$_attrs2 = this._attrs,
4707 aria = _this$_attrs2.aria,
4708 ariaLabel = _this$_attrs2.ariaLabel,
4709 children = _this$_attrs2.children; // 主动关闭
4710
4711 if (!aria) return;
4712 var childAriaLabels = [];
4713
4714 if (children && children.length) {
4715 for (var i = 0, len = children.length; i < len; i++) {
4716 var _childAriaLabel = children[i].getAriaLabel();
4717
4718 if (_childAriaLabel) {
4719 childAriaLabels.push(_childAriaLabel);
4720 }
4721 }
4722 }
4723
4724 var childAriaLabel = childAriaLabels.join(' '); // 2个都有时拼接成完整句子
4725
4726 if (ariaLabel && childAriaLabel) {
4727 return "".concat(ariaLabel, " ").concat(childAriaLabel, " ");
4728 } // 只有1个,或者都没有
4729
4730
4731 return ariaLabel || childAriaLabel;
4732 }
4733 };
4734
4735 var Group = /*#__PURE__*/function (_Rect) {
4736 _inherits$1(Group, _Rect);
4737
4738 var _super = _createSuper$1(Group);
4739
4740 function Group() {
4741 _classCallCheck$1(this, Group);
4742
4743 return _super.apply(this, arguments);
4744 }
4745
4746 _createClass$1(Group, [{
4747 key: "_initProperties",
4748 value:
4749 /* eslint-enable */
4750 function _initProperties() {
4751 this._attrs = {
4752 type: 'group',
4753 zIndex: 0,
4754 visible: true,
4755 destroyed: false,
4756 isGroup: true,
4757 canFill: true,
4758 canStroke: true,
4759 children: [],
4760 attrs: {
4761 x: 0,
4762 y: 0,
4763 width: 0,
4764 height: 0,
4765 radius: 0,
4766 lineWidth: 0
4767 }
4768 };
4769 }
4770 }, {
4771 key: "getBBox",
4772 value: function getBBox() {
4773 var minX = Infinity;
4774 var maxX = -Infinity;
4775 var minY = Infinity;
4776 var maxY = -Infinity;
4777 var children = this.get('children');
4778
4779 for (var i = 0, length = children.length; i < length; i++) {
4780 var child = children[i];
4781
4782 if (child.get('visible')) {
4783 var box = child.getBBox();
4784
4785 if (!box) {
4786 continue;
4787 }
4788
4789 var leftTop = [box.minX, box.minY];
4790 var leftBottom = [box.minX, box.maxY];
4791 var rightTop = [box.maxX, box.minY];
4792 var rightBottom = [box.maxX, box.maxY];
4793 var matrix = child.attr('matrix');
4794 Vector2.transformMat2d(leftTop, leftTop, matrix);
4795 Vector2.transformMat2d(leftBottom, leftBottom, matrix);
4796 Vector2.transformMat2d(rightTop, rightTop, matrix);
4797 Vector2.transformMat2d(rightBottom, rightBottom, matrix);
4798 minX = Math.min(leftTop[0], leftBottom[0], rightTop[0], rightBottom[0], minX);
4799 maxX = Math.max(leftTop[0], leftBottom[0], rightTop[0], rightBottom[0], maxX);
4800 minY = Math.min(leftTop[1], leftBottom[1], rightTop[1], rightBottom[1], minY);
4801 maxY = Math.max(leftTop[1], leftBottom[1], rightTop[1], rightBottom[1], maxY);
4802 }
4803 }
4804
4805 return {
4806 minX: minX,
4807 minY: minY,
4808 maxX: maxX,
4809 maxY: maxY,
4810 x: minX,
4811 y: minY,
4812 width: maxX - minX,
4813 height: maxY - minY
4814 };
4815 }
4816 }, {
4817 key: "createPath",
4818 value: function createPath(context) {
4819 var attrs = this.get('attrs'); // 只有在有fillStyle或strokeStyle 时才需要绘制
4820
4821 if (!attrs.fillStyle && !attrs.strokeStyle) {
4822 return;
4823 }
4824
4825 _get(_getPrototypeOf$1(Group.prototype), "createPath", this).call(this, context);
4826 }
4827 }, {
4828 key: "drawInner",
4829 value: function drawInner(context) {
4830 _get(_getPrototypeOf$1(Group.prototype), "drawInner", this).call(this, context);
4831
4832 this.drawChildren(context);
4833 }
4834 }, {
4835 key: "destroy",
4836 value: function destroy() {
4837 if (this.get('destroyed')) {
4838 return;
4839 }
4840
4841 this.clear();
4842
4843 _get(_getPrototypeOf$1(Group.prototype), "destroy", this).call(this);
4844 }
4845 }]);
4846
4847 return Group;
4848 }(Rect); // @ts-ignore
4849
4850
4851 mix(Group.prototype, Container, {
4852 getGroupClass: function getGroupClass() {
4853 return Group;
4854 }
4855 });
4856
4857 var requestAnimationFrame$1 = (typeof window === "undefined" ? "undefined" : _typeof$1(window)) === 'object' && window.requestAnimationFrame ? window.requestAnimationFrame : function (fn) {
4858 return setTimeout(fn, 16);
4859 };
4860
4861 var lang = {
4862 general: {
4863 title: '这是一个图表,',
4864 withTitle: '这是一个关于“{title}”的图表。'
4865 },
4866 coord: {
4867 cartesian: 'X轴是{xLabel}Y轴是{yLabel}' // polar: '弧度是{xLabel}半径是{yLabel}'
4868
4869 },
4870 scale: {
4871 linear: '数值型,数据最小值为{min},最大值为{max};',
4872 cat: '分类型, 分类类型有:{values};',
4873 timeCat: '时间型,时间范围从{start}到{end};'
4874 },
4875 geometry: {
4876 prefix: '共有{count}种分类组成,',
4877 oneData: '第{index}类是{name},数据是{values};',
4878 partData: '第{index}类是{name},共有{count}项数据,前{part}项是{values};',
4879 allData: '第{index}类是{name},有{count}项数据,分别是{values};'
4880 },
4881 legend: {
4882 prefix: '图例分类有:'
4883 }
4884 };
4885
4886 var getPixelRatio$1 = getPixelRatio,
4887 getDomById$1 = getDomById,
4888 getWidth$1 = getWidth,
4889 getHeight$1 = getHeight,
4890 isCanvasElement$1 = isCanvasElement;
4891
4892 var Canvas = /*#__PURE__*/function (_EventEmit) {
4893 _inherits$1(Canvas, _EventEmit);
4894
4895 var _super = _createSuper$1(Canvas);
4896
4897 function Canvas(cfg) {
4898 var _this;
4899
4900 _classCallCheck$1(this, Canvas);
4901
4902 _this = _super.call(this);
4903 var title = cfg.title;
4904 var ariaLabel = title ? substitute(lang.general.withTitle, {
4905 title: title
4906 }) : lang.general.title;
4907 _this._attrs = mix({
4908 type: 'canvas',
4909 children: [],
4910 ariaLabel: ariaLabel
4911 }, cfg);
4912
4913 _this._initPixelRatio();
4914
4915 _this._initCanvas();
4916
4917 return _this;
4918 }
4919 /* eslint-enable */
4920
4921
4922 _createClass$1(Canvas, [{
4923 key: "get",
4924 value: function get(name) {
4925 return this._attrs[name];
4926 }
4927 }, {
4928 key: "set",
4929 value: function set(name, value) {
4930 this._attrs[name] = value;
4931 }
4932 }, {
4933 key: "_initPixelRatio",
4934 value: function _initPixelRatio() {
4935 var pixelRatio = this.get('pixelRatio');
4936
4937 if (!pixelRatio) {
4938 this.set('pixelRatio', getPixelRatio$1());
4939 }
4940 }
4941 }, {
4942 key: "beforeDraw",
4943 value: function beforeDraw() {
4944 var context = this._attrs.context;
4945 var el = this._attrs.el;
4946 context && context.clearRect && context.clearRect(0, 0, el.width, el.height);
4947 }
4948 }, {
4949 key: "_initCanvas",
4950 value: function _initCanvas() {
4951 var el = this.get('el');
4952 var context = this.get('context');
4953
4954 if (!el && !context) {
4955 throw new Error('Please specify the id, el or context of the chart!');
4956 }
4957
4958 var canvas;
4959
4960 if (el) {
4961 // DOMElement or String
4962 canvas = isString(el) ? getDomById$1(el) : el;
4963 } else {
4964 // 说明没有指定el
4965 canvas = CanvasElement$1.create(context);
4966 }
4967
4968 if (context && canvas && !canvas.getContext) {
4969 canvas.getContext = function () {
4970 return context;
4971 };
4972 }
4973
4974 var width = this.get('width') || getWidth$1(canvas) || canvas.width;
4975 var height = this.get('height') || getHeight$1(canvas) || canvas.height;
4976 this.set('canvas', this);
4977 this.set('el', canvas);
4978 this.set('context', context || canvas.getContext('2d'));
4979 this.changeSize(width, height); // 初始化事件控制器
4980
4981 var eventController = new EventController({
4982 canvas: this,
4983 el: canvas
4984 });
4985 this.set('eventController', eventController);
4986 }
4987 }, {
4988 key: "changeSize",
4989 value: function changeSize(width, height) {
4990 var pixelRatio = this.get('pixelRatio');
4991 var canvasDOM = this.get('el'); // HTMLCanvasElement or canvasElement
4992 // 浏览器环境设置style样式
4993
4994 if (canvasDOM.style) {
4995 canvasDOM.style.width = width + 'px';
4996 canvasDOM.style.height = height + 'px';
4997 }
4998
4999 if (isCanvasElement$1(canvasDOM)) {
5000 canvasDOM.width = width * pixelRatio;
5001 canvasDOM.height = height * pixelRatio;
5002
5003 if (pixelRatio !== 1) {
5004 var ctx = this.get('context');
5005 ctx.scale(pixelRatio, pixelRatio);
5006 }
5007 }
5008
5009 this.set('width', width);
5010 this.set('height', height);
5011 }
5012 }, {
5013 key: "getWidth",
5014 value: function getWidth() {
5015 var pixelRatio = this.get('pixelRatio');
5016 var width = this.get('width');
5017 return width * pixelRatio;
5018 }
5019 }, {
5020 key: "getHeight",
5021 value: function getHeight() {
5022 var pixelRatio = this.get('pixelRatio');
5023 var height = this.get('height');
5024 return height * pixelRatio;
5025 }
5026 }, {
5027 key: "getPointByClient",
5028 value: function getPointByClient(clientX, clientY) {
5029 var el = this.get('el');
5030 var bbox = el.getBoundingClientRect();
5031 var width = bbox.right - bbox.left;
5032 var height = bbox.bottom - bbox.top;
5033 return {
5034 x: (clientX - bbox.left) * (el.width / width),
5035 y: (clientY - bbox.top) * (el.height / height)
5036 };
5037 }
5038 }, {
5039 key: "_beginDraw",
5040 value: function _beginDraw() {
5041 this._attrs.toDraw = true;
5042 }
5043 }, {
5044 key: "_endDraw",
5045 value: function _endDraw() {
5046 this._attrs.toDraw = false;
5047 }
5048 }, {
5049 key: "draw",
5050 value: function draw() {
5051 var _this2 = this;
5052
5053 var drawInner = function drawInner() {
5054 _this2.set('animateHandler', requestAnimationFrame$1(function () {
5055 _this2.set('animateHandler', undefined);
5056
5057 if (_this2.get('toDraw')) {
5058 drawInner();
5059 }
5060 }));
5061
5062 _this2.beforeDraw();
5063
5064 try {
5065 var context = _this2._attrs.context;
5066
5067 _this2.drawChildren(context); // 支付宝,微信小程序,需要调context.draw才能完成绘制, 所以这里直接判断是否有.draw方法
5068
5069
5070 if (context.draw) {
5071 context.draw();
5072 } // 设置无障碍文本
5073
5074
5075 _this2.setAriaLabel();
5076 } catch (ev) {
5077 console.warn('error in draw canvas, detail as:');
5078 console.warn(ev);
5079
5080 _this2._endDraw();
5081 }
5082
5083 _this2._endDraw();
5084 };
5085
5086 if (this.get('destroyed')) {
5087 return;
5088 }
5089
5090 if (this.get('animateHandler')) {
5091 this._beginDraw();
5092 } else {
5093 drawInner();
5094 }
5095 } // 设置无障碍文本
5096
5097 }, {
5098 key: "setAriaLabel",
5099 value: function setAriaLabel() {
5100 var el = this._attrs.el;
5101
5102 var ariaLabel = this._getAriaLabel();
5103
5104 if (ariaLabel && el.setAttribute) {
5105 el.setAttribute('aria-label', ariaLabel);
5106 }
5107 }
5108 }, {
5109 key: "destroy",
5110 value: function destroy() {
5111 if (this.get('destroyed')) {
5112 return;
5113 } // 需要清理 canvas 画布内容,否则会导致 spa 应用 ios 下 canvas 白屏
5114 // https://stackoverflow.com/questions/52532614/total-canvas-memory-use-exceeds-the-maximum-limit-safari-12
5115 // https://github.com/antvis/F2/issues/630
5116
5117
5118 var el = this.get('el');
5119 el.width = 0;
5120 el.height = 0;
5121 this.clear();
5122 this._attrs = {};
5123 this.set('destroyed', true);
5124 }
5125 }, {
5126 key: "isDestroyed",
5127 value: function isDestroyed() {
5128 return this.get('destroyed');
5129 }
5130 }]);
5131
5132 return Canvas;
5133 }(EventEmit); // @ts-ignore
5134
5135
5136 mix(Canvas.prototype, Container, {
5137 getGroupClass: function getGroupClass() {
5138 return Group;
5139 }
5140 });
5141
5142 var engines = {};
5143
5144 function getEngine(name) {
5145 var G = engines[name];
5146
5147 if (G) {
5148 return G;
5149 }
5150
5151 return {
5152 Canvas: Canvas,
5153 Group: Group,
5154 Shape: Shape
5155 };
5156 }
5157
5158 function createCanvas(cfg) {
5159 var renderer = cfg.renderer;
5160 var G = getEngine(renderer);
5161 return new G.Canvas(cfg);
5162 }
5163
5164 var arrayWithHoles = createCommonjsModule(function (module) {
5165 function _arrayWithHoles(arr) {
5166 if (Array.isArray(arr)) return arr;
5167 }
5168
5169 module.exports = _arrayWithHoles, module.exports.__esModule = true, module.exports["default"] = module.exports;
5170 });
5171
5172 var iterableToArrayLimit = createCommonjsModule(function (module) {
5173 function _iterableToArrayLimit(arr, i) {
5174 var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
5175
5176 if (_i == null) return;
5177 var _arr = [];
5178 var _n = true;
5179 var _d = false;
5180
5181 var _s, _e;
5182
5183 try {
5184 for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) {
5185 _arr.push(_s.value);
5186
5187 if (i && _arr.length === i) break;
5188 }
5189 } catch (err) {
5190 _d = true;
5191 _e = err;
5192 } finally {
5193 try {
5194 if (!_n && _i["return"] != null) _i["return"]();
5195 } finally {
5196 if (_d) throw _e;
5197 }
5198 }
5199
5200 return _arr;
5201 }
5202
5203 module.exports = _iterableToArrayLimit, module.exports.__esModule = true, module.exports["default"] = module.exports;
5204 });
5205
5206 var arrayLikeToArray = createCommonjsModule(function (module) {
5207 function _arrayLikeToArray(arr, len) {
5208 if (len == null || len > arr.length) len = arr.length;
5209
5210 for (var i = 0, arr2 = new Array(len); i < len; i++) {
5211 arr2[i] = arr[i];
5212 }
5213
5214 return arr2;
5215 }
5216
5217 module.exports = _arrayLikeToArray, module.exports.__esModule = true, module.exports["default"] = module.exports;
5218 });
5219
5220 var unsupportedIterableToArray = createCommonjsModule(function (module) {
5221 function _unsupportedIterableToArray(o, minLen) {
5222 if (!o) return;
5223 if (typeof o === "string") return arrayLikeToArray(o, minLen);
5224 var n = Object.prototype.toString.call(o).slice(8, -1);
5225 if (n === "Object" && o.constructor) n = o.constructor.name;
5226 if (n === "Map" || n === "Set") return Array.from(o);
5227 if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return arrayLikeToArray(o, minLen);
5228 }
5229
5230 module.exports = _unsupportedIterableToArray, module.exports.__esModule = true, module.exports["default"] = module.exports;
5231 });
5232
5233 var nonIterableRest = createCommonjsModule(function (module) {
5234 function _nonIterableRest() {
5235 throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
5236 }
5237
5238 module.exports = _nonIterableRest, module.exports.__esModule = true, module.exports["default"] = module.exports;
5239 });
5240
5241 var slicedToArray = createCommonjsModule(function (module) {
5242 function _slicedToArray(arr, i) {
5243 return arrayWithHoles(arr) || iterableToArrayLimit(arr, i) || unsupportedIterableToArray(arr, i) || nonIterableRest();
5244 }
5245
5246 module.exports = _slicedToArray, module.exports.__esModule = true, module.exports["default"] = module.exports;
5247 });
5248
5249 var _slicedToArray = /*@__PURE__*/getDefaultExportFromCjs(slicedToArray);
5250
5251 var Layout = /*#__PURE__*/function () {
5252 function Layout(layout) {
5253 _classCallCheck(this, Layout);
5254
5255 this.left = 0;
5256 this.top = 0;
5257 this.width = 0;
5258 this.height = 0;
5259 this.update(layout);
5260 }
5261
5262 _createClass(Layout, [{
5263 key: "update",
5264 value: function update(layout) {
5265 mix(this, layout);
5266 var left = this.left,
5267 top = this.top,
5268 width = this.width,
5269 height = this.height;
5270 this.right = left + width;
5271 this.bottom = top + height;
5272 return this;
5273 }
5274 }, {
5275 key: "padding",
5276 value: function padding(style) {
5277 if (!style) {
5278 return this;
5279 }
5280
5281 var _style$top = style.top,
5282 paddingTop = _style$top === void 0 ? 0 : _style$top,
5283 _style$right = style.right,
5284 paddingRight = _style$right === void 0 ? 0 : _style$right,
5285 _style$bottom = style.bottom,
5286 paddingBottom = _style$bottom === void 0 ? 0 : _style$bottom,
5287 _style$left = style.left,
5288 paddingLeft = _style$left === void 0 ? 0 : _style$left;
5289 var top = this.top,
5290 right = this.right,
5291 bottom = this.bottom,
5292 left = this.left;
5293 this.top = top + paddingTop;
5294 this.right = right - paddingRight;
5295 this.bottom = bottom - paddingBottom;
5296 this.left = left + paddingLeft;
5297 this.width = this.right - this.left;
5298 this.height = this.bottom - this.top;
5299 return this;
5300 }
5301 }, {
5302 key: "clone",
5303 value: function clone() {
5304 var left = this.left,
5305 top = this.top,
5306 width = this.width,
5307 height = this.height;
5308 return new Layout({
5309 left: left,
5310 top: top,
5311 width: width,
5312 height: height
5313 });
5314 }
5315 }], [{
5316 key: "fromStyle",
5317 value: function fromStyle(style) {
5318 var left = style.left,
5319 top = style.top,
5320 width = style.width,
5321 height = style.height,
5322 padding = style.padding;
5323
5324 var _padding = _slicedToArray(padding, 4),
5325 paddingTop = _padding[0],
5326 paddingRight = _padding[1],
5327 paddingBottom = _padding[2],
5328 paddingLeft = _padding[3];
5329
5330 return new Layout({
5331 left: left + paddingLeft,
5332 top: top + paddingTop,
5333 width: width - paddingLeft - paddingRight,
5334 height: height - paddingTop - paddingBottom
5335 });
5336 }
5337 }]);
5338
5339 return Layout;
5340 }();
5341
5342 function objToString(obj) {
5343 return Object.prototype.toString.call(obj);
5344 }
5345
5346 function objectKeys(obj) {
5347 return Object.keys(obj);
5348 }
5349
5350 function equal(a, b) {
5351 if (a === b) return true;
5352
5353 if (_typeof(a) !== _typeof(b)) {
5354 return false;
5355 } // null 和 undefined
5356
5357
5358 if (a == null || b == null) {
5359 return false;
5360 } // 特殊处理NaN
5361
5362
5363 if (Number.isNaN(a) && Number.isNaN(b)) {
5364 return true;
5365 }
5366
5367 if (objToString(a) !== objToString(b)) {
5368 return false;
5369 } // 如果是function, 则认为是相对
5370
5371
5372 if (isFunction(a)) {
5373 return true;
5374 } // 值类型,Number String Boolean
5375
5376
5377 if (_typeof(a) !== 'object') {
5378 return false;
5379 }
5380
5381 if (isArray(a)) {
5382 if (a.length !== b.length) {
5383 return false;
5384 }
5385
5386 for (var i = a.length - 1; i >= 0; i--) {
5387 if (!equal(a[i], b[i])) {
5388 return false;
5389 }
5390 }
5391
5392 return true;
5393 }
5394
5395 if (!isPlainObject(a)) {
5396 return false;
5397 }
5398
5399 var ka = objectKeys(a);
5400 var kb = objectKeys(b); // having the same number of owned properties (keys incorporates hasOwnProperty)
5401
5402 if (ka.length !== kb.length) {
5403 return false;
5404 } // the same set of keys (although not necessarily the same order),
5405
5406
5407 ka.sort();
5408 kb.sort(); // ~~~cheap key test
5409
5410 for (var _i = ka.length - 1; _i >= 0; _i--) {
5411 if (ka[_i] != kb[_i]) {
5412 return false;
5413 }
5414 } // equivalent values for every corresponding key, and ~~~possibly expensive deep test
5415
5416
5417 for (var _i2 = ka.length - 1; _i2 >= 0; _i2--) {
5418 var key = ka[_i2];
5419
5420 if (!equal(a[key], b[key])) {
5421 return false;
5422 }
5423 }
5424
5425 return true;
5426 }
5427
5428 var requestAnimationFrame$2 = (typeof window === "undefined" ? "undefined" : _typeof(window)) === 'object' && window.requestAnimationFrame ? window.requestAnimationFrame : function (fn) {
5429 return setTimeout(fn, 16);
5430 };
5431 var cancelAnimationFrame$1 = (typeof window === "undefined" ? "undefined" : _typeof(window)) === 'object' && window.cancelAnimationFrame ? window.cancelAnimationFrame : function (number) {
5432 return clearTimeout(number);
5433 };
5434 var clock = (typeof performance === "undefined" ? "undefined" : _typeof(performance)) === 'object' && performance.now ? performance : Date;
5435
5436 var Timeline$1 = /*#__PURE__*/function () {
5437 function Timeline() {
5438 _classCallCheck(this, Timeline);
5439
5440 this.playing = false; // 暂停中
5441
5442 this.paused = false; // 暂停的时间点
5443
5444 this.pausedTime = 0;
5445 }
5446
5447 _createClass(Timeline, [{
5448 key: "play",
5449 value: function play(duration, onUpdate, onEnd) {
5450 var _this = this;
5451
5452 if (duration <= 0) {
5453 onEnd();
5454 return;
5455 } // 上次动画未结束
5456
5457
5458 if (this.playing) {
5459 return;
5460 } // 记录 duration、onUpdate、onEnd
5461
5462
5463 this.duration = duration;
5464 this.onUpdate = onUpdate;
5465 this.onEnd = onEnd;
5466 var paused = this.paused,
5467 pausedTime = this.pausedTime;
5468 this.playing = true;
5469 var startTime = clock.now(); // 如果当前正在暂停状态, 从暂停态继续播放
5470
5471 if (paused && pausedTime) {
5472 startTime = startTime - pausedTime;
5473 this.paused = false;
5474 this.pausedTime = 0;
5475 }
5476
5477 var play = function play() {
5478 var now = clock.now();
5479 var time = now - startTime;
5480
5481 if (time >= duration) {
5482 onUpdate(duration);
5483 onEnd();
5484 _this.playing = false;
5485 return;
5486 }
5487
5488 if (_this.paused) {
5489 onUpdate(time);
5490 _this.pausedTime = time;
5491 _this.playing = false;
5492 return;
5493 }
5494
5495 onUpdate(time);
5496 _this.animationFrameNumber = requestAnimationFrame$2(play);
5497 };
5498
5499 this.animationFrameNumber = requestAnimationFrame$2(play);
5500 }
5501 }, {
5502 key: "pause",
5503 value: function pause() {
5504 this.paused = true;
5505 }
5506 }, {
5507 key: "stop",
5508 value: function stop() {
5509 this.playing = false;
5510 }
5511 }, {
5512 key: "end",
5513 value: function end() {
5514 if (!this.playing) {
5515 return;
5516 } // 停掉动画
5517
5518
5519 this.abort(); // 更新到最后一帧状态
5520
5521 this.onUpdate(this.duration);
5522 this.onEnd();
5523 }
5524 }, {
5525 key: "abort",
5526 value: function abort() {
5527 if (!this.animationFrameNumber) {
5528 return;
5529 }
5530
5531 cancelAnimationFrame$1(this.animationFrameNumber);
5532 this.playing = false;
5533 this.animationFrameNumber = null;
5534 }
5535 }]);
5536
5537 return Timeline;
5538 }();
5539
5540 function define (constructor, factory, prototype) {
5541 constructor.prototype = factory.prototype = prototype;
5542 prototype.constructor = constructor;
5543 }
5544 function extend(parent, definition) {
5545 var prototype = Object.create(parent.prototype);
5546
5547 for (var key in definition) {
5548 prototype[key] = definition[key];
5549 }
5550
5551 return prototype;
5552 }
5553
5554 function Color() {}
5555 var _darker = 0.7;
5556
5557 var _brighter = 1 / _darker;
5558 var reI = "\\s*([+-]?\\d+)\\s*",
5559 reN = "\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)\\s*",
5560 reP = "\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)%\\s*",
5561 reHex = /^#([0-9a-f]{3,8})$/,
5562 reRgbInteger = new RegExp("^rgb\\(" + [reI, reI, reI] + "\\)$"),
5563 reRgbPercent = new RegExp("^rgb\\(" + [reP, reP, reP] + "\\)$"),
5564 reRgbaInteger = new RegExp("^rgba\\(" + [reI, reI, reI, reN] + "\\)$"),
5565 reRgbaPercent = new RegExp("^rgba\\(" + [reP, reP, reP, reN] + "\\)$"),
5566 reHslPercent = new RegExp("^hsl\\(" + [reN, reP, reP] + "\\)$"),
5567 reHslaPercent = new RegExp("^hsla\\(" + [reN, reP, reP, reN] + "\\)$");
5568 var named = {
5569 aliceblue: 0xf0f8ff,
5570 antiquewhite: 0xfaebd7,
5571 aqua: 0x00ffff,
5572 aquamarine: 0x7fffd4,
5573 azure: 0xf0ffff,
5574 beige: 0xf5f5dc,
5575 bisque: 0xffe4c4,
5576 black: 0x000000,
5577 blanchedalmond: 0xffebcd,
5578 blue: 0x0000ff,
5579 blueviolet: 0x8a2be2,
5580 brown: 0xa52a2a,
5581 burlywood: 0xdeb887,
5582 cadetblue: 0x5f9ea0,
5583 chartreuse: 0x7fff00,
5584 chocolate: 0xd2691e,
5585 coral: 0xff7f50,
5586 cornflowerblue: 0x6495ed,
5587 cornsilk: 0xfff8dc,
5588 crimson: 0xdc143c,
5589 cyan: 0x00ffff,
5590 darkblue: 0x00008b,
5591 darkcyan: 0x008b8b,
5592 darkgoldenrod: 0xb8860b,
5593 darkgray: 0xa9a9a9,
5594 darkgreen: 0x006400,
5595 darkgrey: 0xa9a9a9,
5596 darkkhaki: 0xbdb76b,
5597 darkmagenta: 0x8b008b,
5598 darkolivegreen: 0x556b2f,
5599 darkorange: 0xff8c00,
5600 darkorchid: 0x9932cc,
5601 darkred: 0x8b0000,
5602 darksalmon: 0xe9967a,
5603 darkseagreen: 0x8fbc8f,
5604 darkslateblue: 0x483d8b,
5605 darkslategray: 0x2f4f4f,
5606 darkslategrey: 0x2f4f4f,
5607 darkturquoise: 0x00ced1,
5608 darkviolet: 0x9400d3,
5609 deeppink: 0xff1493,
5610 deepskyblue: 0x00bfff,
5611 dimgray: 0x696969,
5612 dimgrey: 0x696969,
5613 dodgerblue: 0x1e90ff,
5614 firebrick: 0xb22222,
5615 floralwhite: 0xfffaf0,
5616 forestgreen: 0x228b22,
5617 fuchsia: 0xff00ff,
5618 gainsboro: 0xdcdcdc,
5619 ghostwhite: 0xf8f8ff,
5620 gold: 0xffd700,
5621 goldenrod: 0xdaa520,
5622 gray: 0x808080,
5623 green: 0x008000,
5624 greenyellow: 0xadff2f,
5625 grey: 0x808080,
5626 honeydew: 0xf0fff0,
5627 hotpink: 0xff69b4,
5628 indianred: 0xcd5c5c,
5629 indigo: 0x4b0082,
5630 ivory: 0xfffff0,
5631 khaki: 0xf0e68c,
5632 lavender: 0xe6e6fa,
5633 lavenderblush: 0xfff0f5,
5634 lawngreen: 0x7cfc00,
5635 lemonchiffon: 0xfffacd,
5636 lightblue: 0xadd8e6,
5637 lightcoral: 0xf08080,
5638 lightcyan: 0xe0ffff,
5639 lightgoldenrodyellow: 0xfafad2,
5640 lightgray: 0xd3d3d3,
5641 lightgreen: 0x90ee90,
5642 lightgrey: 0xd3d3d3,
5643 lightpink: 0xffb6c1,
5644 lightsalmon: 0xffa07a,
5645 lightseagreen: 0x20b2aa,
5646 lightskyblue: 0x87cefa,
5647 lightslategray: 0x778899,
5648 lightslategrey: 0x778899,
5649 lightsteelblue: 0xb0c4de,
5650 lightyellow: 0xffffe0,
5651 lime: 0x00ff00,
5652 limegreen: 0x32cd32,
5653 linen: 0xfaf0e6,
5654 magenta: 0xff00ff,
5655 maroon: 0x800000,
5656 mediumaquamarine: 0x66cdaa,
5657 mediumblue: 0x0000cd,
5658 mediumorchid: 0xba55d3,
5659 mediumpurple: 0x9370db,
5660 mediumseagreen: 0x3cb371,
5661 mediumslateblue: 0x7b68ee,
5662 mediumspringgreen: 0x00fa9a,
5663 mediumturquoise: 0x48d1cc,
5664 mediumvioletred: 0xc71585,
5665 midnightblue: 0x191970,
5666 mintcream: 0xf5fffa,
5667 mistyrose: 0xffe4e1,
5668 moccasin: 0xffe4b5,
5669 navajowhite: 0xffdead,
5670 navy: 0x000080,
5671 oldlace: 0xfdf5e6,
5672 olive: 0x808000,
5673 olivedrab: 0x6b8e23,
5674 orange: 0xffa500,
5675 orangered: 0xff4500,
5676 orchid: 0xda70d6,
5677 palegoldenrod: 0xeee8aa,
5678 palegreen: 0x98fb98,
5679 paleturquoise: 0xafeeee,
5680 palevioletred: 0xdb7093,
5681 papayawhip: 0xffefd5,
5682 peachpuff: 0xffdab9,
5683 peru: 0xcd853f,
5684 pink: 0xffc0cb,
5685 plum: 0xdda0dd,
5686 powderblue: 0xb0e0e6,
5687 purple: 0x800080,
5688 rebeccapurple: 0x663399,
5689 red: 0xff0000,
5690 rosybrown: 0xbc8f8f,
5691 royalblue: 0x4169e1,
5692 saddlebrown: 0x8b4513,
5693 salmon: 0xfa8072,
5694 sandybrown: 0xf4a460,
5695 seagreen: 0x2e8b57,
5696 seashell: 0xfff5ee,
5697 sienna: 0xa0522d,
5698 silver: 0xc0c0c0,
5699 skyblue: 0x87ceeb,
5700 slateblue: 0x6a5acd,
5701 slategray: 0x708090,
5702 slategrey: 0x708090,
5703 snow: 0xfffafa,
5704 springgreen: 0x00ff7f,
5705 steelblue: 0x4682b4,
5706 tan: 0xd2b48c,
5707 teal: 0x008080,
5708 thistle: 0xd8bfd8,
5709 tomato: 0xff6347,
5710 turquoise: 0x40e0d0,
5711 violet: 0xee82ee,
5712 wheat: 0xf5deb3,
5713 white: 0xffffff,
5714 whitesmoke: 0xf5f5f5,
5715 yellow: 0xffff00,
5716 yellowgreen: 0x9acd32
5717 };
5718 define(Color, color, {
5719 copy: function copy(channels) {
5720 return Object.assign(new this.constructor(), this, channels);
5721 },
5722 displayable: function displayable() {
5723 return this.rgb().displayable();
5724 },
5725 hex: color_formatHex,
5726 // Deprecated! Use color.formatHex.
5727 formatHex: color_formatHex,
5728 formatHsl: color_formatHsl,
5729 formatRgb: color_formatRgb,
5730 toString: color_formatRgb
5731 });
5732
5733 function color_formatHex() {
5734 return this.rgb().formatHex();
5735 }
5736
5737 function color_formatHsl() {
5738 return hslConvert(this).formatHsl();
5739 }
5740
5741 function color_formatRgb() {
5742 return this.rgb().formatRgb();
5743 }
5744
5745 function color(format) {
5746 var m, l;
5747 format = (format + "").trim().toLowerCase();
5748 return (m = reHex.exec(format)) ? (l = m[1].length, m = parseInt(m[1], 16), l === 6 ? rgbn(m) // #ff0000
5749 : l === 3 ? new Rgb(m >> 8 & 0xf | m >> 4 & 0xf0, m >> 4 & 0xf | m & 0xf0, (m & 0xf) << 4 | m & 0xf, 1) // #f00
5750 : l === 8 ? rgba(m >> 24 & 0xff, m >> 16 & 0xff, m >> 8 & 0xff, (m & 0xff) / 0xff) // #ff000000
5751 : l === 4 ? rgba(m >> 12 & 0xf | m >> 8 & 0xf0, m >> 8 & 0xf | m >> 4 & 0xf0, m >> 4 & 0xf | m & 0xf0, ((m & 0xf) << 4 | m & 0xf) / 0xff) // #f000
5752 : null // invalid hex
5753 ) : (m = reRgbInteger.exec(format)) ? new Rgb(m[1], m[2], m[3], 1) // rgb(255, 0, 0)
5754 : (m = reRgbPercent.exec(format)) ? new Rgb(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, 1) // rgb(100%, 0%, 0%)
5755 : (m = reRgbaInteger.exec(format)) ? rgba(m[1], m[2], m[3], m[4]) // rgba(255, 0, 0, 1)
5756 : (m = reRgbaPercent.exec(format)) ? rgba(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, m[4]) // rgb(100%, 0%, 0%, 1)
5757 : (m = reHslPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, 1) // hsl(120, 50%, 50%)
5758 : (m = reHslaPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, m[4]) // hsla(120, 50%, 50%, 1)
5759 : named.hasOwnProperty(format) ? rgbn(named[format]) // eslint-disable-line no-prototype-builtins
5760 : format === "transparent" ? new Rgb(NaN, NaN, NaN, 0) : null;
5761 }
5762
5763 function rgbn(n) {
5764 return new Rgb(n >> 16 & 0xff, n >> 8 & 0xff, n & 0xff, 1);
5765 }
5766
5767 function rgba(r, g, b, a) {
5768 if (a <= 0) r = g = b = NaN;
5769 return new Rgb(r, g, b, a);
5770 }
5771
5772 function rgbConvert(o) {
5773 if (!(o instanceof Color)) o = color(o);
5774 if (!o) return new Rgb();
5775 o = o.rgb();
5776 return new Rgb(o.r, o.g, o.b, o.opacity);
5777 }
5778 function rgb(r, g, b, opacity) {
5779 return arguments.length === 1 ? rgbConvert(r) : new Rgb(r, g, b, opacity == null ? 1 : opacity);
5780 }
5781 function Rgb(r, g, b, opacity) {
5782 this.r = +r;
5783 this.g = +g;
5784 this.b = +b;
5785 this.opacity = +opacity;
5786 }
5787 define(Rgb, rgb, extend(Color, {
5788 brighter: function brighter(k) {
5789 k = k == null ? _brighter : Math.pow(_brighter, k);
5790 return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity);
5791 },
5792 darker: function darker(k) {
5793 k = k == null ? _darker : Math.pow(_darker, k);
5794 return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity);
5795 },
5796 rgb: function rgb() {
5797 return this;
5798 },
5799 displayable: function displayable() {
5800 return -0.5 <= this.r && this.r < 255.5 && -0.5 <= this.g && this.g < 255.5 && -0.5 <= this.b && this.b < 255.5 && 0 <= this.opacity && this.opacity <= 1;
5801 },
5802 hex: rgb_formatHex,
5803 // Deprecated! Use color.formatHex.
5804 formatHex: rgb_formatHex,
5805 formatRgb: rgb_formatRgb,
5806 toString: rgb_formatRgb
5807 }));
5808
5809 function rgb_formatHex() {
5810 return "#" + hex(this.r) + hex(this.g) + hex(this.b);
5811 }
5812
5813 function rgb_formatRgb() {
5814 var a = this.opacity;
5815 a = isNaN(a) ? 1 : Math.max(0, Math.min(1, a));
5816 return (a === 1 ? "rgb(" : "rgba(") + Math.max(0, Math.min(255, Math.round(this.r) || 0)) + ", " + Math.max(0, Math.min(255, Math.round(this.g) || 0)) + ", " + Math.max(0, Math.min(255, Math.round(this.b) || 0)) + (a === 1 ? ")" : ", " + a + ")");
5817 }
5818
5819 function hex(value) {
5820 value = Math.max(0, Math.min(255, Math.round(value) || 0));
5821 return (value < 16 ? "0" : "") + value.toString(16);
5822 }
5823
5824 function hsla(h, s, l, a) {
5825 if (a <= 0) h = s = l = NaN;else if (l <= 0 || l >= 1) h = s = NaN;else if (s <= 0) h = NaN;
5826 return new Hsl(h, s, l, a);
5827 }
5828
5829 function hslConvert(o) {
5830 if (o instanceof Hsl) return new Hsl(o.h, o.s, o.l, o.opacity);
5831 if (!(o instanceof Color)) o = color(o);
5832 if (!o) return new Hsl();
5833 if (o instanceof Hsl) return o;
5834 o = o.rgb();
5835 var r = o.r / 255,
5836 g = o.g / 255,
5837 b = o.b / 255,
5838 min = Math.min(r, g, b),
5839 max = Math.max(r, g, b),
5840 h = NaN,
5841 s = max - min,
5842 l = (max + min) / 2;
5843
5844 if (s) {
5845 if (r === max) h = (g - b) / s + (g < b) * 6;else if (g === max) h = (b - r) / s + 2;else h = (r - g) / s + 4;
5846 s /= l < 0.5 ? max + min : 2 - max - min;
5847 h *= 60;
5848 } else {
5849 s = l > 0 && l < 1 ? 0 : h;
5850 }
5851
5852 return new Hsl(h, s, l, o.opacity);
5853 }
5854 function hsl(h, s, l, opacity) {
5855 return arguments.length === 1 ? hslConvert(h) : new Hsl(h, s, l, opacity == null ? 1 : opacity);
5856 }
5857
5858 function Hsl(h, s, l, opacity) {
5859 this.h = +h;
5860 this.s = +s;
5861 this.l = +l;
5862 this.opacity = +opacity;
5863 }
5864
5865 define(Hsl, hsl, extend(Color, {
5866 brighter: function brighter(k) {
5867 k = k == null ? _brighter : Math.pow(_brighter, k);
5868 return new Hsl(this.h, this.s, this.l * k, this.opacity);
5869 },
5870 darker: function darker(k) {
5871 k = k == null ? _darker : Math.pow(_darker, k);
5872 return new Hsl(this.h, this.s, this.l * k, this.opacity);
5873 },
5874 rgb: function rgb() {
5875 var h = this.h % 360 + (this.h < 0) * 360,
5876 s = isNaN(h) || isNaN(this.s) ? 0 : this.s,
5877 l = this.l,
5878 m2 = l + (l < 0.5 ? l : 1 - l) * s,
5879 m1 = 2 * l - m2;
5880 return new Rgb(hsl2rgb(h >= 240 ? h - 240 : h + 120, m1, m2), hsl2rgb(h, m1, m2), hsl2rgb(h < 120 ? h + 240 : h - 120, m1, m2), this.opacity);
5881 },
5882 displayable: function displayable() {
5883 return (0 <= this.s && this.s <= 1 || isNaN(this.s)) && 0 <= this.l && this.l <= 1 && 0 <= this.opacity && this.opacity <= 1;
5884 },
5885 formatHsl: function formatHsl() {
5886 var a = this.opacity;
5887 a = isNaN(a) ? 1 : Math.max(0, Math.min(1, a));
5888 return (a === 1 ? "hsl(" : "hsla(") + (this.h || 0) + ", " + (this.s || 0) * 100 + "%, " + (this.l || 0) * 100 + "%" + (a === 1 ? ")" : ", " + a + ")");
5889 }
5890 }));
5891 /* From FvD 13.37, CSS Color Module Level 3 */
5892
5893 function hsl2rgb(h, m1, m2) {
5894 return (h < 60 ? m1 + (m2 - m1) * h / 60 : h < 180 ? m2 : h < 240 ? m1 + (m2 - m1) * (240 - h) / 60 : m1) * 255;
5895 }
5896
5897 var constant = (function (x) {
5898 return function () {
5899 return x;
5900 };
5901 });
5902
5903 function linear(a, d) {
5904 return function (t) {
5905 return a + t * d;
5906 };
5907 }
5908
5909 function exponential(a, b, y) {
5910 return a = Math.pow(a, y), b = Math.pow(b, y) - a, y = 1 / y, function (t) {
5911 return Math.pow(a + t * b, y);
5912 };
5913 }
5914 function gamma(y) {
5915 return (y = +y) === 1 ? nogamma : function (a, b) {
5916 return b - a ? exponential(a, b, y) : constant(isNaN(a) ? b : a);
5917 };
5918 }
5919 function nogamma(a, b) {
5920 var d = b - a;
5921 return d ? linear(a, d) : constant(isNaN(a) ? b : a);
5922 }
5923
5924 var interpolateRgb = (function rgbGamma(y) {
5925 var color = gamma(y);
5926
5927 function rgb$1(start, end) {
5928 var r = color((start = rgb(start)).r, (end = rgb(end)).r),
5929 g = color(start.g, end.g),
5930 b = color(start.b, end.b),
5931 opacity = nogamma(start.opacity, end.opacity);
5932 return function (t) {
5933 start.r = r(t);
5934 start.g = g(t);
5935 start.b = b(t);
5936 start.opacity = opacity(t);
5937 return start + '';
5938 };
5939 }
5940
5941 rgb$1.gamma = rgbGamma;
5942 return rgb$1;
5943 })(1);
5944
5945 function interpolateNumberArray (a, b) {
5946 if (!b) b = [];
5947 var n = a ? Math.min(b.length, a.length) : 0,
5948 c = b.slice(),
5949 i;
5950 return function (t) {
5951 for (i = 0; i < n; ++i) {
5952 c[i] = a[i] * (1 - t) + b[i] * t;
5953 }
5954
5955 return c;
5956 };
5957 }
5958 function isNumberArray(x) {
5959 return ArrayBuffer.isView(x) && !(x instanceof DataView);
5960 }
5961
5962 function genericArray(a, b) {
5963 var nb = b ? b.length : 0,
5964 na = a ? Math.min(nb, a.length) : 0,
5965 x = new Array(na),
5966 c = new Array(nb),
5967 i;
5968
5969 for (i = 0; i < na; ++i) {
5970 x[i] = interpolate(a[i], b[i]);
5971 }
5972
5973 for (; i < nb; ++i) {
5974 c[i] = b[i];
5975 }
5976
5977 return function (t) {
5978 for (i = 0; i < na; ++i) {
5979 c[i] = x[i](t);
5980 }
5981
5982 return c;
5983 };
5984 }
5985
5986 function date (a, b) {
5987 var d = new Date();
5988 return a = +a, b = +b, function (t) {
5989 return d.setTime(a * (1 - t) + b * t), d;
5990 };
5991 }
5992
5993 function interpolateNumber (a, b) {
5994 return a = +a, b = +b, function (t) {
5995 return a * (1 - t) + b * t;
5996 };
5997 }
5998
5999 function interpolateObject (a, b) {
6000 var i = {},
6001 c = {},
6002 k;
6003 if (a === null || _typeof(a) !== "object") a = {};
6004 if (b === null || _typeof(b) !== "object") b = {};
6005
6006 for (k in b) {
6007 if (k in a) {
6008 i[k] = interpolate(a[k], b[k]);
6009 } else {
6010 c[k] = b[k];
6011 }
6012 }
6013
6014 return function (t) {
6015 for (k in i) {
6016 c[k] = i[k](t);
6017 }
6018
6019 return c;
6020 };
6021 }
6022
6023 var reA = /[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g,
6024 reB = new RegExp(reA.source, "g");
6025
6026 function zero(b) {
6027 return function () {
6028 return b;
6029 };
6030 }
6031
6032 function one(b) {
6033 return function (t) {
6034 return b(t) + "";
6035 };
6036 }
6037
6038 function string (a, b) {
6039 var bi = reA.lastIndex = reB.lastIndex = 0,
6040 // scan index for next number in b
6041 am,
6042 // current match in a
6043 bm,
6044 // current match in b
6045 bs,
6046 // string preceding current number in b, if any
6047 i = -1,
6048 // index in s
6049 s = [],
6050 // string constants and placeholders
6051 q = []; // number interpolators
6052 // Coerce inputs to strings.
6053
6054 a = a + "", b = b + ""; // Interpolate pairs of numbers in a & b.
6055
6056 while ((am = reA.exec(a)) && (bm = reB.exec(b))) {
6057 if ((bs = bm.index) > bi) {
6058 // a string precedes the next number in b
6059 bs = b.slice(bi, bs);
6060 if (s[i]) s[i] += bs; // coalesce with previous string
6061 else s[++i] = bs;
6062 }
6063
6064 if ((am = am[0]) === (bm = bm[0])) {
6065 // numbers in a & b match
6066 if (s[i]) s[i] += bm; // coalesce with previous string
6067 else s[++i] = bm;
6068 } else {
6069 // interpolate non-matching numbers
6070 s[++i] = null;
6071 q.push({
6072 i: i,
6073 x: interpolateNumber(am, bm)
6074 });
6075 }
6076
6077 bi = reB.lastIndex;
6078 } // Add remains of b.
6079
6080
6081 if (bi < b.length) {
6082 bs = b.slice(bi);
6083 if (s[i]) s[i] += bs; // coalesce with previous string
6084 else s[++i] = bs;
6085 } // Special optimization for only a single match.
6086 // Otherwise, interpolate each of the numbers and rejoin the string.
6087
6088
6089 return s.length < 2 ? q[0] ? one(q[0].x) : zero(b) : (b = q.length, function (t) {
6090 for (var i = 0, o; i < b; ++i) {
6091 s[(o = q[i]).i] = o.x(t);
6092 }
6093
6094 return s.join("");
6095 });
6096 }
6097
6098 function interpolate (a, b) {
6099 var t = _typeof(b),
6100 c;
6101
6102 return b == null || t === 'boolean' ? constant(b) : (t === 'number' ? interpolateNumber : t === 'string' ? (c = color(b)) ? (b = c, interpolateRgb) : string : b instanceof color ? interpolateRgb : b instanceof Date ? date : isNumberArray(b) ? interpolateNumberArray : Array.isArray(b) ? genericArray : typeof b.valueOf !== 'function' && typeof b.toString !== 'function' || isNaN(b) ? interpolateObject : interpolateNumber)(a, b);
6103 }
6104
6105 function interpolateObjectArray(a, b) {
6106 var na = a ? a.length : 0;
6107 var nb = b ? b.length : 0;
6108 var maxLen = Math.max(nb, na);
6109 var c = new Array(maxLen);
6110 var x = new Array(maxLen);
6111 var i; // 将a、b长度补齐后再进行插值计算
6112
6113 for (i = 0; i < maxLen; i++) {
6114 var ia = i < na ? (a || [])[i] : (a || [])[na - 1];
6115 var ib = i < nb ? (b || [])[i] : (b || [])[nb - 1];
6116 x[i] = interpolateObject(ia, ib);
6117 }
6118
6119 return function (t) {
6120 // 清除补间的多余点
6121 if (t >= 1) {
6122 return b;
6123 }
6124
6125 for (i = 0; i < maxLen; ++i) {
6126 c[i] = x[i](t);
6127 }
6128
6129 return c;
6130 };
6131 }
6132
6133 var interpolate$1 = (function (a, b) {
6134 if (typeof b === 'string') {
6135 return interpolateRgb(a, b);
6136 }
6137
6138 if (Array.isArray(b)) {
6139 if (typeof b[0] !== 'number') {
6140 // if (hasNaN(a[0])) {
6141 // return interpolateObjectArray(b, b);
6142 // }
6143 return interpolateObjectArray(a, b);
6144 }
6145
6146 return interpolateNumberArray(a, b);
6147 } // if (isNaN(a)) {
6148 // return interpolateNumber(b, b);
6149 // }
6150
6151
6152 return interpolateNumber(a, b);
6153 });
6154
6155 // https://github.com/tweenjs/tween.js
6156 function linear$1(k) {
6157 return k;
6158 }
6159
6160 function quadraticIn(k) {
6161 return k * k;
6162 }
6163
6164 function quadraticOut(k) {
6165 return k * (2 - k);
6166 }
6167
6168 function quadraticInOut(k) {
6169 if ((k *= 2) < 1) {
6170 return 0.5 * k * k;
6171 }
6172
6173 return -0.5 * (--k * (k - 2) - 1);
6174 }
6175
6176 function cubicIn(k) {
6177 return k * k * k;
6178 }
6179
6180 function cubicOut(k) {
6181 return --k * k * k + 1;
6182 }
6183
6184 function cubicInOut(k) {
6185 if ((k *= 2) < 1) {
6186 return 0.5 * k * k * k;
6187 }
6188
6189 return 0.5 * ((k -= 2) * k * k + 2);
6190 }
6191
6192 function quarticIn(k) {
6193 return k * k * k * k;
6194 }
6195
6196 function quarticOut(k) {
6197 return 1 - k * k * k * k;
6198 }
6199
6200 function quarticInOut(k) {
6201 if ((k *= 2) < 1) {
6202 return 0.5 * k * k * k * k;
6203 }
6204
6205 return -0.5 * ((k -= 2) * k * k * k - 2);
6206 }
6207
6208 function quinticIn(k) {
6209 return k * k * k * k * k;
6210 }
6211
6212 function quinticOut(k) {
6213 return --k * k * k * k * k + 1;
6214 }
6215
6216 function quinticInOut(k) {
6217 if ((k *= 2) < 1) {
6218 return 0.5 * k * k * k * k * k;
6219 }
6220
6221 return 0.5 * ((k -= 2) * k * k * k * k + 2);
6222 }
6223
6224 function exponentialIn(k) {
6225 return k === 0 ? 0 : Math.pow(1024, k - 1);
6226 }
6227
6228 function exponentialOut(k) {
6229 return k === 1 ? 1 : 1 - Math.pow(2, -10 * k);
6230 }
6231
6232 function elasticIn(k) {
6233 var s;
6234 var a = 0.1;
6235 var p = 0.4;
6236 if (k === 0) return 0;
6237 if (k === 1) return 1;
6238
6239 if (!a || a < 1) {
6240 a = 1;
6241 s = p / 4;
6242 } else {
6243 s = p / (2 * Math.PI) * Math.asin(1 / a);
6244 }
6245
6246 return -(a * Math.pow(2, 10 * (k -= 1)) * Math.sin((k - s) * (2 * Math.PI) / p));
6247 }
6248
6249 function elasticOut(k) {
6250 var s;
6251 var a = 0.1;
6252 var p = 0.4;
6253 if (k === 0) return 0;
6254 if (k === 1) return 1;
6255
6256 if (!a || a < 1) {
6257 a = 1;
6258 s = p / 4;
6259 } else {
6260 s = p / (2 * Math.PI) * Math.asin(1 / a);
6261 }
6262
6263 return a * Math.pow(2, -10 * k) * Math.sin((k - s) * (2 * Math.PI) / p) + 1;
6264 }
6265
6266 function elasticInOut(k) {
6267 var s;
6268 var a = 0.1;
6269 var p = 0.4;
6270 if (k === 0) return 0;
6271 if (k === 1) return 1;
6272
6273 if (!a || a < 1) {
6274 a = 1;
6275 s = p / 4;
6276 } else {
6277 s = p / (2 * Math.PI) * Math.asin(1 / a);
6278 }
6279
6280 if ((k *= 2) < 1) {
6281 return -0.5 * (a * Math.pow(2, 10 * (k -= 1)) * Math.sin((k - s) * (2 * Math.PI) / p));
6282 }
6283
6284 return a * Math.pow(2, -10 * (k -= 1)) * Math.sin((k - s) * (2 * Math.PI) / p) * 0.5 + 1;
6285 }
6286
6287 function backIn(k) {
6288 var s = 1.70158;
6289 return k * k * ((s + 1) * k - s);
6290 }
6291
6292 function backOut(k) {
6293 var s = 1.70158;
6294 return (k = k - 1) * k * ((s + 1) * k + s) + 1;
6295 }
6296
6297 function backInOut(k) {
6298 var s = 1.70158 * 1.525;
6299
6300 if ((k *= 2) < 1) {
6301 return 0.5 * (k * k * ((s + 1) * k - s));
6302 }
6303
6304 return 0.5 * ((k -= 2) * k * ((s + 1) * k + s) + 2);
6305 }
6306
6307 function bounceIn(k) {
6308 return 1 - bounceOut(1 - k);
6309 }
6310
6311 function bounceOut(k) {
6312 if ((k /= 1) < 1 / 2.75) {
6313 return 7.5625 * k * k;
6314 } else if (k < 2 / 2.75) {
6315 return 7.5625 * (k -= 1.5 / 2.75) * k + 0.75;
6316 } else if (k < 2.5 / 2.75) {
6317 return 7.5625 * (k -= 2.25 / 2.75) * k + 0.9375;
6318 }
6319
6320 return 7.5625 * (k -= 2.625 / 2.75) * k + 0.984375;
6321 }
6322
6323 function bounceInOut(k) {
6324 if (k < 0.5) {
6325 return bounceIn(k * 2) * 0.5;
6326 }
6327
6328 return bounceOut(k * 2 - 1) * 0.5 + 0.5;
6329 }
6330
6331 var Easing = /*#__PURE__*/Object.freeze({
6332 __proto__: null,
6333 linear: linear$1,
6334 quadraticIn: quadraticIn,
6335 quadraticOut: quadraticOut,
6336 quadraticInOut: quadraticInOut,
6337 cubicIn: cubicIn,
6338 cubicOut: cubicOut,
6339 cubicInOut: cubicInOut,
6340 quarticIn: quarticIn,
6341 quarticOut: quarticOut,
6342 quarticInOut: quarticInOut,
6343 elasticIn: elasticIn,
6344 elasticOut: elasticOut,
6345 elasticInOut: elasticInOut,
6346 backIn: backIn,
6347 backOut: backOut,
6348 backInOut: backInOut,
6349 bounceIn: bounceIn,
6350 bounceOut: bounceOut,
6351 bounceInOut: bounceInOut,
6352 exponentialIn: exponentialIn,
6353 exponentialOut: exponentialOut,
6354 quinticIn: quinticIn,
6355 quinticOut: quinticOut,
6356 quinticInOut: quinticInOut
6357 });
6358
6359 var objectWithoutPropertiesLoose = createCommonjsModule(function (module) {
6360 function _objectWithoutPropertiesLoose(source, excluded) {
6361 if (source == null) return {};
6362 var target = {};
6363 var sourceKeys = Object.keys(source);
6364 var key, i;
6365
6366 for (i = 0; i < sourceKeys.length; i++) {
6367 key = sourceKeys[i];
6368 if (excluded.indexOf(key) >= 0) continue;
6369 target[key] = source[key];
6370 }
6371
6372 return target;
6373 }
6374
6375 module.exports = _objectWithoutPropertiesLoose, module.exports.__esModule = true, module.exports["default"] = module.exports;
6376 });
6377
6378 var objectWithoutProperties = createCommonjsModule(function (module) {
6379 function _objectWithoutProperties(source, excluded) {
6380 if (source == null) return {};
6381 var target = objectWithoutPropertiesLoose(source, excluded);
6382 var key, i;
6383
6384 if (Object.getOwnPropertySymbols) {
6385 var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
6386
6387 for (i = 0; i < sourceSymbolKeys.length; i++) {
6388 key = sourceSymbolKeys[i];
6389 if (excluded.indexOf(key) >= 0) continue;
6390 if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
6391 target[key] = source[key];
6392 }
6393 }
6394
6395 return target;
6396 }
6397
6398 module.exports = _objectWithoutProperties, module.exports.__esModule = true, module.exports["default"] = module.exports;
6399 });
6400
6401 var _objectWithoutProperties = /*@__PURE__*/getDefaultExportFromCjs(objectWithoutProperties);
6402
6403 var _excluded = ["key", "ref"];
6404 // 实现jsx-classic 入口
6405 function jsx(type, config) {
6406 var _ref = config || {},
6407 key = _ref.key,
6408 ref = _ref.ref,
6409 props = _objectWithoutProperties(_ref, _excluded); // 保持和automatic模式一致
6410
6411
6412 for (var _len = arguments.length, children = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
6413 children[_key - 2] = arguments[_key];
6414 }
6415
6416 if (children.length) {
6417 props.children = children.length === 1 ? children[0] : children;
6418 }
6419
6420 return {
6421 key: key,
6422 ref: ref,
6423 type: type,
6424 props: props,
6425 // 存储一些过程中的cache值
6426 _cache: {}
6427 };
6428 }
6429
6430 var fragment = (function (props) {
6431 return props.children;
6432 });
6433
6434 var ONE_REM;
6435
6436 try {
6437 // xgraph下这段会抛错
6438 ONE_REM = parseInt(document.documentElement.style.fontSize, 10) || 50;
6439 } catch (e) {
6440 ONE_REM = 50;
6441 }
6442
6443 var SCALE = ONE_REM / 100;
6444 /**
6445 * 像素转换
6446 * @param {Number} px - 750视觉稿像素
6447 * @return {Number} 屏幕上实际像素
6448 */
6449
6450 function defaultPx2hd(px) {
6451 if (!px) {
6452 return 0;
6453 }
6454
6455 return Number((px * SCALE).toFixed(1));
6456 }
6457
6458 function parsePadding$1(padding) {
6459 if (isNumber(padding)) {
6460 return [padding, padding, padding, padding];
6461 }
6462
6463 var top = padding[0];
6464 var right = isNumber(padding[1]) ? padding[1] : padding[0];
6465 var bottom = isNumber(padding[2]) ? padding[2] : top;
6466 var left = isNumber(padding[3]) ? padding[3] : right;
6467 return [top, right, bottom, left];
6468 }
6469
6470 function batch2hd(px2hd) {
6471 var batchPx2hd = function batchPx2hd(value) {
6472 // 处理带px的数据
6473 if (isString(value) && /^-?\d+px$/.test(value)) {
6474 var num = value.substr(0, value.length - 2);
6475 return px2hd(Number(num));
6476 }
6477
6478 if (isArray(value)) {
6479 return value.map(function (v) {
6480 return batchPx2hd(v);
6481 });
6482 }
6483
6484 if (isPlainObject(value)) {
6485 var result = {};
6486
6487 for (var key in value) {
6488 if (value.hasOwnProperty(key)) {
6489 var rst = batchPx2hd(value[key]);
6490
6491 if (!rst) {
6492 result[key] = rst;
6493 continue;
6494 }
6495
6496 if (key === 'padding' || key === 'margin') {
6497 var paddingArray = parsePadding$1(rst);
6498 result[key] = paddingArray;
6499 result["".concat(key, "Top")] = paddingArray[0];
6500 result["".concat(key, "Right")] = paddingArray[1];
6501 result["".concat(key, "Bottom")] = paddingArray[2];
6502 result["".concat(key, "Left")] = paddingArray[3];
6503 continue;
6504 }
6505
6506 result[key] = rst;
6507 }
6508 }
6509
6510 return result;
6511 } // 默认直接返回
6512
6513
6514 return value;
6515 };
6516
6517 return batchPx2hd;
6518 } // 展开数组
6519
6520
6521 function extendMap(arr, fn) {
6522 if (!arr) {
6523 return arr;
6524 }
6525
6526 if (!isArray(arr)) {
6527 return [fn(arr)];
6528 }
6529
6530 var newArray = [];
6531
6532 for (var i = 0; i < arr.length; i++) {
6533 var element = arr[i];
6534
6535 if (isArray(element)) {
6536 newArray = newArray.concat(extendMap(element, fn));
6537 } else if (element) {
6538 newArray.push(fn(element));
6539 }
6540 }
6541
6542 return newArray;
6543 }
6544
6545 function toTimeStamp(value) {
6546 if (isString(value)) {
6547 if (value.indexOf('T') > 0) {
6548 value = new Date(value).getTime();
6549 } else {
6550 // new Date('2010/01/10') 和 new Date('2010-01-10') 的差别在于:
6551 // 如果仅有年月日时,前者是带有时区的: Fri Jan 10 2020 02:40:13 GMT+0800 (中国标准时间)
6552 // 后者会格式化成 Sun Jan 10 2010 08:00:00 GMT+0800 (中国标准时间)
6553 value = new Date(value.replace(/-/gi, '/')).getTime();
6554 }
6555 }
6556
6557 if (isDate(value)) {
6558 value = value.getTime();
6559 }
6560
6561 return value;
6562 }
6563
6564 function isInBBox(bbox, point) {
6565 var minX = bbox.minX,
6566 maxX = bbox.maxX,
6567 minY = bbox.minY,
6568 maxY = bbox.maxY;
6569 var x = point.x,
6570 y = point.y;
6571 return minX <= x && maxX >= x && minY <= y && maxY >= y;
6572 }
6573
6574 function getElementsByClassName(className, element) {
6575 if (!element || !className) return [];
6576 var rst = [];
6577
6578 if (element.get('className') === className) {
6579 rst.push(element);
6580 }
6581
6582 var children = element.get('children');
6583
6584 if (children && children.length) {
6585 for (var i = 0; i < children.length; i++) {
6586 var child = children[i];
6587 rst = rst.concat(getElementsByClassName(className, child));
6588 }
6589 }
6590
6591 return rst;
6592 }
6593
6594 var px2hd = batch2hd(defaultPx2hd);
6595
6596 /* eslint-disable */
6597 // @ts-nocheck
6598 // from css-layout
6599 var CSS_UNDEFINED;
6600 var CSS_DIRECTION_INHERIT = 'inherit';
6601 var CSS_DIRECTION_LTR = 'ltr';
6602 var CSS_DIRECTION_RTL = 'rtl';
6603 var CSS_FLEX_DIRECTION_ROW = 'row';
6604 var CSS_FLEX_DIRECTION_ROW_REVERSE = 'row-reverse';
6605 var CSS_FLEX_DIRECTION_COLUMN = 'column';
6606 var CSS_FLEX_DIRECTION_COLUMN_REVERSE = 'column-reverse';
6607 var CSS_JUSTIFY_FLEX_START = 'flex-start';
6608 var CSS_JUSTIFY_CENTER = 'center';
6609 var CSS_JUSTIFY_FLEX_END = 'flex-end';
6610 var CSS_JUSTIFY_SPACE_BETWEEN = 'space-between';
6611 var CSS_JUSTIFY_SPACE_AROUND = 'space-around';
6612 var CSS_ALIGN_FLEX_START = 'flex-start';
6613 var CSS_ALIGN_CENTER = 'center';
6614 var CSS_ALIGN_FLEX_END = 'flex-end';
6615 var CSS_ALIGN_STRETCH = 'stretch';
6616 var CSS_POSITION_RELATIVE = 'relative';
6617 var CSS_POSITION_ABSOLUTE = 'absolute';
6618 var leading = {
6619 row: 'left',
6620 'row-reverse': 'right',
6621 column: 'top',
6622 'column-reverse': 'bottom'
6623 };
6624 var trailing = {
6625 row: 'right',
6626 'row-reverse': 'left',
6627 column: 'bottom',
6628 'column-reverse': 'top'
6629 };
6630 var pos = {
6631 row: 'left',
6632 'row-reverse': 'right',
6633 column: 'top',
6634 'column-reverse': 'bottom'
6635 };
6636 var dim = {
6637 row: 'width',
6638 'row-reverse': 'width',
6639 column: 'height',
6640 'column-reverse': 'height'
6641 }; // When transpiled to Java / C the node type has layout, children and style
6642 // properties. For the JavaScript version this function adds these properties
6643 // if they don't already exist.
6644
6645 function fillNodes(node) {
6646 if (!node.layout || node.isDirty) {
6647 node.layout = {
6648 width: undefined,
6649 height: undefined,
6650 top: 0,
6651 left: 0,
6652 right: 0,
6653 bottom: 0
6654 };
6655 }
6656
6657 if (!node.style) {
6658 node.style = {};
6659 }
6660
6661 if (!node.children) {
6662 node.children = [];
6663 }
6664
6665 node.children.forEach(fillNodes);
6666 return node;
6667 }
6668
6669 function isUndefined$1(value) {
6670 return value === undefined;
6671 }
6672
6673 function isRowDirection(flexDirection) {
6674 return flexDirection === CSS_FLEX_DIRECTION_ROW || flexDirection === CSS_FLEX_DIRECTION_ROW_REVERSE;
6675 }
6676
6677 function isColumnDirection(flexDirection) {
6678 return flexDirection === CSS_FLEX_DIRECTION_COLUMN || flexDirection === CSS_FLEX_DIRECTION_COLUMN_REVERSE;
6679 }
6680
6681 function getLeadingMargin(node, axis) {
6682 if (node.style.marginStart !== undefined && isRowDirection(axis)) {
6683 return node.style.marginStart;
6684 }
6685
6686 var value = null;
6687
6688 switch (axis) {
6689 case 'row':
6690 value = node.style.marginLeft;
6691 break;
6692
6693 case 'row-reverse':
6694 value = node.style.marginRight;
6695 break;
6696
6697 case 'column':
6698 value = node.style.marginTop;
6699 break;
6700
6701 case 'column-reverse':
6702 value = node.style.marginBottom;
6703 break;
6704 }
6705
6706 if (value !== undefined) {
6707 return value;
6708 }
6709
6710 if (node.style.margin !== undefined) {
6711 return node.style.margin;
6712 }
6713
6714 return 0;
6715 }
6716
6717 function getTrailingMargin(node, axis) {
6718 if (node.style.marginEnd !== undefined && isRowDirection(axis)) {
6719 return node.style.marginEnd;
6720 }
6721
6722 var value = null;
6723
6724 switch (axis) {
6725 case 'row':
6726 value = node.style.marginRight;
6727 break;
6728
6729 case 'row-reverse':
6730 value = node.style.marginLeft;
6731 break;
6732
6733 case 'column':
6734 value = node.style.marginBottom;
6735 break;
6736
6737 case 'column-reverse':
6738 value = node.style.marginTop;
6739 break;
6740 }
6741
6742 if (value != null) {
6743 return value;
6744 }
6745
6746 if (node.style.margin !== undefined) {
6747 return node.style.margin;
6748 }
6749
6750 return 0;
6751 }
6752
6753 function getLeadingPadding(node, axis) {
6754 if (node.style.paddingStart !== undefined && node.style.paddingStart >= 0 && isRowDirection(axis)) {
6755 return node.style.paddingStart;
6756 }
6757
6758 var value = null;
6759
6760 switch (axis) {
6761 case 'row':
6762 value = node.style.paddingLeft;
6763 break;
6764
6765 case 'row-reverse':
6766 value = node.style.paddingRight;
6767 break;
6768
6769 case 'column':
6770 value = node.style.paddingTop;
6771 break;
6772
6773 case 'column-reverse':
6774 value = node.style.paddingBottom;
6775 break;
6776 }
6777
6778 if (value != null && value >= 0) {
6779 return value;
6780 }
6781
6782 if (node.style.padding !== undefined && node.style.padding >= 0) {
6783 return node.style.padding;
6784 }
6785
6786 return 0;
6787 }
6788
6789 function getTrailingPadding(node, axis) {
6790 if (node.style.paddingEnd !== undefined && node.style.paddingEnd >= 0 && isRowDirection(axis)) {
6791 return node.style.paddingEnd;
6792 }
6793
6794 var value = null;
6795
6796 switch (axis) {
6797 case 'row':
6798 value = node.style.paddingRight;
6799 break;
6800
6801 case 'row-reverse':
6802 value = node.style.paddingLeft;
6803 break;
6804
6805 case 'column':
6806 value = node.style.paddingBottom;
6807 break;
6808
6809 case 'column-reverse':
6810 value = node.style.paddingTop;
6811 break;
6812 }
6813
6814 if (value != null && value >= 0) {
6815 return value;
6816 }
6817
6818 if (node.style.padding !== undefined && node.style.padding >= 0) {
6819 return node.style.padding;
6820 }
6821
6822 return 0;
6823 }
6824
6825 function getLeadingBorder(node, axis) {
6826 if (node.style.borderStartWidth !== undefined && node.style.borderStartWidth >= 0 && isRowDirection(axis)) {
6827 return node.style.borderStartWidth;
6828 }
6829
6830 var value = null;
6831
6832 switch (axis) {
6833 case 'row':
6834 value = node.style.borderLeftWidth;
6835 break;
6836
6837 case 'row-reverse':
6838 value = node.style.borderRightWidth;
6839 break;
6840
6841 case 'column':
6842 value = node.style.borderTopWidth;
6843 break;
6844
6845 case 'column-reverse':
6846 value = node.style.borderBottomWidth;
6847 break;
6848 }
6849
6850 if (value != null && value >= 0) {
6851 return value;
6852 }
6853
6854 if (node.style.borderWidth !== undefined && node.style.borderWidth >= 0) {
6855 return node.style.borderWidth;
6856 }
6857
6858 return 0;
6859 }
6860
6861 function getTrailingBorder(node, axis) {
6862 if (node.style.borderEndWidth !== undefined && node.style.borderEndWidth >= 0 && isRowDirection(axis)) {
6863 return node.style.borderEndWidth;
6864 }
6865
6866 var value = null;
6867
6868 switch (axis) {
6869 case 'row':
6870 value = node.style.borderRightWidth;
6871 break;
6872
6873 case 'row-reverse':
6874 value = node.style.borderLeftWidth;
6875 break;
6876
6877 case 'column':
6878 value = node.style.borderBottomWidth;
6879 break;
6880
6881 case 'column-reverse':
6882 value = node.style.borderTopWidth;
6883 break;
6884 }
6885
6886 if (value != null && value >= 0) {
6887 return value;
6888 }
6889
6890 if (node.style.borderWidth !== undefined && node.style.borderWidth >= 0) {
6891 return node.style.borderWidth;
6892 }
6893
6894 return 0;
6895 }
6896
6897 function getLeadingPaddingAndBorder(node, axis) {
6898 return getLeadingPadding(node, axis) + getLeadingBorder(node, axis);
6899 }
6900
6901 function getTrailingPaddingAndBorder(node, axis) {
6902 return getTrailingPadding(node, axis) + getTrailingBorder(node, axis);
6903 }
6904
6905 function getBorderAxis(node, axis) {
6906 return getLeadingBorder(node, axis) + getTrailingBorder(node, axis);
6907 }
6908
6909 function getMarginAxis(node, axis) {
6910 return getLeadingMargin(node, axis) + getTrailingMargin(node, axis);
6911 }
6912
6913 function getPaddingAndBorderAxis(node, axis) {
6914 return getLeadingPaddingAndBorder(node, axis) + getTrailingPaddingAndBorder(node, axis);
6915 }
6916
6917 function getJustifyContent(node) {
6918 if (node.style.justifyContent) {
6919 return node.style.justifyContent;
6920 }
6921
6922 return 'flex-start';
6923 }
6924
6925 function getAlignContent(node) {
6926 if (node.style.alignContent) {
6927 return node.style.alignContent;
6928 }
6929
6930 return 'flex-start';
6931 }
6932
6933 function getAlignItem(node, child) {
6934 if (child.style.alignSelf) {
6935 return child.style.alignSelf;
6936 }
6937
6938 if (node.style.alignItems) {
6939 return node.style.alignItems;
6940 }
6941
6942 return 'stretch';
6943 }
6944
6945 function resolveAxis(axis, direction) {
6946 if (direction === CSS_DIRECTION_RTL) {
6947 if (axis === CSS_FLEX_DIRECTION_ROW) {
6948 return CSS_FLEX_DIRECTION_ROW_REVERSE;
6949 } else if (axis === CSS_FLEX_DIRECTION_ROW_REVERSE) {
6950 return CSS_FLEX_DIRECTION_ROW;
6951 }
6952 }
6953
6954 return axis;
6955 }
6956
6957 function resolveDirection(node, parentDirection) {
6958 var direction;
6959
6960 if (node.style.direction) {
6961 direction = node.style.direction;
6962 } else {
6963 direction = CSS_DIRECTION_INHERIT;
6964 }
6965
6966 if (direction === CSS_DIRECTION_INHERIT) {
6967 direction = parentDirection === undefined ? CSS_DIRECTION_LTR : parentDirection;
6968 }
6969
6970 return direction;
6971 }
6972
6973 function getFlexDirection(node) {
6974 if (node.style.flexDirection) {
6975 return node.style.flexDirection;
6976 }
6977
6978 return CSS_FLEX_DIRECTION_COLUMN;
6979 }
6980
6981 function getCrossFlexDirection(flexDirection, direction) {
6982 if (isColumnDirection(flexDirection)) {
6983 return resolveAxis(CSS_FLEX_DIRECTION_ROW, direction);
6984 } else {
6985 return CSS_FLEX_DIRECTION_COLUMN;
6986 }
6987 }
6988
6989 function getPositionType(node) {
6990 if (node.style.position) {
6991 return node.style.position;
6992 }
6993
6994 return 'relative';
6995 }
6996
6997 function isFlex(node) {
6998 return getPositionType(node) === CSS_POSITION_RELATIVE && node.style.flex > 0;
6999 }
7000
7001 function isFlexWrap(node) {
7002 return node.style.flexWrap === 'wrap';
7003 }
7004
7005 function getDimWithMargin(node, axis) {
7006 return node.layout[dim[axis]] + getMarginAxis(node, axis);
7007 }
7008
7009 function isDimDefined(node, axis) {
7010 return node.style[dim[axis]] !== undefined && node.style[dim[axis]] >= 0;
7011 }
7012
7013 function isPosDefined(node, pos) {
7014 return node.style[pos] !== undefined;
7015 }
7016
7017 function isMeasureDefined(node) {
7018 return node.style.measure !== undefined;
7019 }
7020
7021 function getPosition(node, pos) {
7022 if (node.style[pos] !== undefined) {
7023 return node.style[pos];
7024 }
7025
7026 return 0;
7027 }
7028
7029 function boundAxis(node, axis, value) {
7030 var min = {
7031 row: node.style.minWidth,
7032 'row-reverse': node.style.minWidth,
7033 column: node.style.minHeight,
7034 'column-reverse': node.style.minHeight
7035 }[axis];
7036 var max = {
7037 row: node.style.maxWidth,
7038 'row-reverse': node.style.maxWidth,
7039 column: node.style.maxHeight,
7040 'column-reverse': node.style.maxHeight
7041 }[axis];
7042 var boundValue = value;
7043
7044 if (max !== undefined && max >= 0 && boundValue > max) {
7045 boundValue = max;
7046 }
7047
7048 if (min !== undefined && min >= 0 && boundValue < min) {
7049 boundValue = min;
7050 }
7051
7052 return boundValue;
7053 }
7054
7055 function fmaxf(a, b) {
7056 if (a > b) {
7057 return a;
7058 }
7059
7060 return b;
7061 } // When the user specifically sets a value for width or height
7062
7063
7064 function setDimensionFromStyle(node, axis) {
7065 // The parent already computed us a width or height. We just skip it
7066 if (node.layout[dim[axis]] !== undefined) {
7067 return;
7068 } // We only run if there's a width or height defined
7069
7070
7071 if (!isDimDefined(node, axis)) {
7072 return;
7073 } // The dimensions can never be smaller than the padding and border
7074
7075
7076 node.layout[dim[axis]] = fmaxf(boundAxis(node, axis, node.style[dim[axis]]), getPaddingAndBorderAxis(node, axis));
7077 }
7078
7079 function setTrailingPosition(node, child, axis) {
7080 child.layout[trailing[axis]] = node.layout[dim[axis]] - child.layout[dim[axis]] - child.layout[pos[axis]];
7081 } // If both left and right are defined, then use left. Otherwise return
7082 // +left or -right depending on which is defined.
7083
7084
7085 function getRelativePosition$1(node, axis) {
7086 if (node.style[leading[axis]] !== undefined) {
7087 return getPosition(node, leading[axis]);
7088 }
7089
7090 return -getPosition(node, trailing[axis]);
7091 }
7092
7093 function layoutNodeImpl(node, parentMaxWidth,
7094 /*css_direction_t*/
7095 parentDirection) {
7096 var
7097 /*css_direction_t*/
7098 direction = resolveDirection(node, parentDirection);
7099 var
7100 /*(c)!css_flex_direction_t*/
7101
7102 /*(java)!int*/
7103 mainAxis = resolveAxis(getFlexDirection(node), direction);
7104 var
7105 /*(c)!css_flex_direction_t*/
7106
7107 /*(java)!int*/
7108 crossAxis = getCrossFlexDirection(mainAxis, direction);
7109 var
7110 /*(c)!css_flex_direction_t*/
7111
7112 /*(java)!int*/
7113 resolvedRowAxis = resolveAxis(CSS_FLEX_DIRECTION_ROW, direction); // Handle width and height style attributes
7114
7115 setDimensionFromStyle(node, mainAxis);
7116 setDimensionFromStyle(node, crossAxis); // Set the resolved resolution in the node's layout
7117
7118 node.layout.direction = direction; // The position is set by the parent, but we need to complete it with a
7119 // delta composed of the margin and left/top/right/bottom
7120
7121 node.layout[leading[mainAxis]] += getLeadingMargin(node, mainAxis) + getRelativePosition$1(node, mainAxis);
7122 node.layout[trailing[mainAxis]] += getTrailingMargin(node, mainAxis) + getRelativePosition$1(node, mainAxis);
7123 node.layout[leading[crossAxis]] += getLeadingMargin(node, crossAxis) + getRelativePosition$1(node, crossAxis);
7124 node.layout[trailing[crossAxis]] += getTrailingMargin(node, crossAxis) + getRelativePosition$1(node, crossAxis); // Inline immutable values from the target node to avoid excessive method
7125 // invocations during the layout calculation.
7126
7127 var
7128 /*int*/
7129 childCount = node.children.length;
7130 var
7131 /*float*/
7132 paddingAndBorderAxisResolvedRow = getPaddingAndBorderAxis(node, resolvedRowAxis);
7133
7134 if (isMeasureDefined(node)) {
7135 var
7136 /*bool*/
7137 isResolvedRowDimDefined = !isUndefined$1(node.layout[dim[resolvedRowAxis]]);
7138 var
7139 /*float*/
7140 width = CSS_UNDEFINED;
7141
7142 if (isDimDefined(node, resolvedRowAxis)) {
7143 width = node.style.width;
7144 } else if (isResolvedRowDimDefined) {
7145 width = node.layout[dim[resolvedRowAxis]];
7146 } else {
7147 width = parentMaxWidth - getMarginAxis(node, resolvedRowAxis);
7148 }
7149
7150 width -= paddingAndBorderAxisResolvedRow; // We only need to give a dimension for the text if we haven't got any
7151 // for it computed yet. It can either be from the style attribute or because
7152 // the element is flexible.
7153
7154 var
7155 /*bool*/
7156 isRowUndefined = !isDimDefined(node, resolvedRowAxis) && !isResolvedRowDimDefined;
7157 var
7158 /*bool*/
7159 isColumnUndefined = !isDimDefined(node, CSS_FLEX_DIRECTION_COLUMN) && isUndefined$1(node.layout[dim[CSS_FLEX_DIRECTION_COLUMN]]); // Let's not measure the text if we already know both dimensions
7160
7161 if (isRowUndefined || isColumnUndefined) {
7162 var
7163 /*css_dim_t*/
7164 measureDim = node.style.measure(
7165 /*(c)!node->context,*/
7166
7167 /*(java)!layoutContext.measureOutput,*/
7168 width);
7169
7170 if (isRowUndefined) {
7171 node.layout.width = measureDim.width + paddingAndBorderAxisResolvedRow;
7172 }
7173
7174 if (isColumnUndefined) {
7175 node.layout.height = measureDim.height + getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_COLUMN);
7176 }
7177 }
7178
7179 if (childCount === 0) {
7180 return;
7181 }
7182 }
7183
7184 var
7185 /*bool*/
7186 isNodeFlexWrap = isFlexWrap(node);
7187 var
7188 /*css_justify_t*/
7189 justifyContent = getJustifyContent(node);
7190 var
7191 /*float*/
7192 leadingPaddingAndBorderMain = getLeadingPaddingAndBorder(node, mainAxis);
7193 var
7194 /*float*/
7195 leadingPaddingAndBorderCross = getLeadingPaddingAndBorder(node, crossAxis);
7196 var
7197 /*float*/
7198 paddingAndBorderAxisMain = getPaddingAndBorderAxis(node, mainAxis);
7199 var
7200 /*float*/
7201 paddingAndBorderAxisCross = getPaddingAndBorderAxis(node, crossAxis);
7202 var
7203 /*bool*/
7204 isMainDimDefined = !isUndefined$1(node.layout[dim[mainAxis]]);
7205 var
7206 /*bool*/
7207 isCrossDimDefined = !isUndefined$1(node.layout[dim[crossAxis]]);
7208 var
7209 /*bool*/
7210 isMainRowDirection = isRowDirection(mainAxis);
7211 var
7212 /*int*/
7213 i;
7214 var
7215 /*int*/
7216 ii;
7217 var
7218 /*css_node_t**/
7219 child;
7220 var
7221 /*(c)!css_flex_direction_t*/
7222
7223 /*(java)!int*/
7224 axis;
7225 var
7226 /*css_node_t**/
7227 firstAbsoluteChild = null;
7228 var
7229 /*css_node_t**/
7230 currentAbsoluteChild = null;
7231 var
7232 /*float*/
7233 definedMainDim = CSS_UNDEFINED;
7234
7235 if (isMainDimDefined) {
7236 definedMainDim = node.layout[dim[mainAxis]] - paddingAndBorderAxisMain;
7237 } // We want to execute the next two loops one per line with flex-wrap
7238
7239
7240 var
7241 /*int*/
7242 startLine = 0;
7243 var
7244 /*int*/
7245 endLine = 0; // var/*int*/ nextOffset = 0;
7246
7247 var
7248 /*int*/
7249 alreadyComputedNextLayout = 0; // We aggregate the total dimensions of the container in those two variables
7250
7251 var
7252 /*float*/
7253 linesCrossDim = 0;
7254 var
7255 /*float*/
7256 linesMainDim = 0;
7257 var
7258 /*int*/
7259 linesCount = 0;
7260
7261 while (endLine < childCount) {
7262 // <Loop A> Layout non flexible children and count children by type
7263 // mainContentDim is accumulation of the dimensions and margin of all the
7264 // non flexible children. This will be used in order to either set the
7265 // dimensions of the node if none already exist, or to compute the
7266 // remaining space left for the flexible children.
7267 var
7268 /*float*/
7269 mainContentDim = 0; // There are three kind of children, non flexible, flexible and absolute.
7270 // We need to know how many there are in order to distribute the space.
7271
7272 var
7273 /*int*/
7274 flexibleChildrenCount = 0;
7275 var
7276 /*float*/
7277 totalFlexible = 0;
7278 var
7279 /*int*/
7280 nonFlexibleChildrenCount = 0; // Use the line loop to position children in the main axis for as long
7281 // as they are using a simple stacking behaviour. Children that are
7282 // immediately stacked in the initial loop will not be touched again
7283 // in <Loop C>.
7284
7285 var
7286 /*bool*/
7287 isSimpleStackMain = isMainDimDefined && justifyContent === CSS_JUSTIFY_FLEX_START || !isMainDimDefined && justifyContent !== CSS_JUSTIFY_CENTER;
7288 var
7289 /*int*/
7290 firstComplexMain = isSimpleStackMain ? childCount : startLine; // Use the initial line loop to position children in the cross axis for
7291 // as long as they are relatively positioned with alignment STRETCH or
7292 // FLEX_START. Children that are immediately stacked in the initial loop
7293 // will not be touched again in <Loop D>.
7294
7295 var
7296 /*bool*/
7297 isSimpleStackCross = true;
7298 var
7299 /*int*/
7300 firstComplexCross = childCount;
7301 var
7302 /*css_node_t**/
7303 firstFlexChild = null;
7304 var
7305 /*css_node_t**/
7306 currentFlexChild = null;
7307 var
7308 /*float*/
7309 mainDim = leadingPaddingAndBorderMain;
7310 var
7311 /*float*/
7312 crossDim = 0;
7313 var
7314 /*float*/
7315 maxWidth;
7316
7317 for (i = startLine; i < childCount; ++i) {
7318 child = node.children[i];
7319 child.lineIndex = linesCount;
7320 child.nextAbsoluteChild = null;
7321 child.nextFlexChild = null;
7322 var
7323 /*css_align_t*/
7324 alignItem = getAlignItem(node, child); // Pre-fill cross axis dimensions when the child is using stretch before
7325 // we call the recursive layout pass
7326
7327 if (alignItem === CSS_ALIGN_STRETCH && getPositionType(child) === CSS_POSITION_RELATIVE && isCrossDimDefined && !isDimDefined(child, crossAxis)) {
7328 child.layout[dim[crossAxis]] = fmaxf(boundAxis(child, crossAxis, node.layout[dim[crossAxis]] - paddingAndBorderAxisCross - getMarginAxis(child, crossAxis)), // You never want to go smaller than padding
7329 getPaddingAndBorderAxis(child, crossAxis));
7330 } else if (getPositionType(child) === CSS_POSITION_ABSOLUTE) {
7331 // Store a private linked list of absolutely positioned children
7332 // so that we can efficiently traverse them later.
7333 if (firstAbsoluteChild === null) {
7334 firstAbsoluteChild = child;
7335 }
7336
7337 if (currentAbsoluteChild !== null) {
7338 currentAbsoluteChild.nextAbsoluteChild = child;
7339 }
7340
7341 currentAbsoluteChild = child; // Pre-fill dimensions when using absolute position and both offsets for the axis are defined (either both
7342 // left and right or top and bottom).
7343
7344 for (ii = 0; ii < 2; ii++) {
7345 axis = ii !== 0 ? CSS_FLEX_DIRECTION_ROW : CSS_FLEX_DIRECTION_COLUMN;
7346
7347 if (!isUndefined$1(node.layout[dim[axis]]) && !isDimDefined(child, axis) && isPosDefined(child, leading[axis]) && isPosDefined(child, trailing[axis])) {
7348 child.layout[dim[axis]] = fmaxf(boundAxis(child, axis, node.layout[dim[axis]] - getPaddingAndBorderAxis(node, axis) - getMarginAxis(child, axis) - getPosition(child, leading[axis]) - getPosition(child, trailing[axis])), // You never want to go smaller than padding
7349 getPaddingAndBorderAxis(child, axis));
7350 }
7351 }
7352 }
7353
7354 var
7355 /*float*/
7356 nextContentDim = 0; // It only makes sense to consider a child flexible if we have a computed
7357 // dimension for the node.
7358
7359 if (isMainDimDefined && isFlex(child)) {
7360 flexibleChildrenCount++;
7361 totalFlexible += child.style.flex; // Store a private linked list of flexible children so that we can
7362 // efficiently traverse them later.
7363
7364 if (firstFlexChild === null) {
7365 firstFlexChild = child;
7366 }
7367
7368 if (currentFlexChild !== null) {
7369 currentFlexChild.nextFlexChild = child;
7370 }
7371
7372 currentFlexChild = child; // Even if we don't know its exact size yet, we already know the padding,
7373 // border and margin. We'll use this partial information, which represents
7374 // the smallest possible size for the child, to compute the remaining
7375 // available space.
7376
7377 nextContentDim = getPaddingAndBorderAxis(child, mainAxis) + getMarginAxis(child, mainAxis);
7378 } else {
7379 maxWidth = CSS_UNDEFINED;
7380
7381 if (!isMainRowDirection) {
7382 if (isDimDefined(node, resolvedRowAxis)) {
7383 maxWidth = node.layout[dim[resolvedRowAxis]] - paddingAndBorderAxisResolvedRow;
7384 } else {
7385 maxWidth = parentMaxWidth - getMarginAxis(node, resolvedRowAxis) - paddingAndBorderAxisResolvedRow;
7386 }
7387 } // This is the main recursive call. We layout non flexible children.
7388
7389
7390 if (alreadyComputedNextLayout === 0) {
7391 layoutNode(
7392 /*(java)!layoutContext, */
7393 child, maxWidth, direction);
7394 } // Absolute positioned elements do not take part of the layout, so we
7395 // don't use them to compute mainContentDim
7396
7397
7398 if (getPositionType(child) === CSS_POSITION_RELATIVE) {
7399 nonFlexibleChildrenCount++; // At this point we know the final size and margin of the element.
7400
7401 nextContentDim = getDimWithMargin(child, mainAxis);
7402 }
7403 } // The element we are about to add would make us go to the next line
7404
7405
7406 if (isNodeFlexWrap && isMainDimDefined && mainContentDim + nextContentDim > definedMainDim && // If there's only one element, then it's bigger than the content
7407 // and needs its own line
7408 i !== startLine) {
7409 nonFlexibleChildrenCount--;
7410 alreadyComputedNextLayout = 1;
7411 break;
7412 } // Disable simple stacking in the main axis for the current line as
7413 // we found a non-trivial child. The remaining children will be laid out
7414 // in <Loop C>.
7415
7416
7417 if (isSimpleStackMain && (getPositionType(child) !== CSS_POSITION_RELATIVE || isFlex(child))) {
7418 isSimpleStackMain = false;
7419 firstComplexMain = i;
7420 } // Disable simple stacking in the cross axis for the current line as
7421 // we found a non-trivial child. The remaining children will be laid out
7422 // in <Loop D>.
7423
7424
7425 if (isSimpleStackCross && (getPositionType(child) !== CSS_POSITION_RELATIVE || alignItem !== CSS_ALIGN_STRETCH && alignItem !== CSS_ALIGN_FLEX_START || isUndefined$1(child.layout[dim[crossAxis]]))) {
7426 isSimpleStackCross = false;
7427 firstComplexCross = i;
7428 }
7429
7430 if (isSimpleStackMain) {
7431 child.layout[pos[mainAxis]] += mainDim;
7432
7433 if (isMainDimDefined) {
7434 setTrailingPosition(node, child, mainAxis);
7435 }
7436
7437 mainDim += getDimWithMargin(child, mainAxis);
7438 crossDim = fmaxf(crossDim, boundAxis(child, crossAxis, getDimWithMargin(child, crossAxis)));
7439 }
7440
7441 if (isSimpleStackCross) {
7442 child.layout[pos[crossAxis]] += linesCrossDim + leadingPaddingAndBorderCross;
7443
7444 if (isCrossDimDefined) {
7445 setTrailingPosition(node, child, crossAxis);
7446 }
7447 }
7448
7449 alreadyComputedNextLayout = 0;
7450 mainContentDim += nextContentDim;
7451 endLine = i + 1;
7452 } // <Loop B> Layout flexible children and allocate empty space
7453 // In order to position the elements in the main axis, we have two
7454 // controls. The space between the beginning and the first element
7455 // and the space between each two elements.
7456
7457
7458 var
7459 /*float*/
7460 leadingMainDim = 0;
7461 var
7462 /*float*/
7463 betweenMainDim = 0; // The remaining available space that needs to be allocated
7464
7465 var
7466 /*float*/
7467 remainingMainDim = 0;
7468
7469 if (isMainDimDefined) {
7470 remainingMainDim = definedMainDim - mainContentDim;
7471 } else {
7472 remainingMainDim = fmaxf(mainContentDim, 0) - mainContentDim;
7473 } // If there are flexible children in the mix, they are going to fill the
7474 // remaining space
7475
7476
7477 if (flexibleChildrenCount !== 0) {
7478 var
7479 /*float*/
7480 flexibleMainDim = remainingMainDim / totalFlexible;
7481 var
7482 /*float*/
7483 baseMainDim;
7484 var
7485 /*float*/
7486 boundMainDim; // If the flex share of remaining space doesn't meet min/max bounds,
7487 // remove this child from flex calculations.
7488
7489 currentFlexChild = firstFlexChild;
7490
7491 while (currentFlexChild !== null) {
7492 baseMainDim = flexibleMainDim * currentFlexChild.style.flex + getPaddingAndBorderAxis(currentFlexChild, mainAxis);
7493 boundMainDim = boundAxis(currentFlexChild, mainAxis, baseMainDim);
7494
7495 if (baseMainDim !== boundMainDim) {
7496 remainingMainDim -= boundMainDim;
7497 totalFlexible -= currentFlexChild.style.flex;
7498 }
7499
7500 currentFlexChild = currentFlexChild.nextFlexChild;
7501 }
7502
7503 flexibleMainDim = remainingMainDim / totalFlexible; // The non flexible children can overflow the container, in this case
7504 // we should just assume that there is no space available.
7505
7506 if (flexibleMainDim < 0) {
7507 flexibleMainDim = 0;
7508 }
7509
7510 currentFlexChild = firstFlexChild;
7511
7512 while (currentFlexChild !== null) {
7513 // At this point we know the final size of the element in the main
7514 // dimension
7515 currentFlexChild.layout[dim[mainAxis]] = boundAxis(currentFlexChild, mainAxis, flexibleMainDim * currentFlexChild.style.flex + getPaddingAndBorderAxis(currentFlexChild, mainAxis));
7516 maxWidth = CSS_UNDEFINED;
7517
7518 if (isDimDefined(node, resolvedRowAxis)) {
7519 maxWidth = node.layout[dim[resolvedRowAxis]] - paddingAndBorderAxisResolvedRow;
7520 } else if (!isMainRowDirection) {
7521 maxWidth = parentMaxWidth - getMarginAxis(node, resolvedRowAxis) - paddingAndBorderAxisResolvedRow;
7522 } // And we recursively call the layout algorithm for this child
7523
7524
7525 layoutNode(
7526 /*(java)!layoutContext, */
7527 currentFlexChild, maxWidth, direction);
7528 child = currentFlexChild;
7529 currentFlexChild = currentFlexChild.nextFlexChild;
7530 child.nextFlexChild = null;
7531 } // We use justifyContent to figure out how to allocate the remaining
7532 // space available
7533
7534 } else if (justifyContent !== CSS_JUSTIFY_FLEX_START) {
7535 if (justifyContent === CSS_JUSTIFY_CENTER) {
7536 leadingMainDim = remainingMainDim / 2;
7537 } else if (justifyContent === CSS_JUSTIFY_FLEX_END) {
7538 leadingMainDim = remainingMainDim;
7539 } else if (justifyContent === CSS_JUSTIFY_SPACE_BETWEEN) {
7540 remainingMainDim = fmaxf(remainingMainDim, 0);
7541
7542 if (flexibleChildrenCount + nonFlexibleChildrenCount - 1 !== 0) {
7543 betweenMainDim = remainingMainDim / (flexibleChildrenCount + nonFlexibleChildrenCount - 1);
7544 } else {
7545 betweenMainDim = 0;
7546 }
7547 } else if (justifyContent === CSS_JUSTIFY_SPACE_AROUND) {
7548 // Space on the edges is half of the space between elements
7549 betweenMainDim = remainingMainDim / (flexibleChildrenCount + nonFlexibleChildrenCount);
7550 leadingMainDim = betweenMainDim / 2;
7551 }
7552 } // <Loop C> Position elements in the main axis and compute dimensions
7553 // At this point, all the children have their dimensions set. We need to
7554 // find their position. In order to do that, we accumulate data in
7555 // variables that are also useful to compute the total dimensions of the
7556 // container!
7557
7558
7559 mainDim += leadingMainDim;
7560
7561 for (i = firstComplexMain; i < endLine; ++i) {
7562 child = node.children[i];
7563
7564 if (getPositionType(child) === CSS_POSITION_ABSOLUTE && isPosDefined(child, leading[mainAxis])) {
7565 // In case the child is position absolute and has left/top being
7566 // defined, we override the position to whatever the user said
7567 // (and margin/border).
7568 child.layout[pos[mainAxis]] = getPosition(child, leading[mainAxis]) + getLeadingBorder(node, mainAxis) + getLeadingMargin(child, mainAxis);
7569 } else {
7570 // If the child is position absolute (without top/left) or relative,
7571 // we put it at the current accumulated offset.
7572 child.layout[pos[mainAxis]] += mainDim; // Define the trailing position accordingly.
7573
7574 if (isMainDimDefined) {
7575 setTrailingPosition(node, child, mainAxis);
7576 } // Now that we placed the element, we need to update the variables
7577 // We only need to do that for relative elements. Absolute elements
7578 // do not take part in that phase.
7579
7580
7581 if (getPositionType(child) === CSS_POSITION_RELATIVE) {
7582 // The main dimension is the sum of all the elements dimension plus
7583 // the spacing.
7584 mainDim += betweenMainDim + getDimWithMargin(child, mainAxis); // The cross dimension is the max of the elements dimension since there
7585 // can only be one element in that cross dimension.
7586
7587 crossDim = fmaxf(crossDim, boundAxis(child, crossAxis, getDimWithMargin(child, crossAxis)));
7588 }
7589 }
7590 }
7591
7592 var
7593 /*float*/
7594 containerCrossAxis = node.layout[dim[crossAxis]];
7595
7596 if (!isCrossDimDefined) {
7597 containerCrossAxis = fmaxf( // For the cross dim, we add both sides at the end because the value
7598 // is aggregate via a max function. Intermediate negative values
7599 // can mess this computation otherwise
7600 boundAxis(node, crossAxis, crossDim + paddingAndBorderAxisCross), paddingAndBorderAxisCross);
7601 } // <Loop D> Position elements in the cross axis
7602
7603
7604 for (i = firstComplexCross; i < endLine; ++i) {
7605 child = node.children[i];
7606
7607 if (getPositionType(child) === CSS_POSITION_ABSOLUTE && isPosDefined(child, leading[crossAxis])) {
7608 // In case the child is absolutely positionned and has a
7609 // top/left/bottom/right being set, we override all the previously
7610 // computed positions to set it correctly.
7611 child.layout[pos[crossAxis]] = getPosition(child, leading[crossAxis]) + getLeadingBorder(node, crossAxis) + getLeadingMargin(child, crossAxis);
7612 } else {
7613 var
7614 /*float*/
7615 leadingCrossDim = leadingPaddingAndBorderCross; // For a relative children, we're either using alignItems (parent) or
7616 // alignSelf (child) in order to determine the position in the cross axis
7617
7618 if (getPositionType(child) === CSS_POSITION_RELATIVE) {
7619 // This variable is intentionally re-defined as the code is transpiled to a block scope language
7620 var
7621 /*css_align_t*/
7622 alignItem = getAlignItem(node, child);
7623
7624 if (alignItem === CSS_ALIGN_STRETCH) {
7625 // You can only stretch if the dimension has not already been set
7626 // previously.
7627 if (isUndefined$1(child.layout[dim[crossAxis]])) {
7628 child.layout[dim[crossAxis]] = fmaxf(boundAxis(child, crossAxis, containerCrossAxis - paddingAndBorderAxisCross - getMarginAxis(child, crossAxis)), // You never want to go smaller than padding
7629 getPaddingAndBorderAxis(child, crossAxis));
7630 }
7631 } else if (alignItem !== CSS_ALIGN_FLEX_START) {
7632 // The remaining space between the parent dimensions+padding and child
7633 // dimensions+margin.
7634 var
7635 /*float*/
7636 remainingCrossDim = containerCrossAxis - paddingAndBorderAxisCross - getDimWithMargin(child, crossAxis);
7637
7638 if (alignItem === CSS_ALIGN_CENTER) {
7639 leadingCrossDim += remainingCrossDim / 2;
7640 } else {
7641 // CSS_ALIGN_FLEX_END
7642 leadingCrossDim += remainingCrossDim;
7643 }
7644 }
7645 } // And we apply the position
7646
7647
7648 child.layout[pos[crossAxis]] += linesCrossDim + leadingCrossDim; // Define the trailing position accordingly.
7649
7650 if (isCrossDimDefined) {
7651 setTrailingPosition(node, child, crossAxis);
7652 }
7653 }
7654 }
7655
7656 linesCrossDim += crossDim;
7657 linesMainDim = fmaxf(linesMainDim, mainDim);
7658 linesCount += 1;
7659 startLine = endLine;
7660 } // <Loop E>
7661 //
7662 // Note(prenaux): More than one line, we need to layout the crossAxis
7663 // according to alignContent.
7664 //
7665 // Note that we could probably remove <Loop D> and handle the one line case
7666 // here too, but for the moment this is safer since it won't interfere with
7667 // previously working code.
7668 //
7669 // See specs:
7670 // http://www.w3.org/TR/2012/CR-css3-flexbox-20120918/#layout-algorithm
7671 // section 9.4
7672 //
7673
7674
7675 if (linesCount > 1 && isCrossDimDefined) {
7676 var
7677 /*float*/
7678 nodeCrossAxisInnerSize = node.layout[dim[crossAxis]] - paddingAndBorderAxisCross;
7679 var
7680 /*float*/
7681 remainingAlignContentDim = nodeCrossAxisInnerSize - linesCrossDim;
7682 var
7683 /*float*/
7684 crossDimLead = 0;
7685 var
7686 /*float*/
7687 currentLead = leadingPaddingAndBorderCross;
7688 var
7689 /*css_align_t*/
7690 alignContent = getAlignContent(node);
7691
7692 if (alignContent === CSS_ALIGN_FLEX_END) {
7693 currentLead += remainingAlignContentDim;
7694 } else if (alignContent === CSS_ALIGN_CENTER) {
7695 currentLead += remainingAlignContentDim / 2;
7696 } else if (alignContent === CSS_ALIGN_STRETCH) {
7697 if (nodeCrossAxisInnerSize > linesCrossDim) {
7698 crossDimLead = remainingAlignContentDim / linesCount;
7699 }
7700 }
7701
7702 var
7703 /*int*/
7704 endIndex = 0;
7705
7706 for (i = 0; i < linesCount; ++i) {
7707 var
7708 /*int*/
7709 startIndex = endIndex; // compute the line's height and find the endIndex
7710
7711 var
7712 /*float*/
7713 lineHeight = 0;
7714
7715 for (ii = startIndex; ii < childCount; ++ii) {
7716 child = node.children[ii];
7717
7718 if (getPositionType(child) !== CSS_POSITION_RELATIVE) {
7719 continue;
7720 }
7721
7722 if (child.lineIndex !== i) {
7723 break;
7724 }
7725
7726 if (!isUndefined$1(child.layout[dim[crossAxis]])) {
7727 lineHeight = fmaxf(lineHeight, child.layout[dim[crossAxis]] + getMarginAxis(child, crossAxis));
7728 }
7729 }
7730
7731 endIndex = ii;
7732 lineHeight += crossDimLead;
7733
7734 for (ii = startIndex; ii < endIndex; ++ii) {
7735 child = node.children[ii];
7736
7737 if (getPositionType(child) !== CSS_POSITION_RELATIVE) {
7738 continue;
7739 }
7740
7741 var
7742 /*css_align_t*/
7743 alignContentAlignItem = getAlignItem(node, child);
7744
7745 if (alignContentAlignItem === CSS_ALIGN_FLEX_START) {
7746 child.layout[pos[crossAxis]] = currentLead + getLeadingMargin(child, crossAxis);
7747 } else if (alignContentAlignItem === CSS_ALIGN_FLEX_END) {
7748 child.layout[pos[crossAxis]] = currentLead + lineHeight - getTrailingMargin(child, crossAxis) - child.layout[dim[crossAxis]];
7749 } else if (alignContentAlignItem === CSS_ALIGN_CENTER) {
7750 var
7751 /*float*/
7752 childHeight = child.layout[dim[crossAxis]];
7753 child.layout[pos[crossAxis]] = currentLead + (lineHeight - childHeight) / 2;
7754 } else if (alignContentAlignItem === CSS_ALIGN_STRETCH) {
7755 child.layout[pos[crossAxis]] = currentLead + getLeadingMargin(child, crossAxis); // TODO(prenaux): Correctly set the height of items with undefined
7756 // (auto) crossAxis dimension.
7757 }
7758 }
7759
7760 currentLead += lineHeight;
7761 }
7762 }
7763
7764 var
7765 /*bool*/
7766 needsMainTrailingPos = false;
7767 var
7768 /*bool*/
7769 needsCrossTrailingPos = false; // If the user didn't specify a width or height, and it has not been set
7770 // by the container, then we set it via the children.
7771
7772 if (!isMainDimDefined) {
7773 node.layout[dim[mainAxis]] = fmaxf( // We're missing the last padding at this point to get the final
7774 // dimension
7775 boundAxis(node, mainAxis, linesMainDim + getTrailingPaddingAndBorder(node, mainAxis)), // We can never assign a width smaller than the padding and borders
7776 paddingAndBorderAxisMain);
7777
7778 if (mainAxis === CSS_FLEX_DIRECTION_ROW_REVERSE || mainAxis === CSS_FLEX_DIRECTION_COLUMN_REVERSE) {
7779 needsMainTrailingPos = true;
7780 }
7781 }
7782
7783 if (!isCrossDimDefined) {
7784 node.layout[dim[crossAxis]] = fmaxf( // For the cross dim, we add both sides at the end because the value
7785 // is aggregate via a max function. Intermediate negative values
7786 // can mess this computation otherwise
7787 boundAxis(node, crossAxis, linesCrossDim + paddingAndBorderAxisCross), paddingAndBorderAxisCross);
7788
7789 if (crossAxis === CSS_FLEX_DIRECTION_ROW_REVERSE || crossAxis === CSS_FLEX_DIRECTION_COLUMN_REVERSE) {
7790 needsCrossTrailingPos = true;
7791 }
7792 } // <Loop F> Set trailing position if necessary
7793
7794
7795 if (needsMainTrailingPos || needsCrossTrailingPos) {
7796 for (i = 0; i < childCount; ++i) {
7797 child = node.children[i];
7798
7799 if (needsMainTrailingPos) {
7800 setTrailingPosition(node, child, mainAxis);
7801 }
7802
7803 if (needsCrossTrailingPos) {
7804 setTrailingPosition(node, child, crossAxis);
7805 }
7806 }
7807 } // <Loop G> Calculate dimensions for absolutely positioned elements
7808
7809
7810 currentAbsoluteChild = firstAbsoluteChild;
7811
7812 while (currentAbsoluteChild !== null) {
7813 // Pre-fill dimensions when using absolute position and both offsets for
7814 // the axis are defined (either both left and right or top and bottom).
7815 for (ii = 0; ii < 2; ii++) {
7816 axis = ii !== 0 ? CSS_FLEX_DIRECTION_ROW : CSS_FLEX_DIRECTION_COLUMN;
7817
7818 if (!isUndefined$1(node.layout[dim[axis]]) && !isDimDefined(currentAbsoluteChild, axis) && isPosDefined(currentAbsoluteChild, leading[axis]) && isPosDefined(currentAbsoluteChild, trailing[axis])) {
7819 currentAbsoluteChild.layout[dim[axis]] = fmaxf(boundAxis(currentAbsoluteChild, axis, node.layout[dim[axis]] - getBorderAxis(node, axis) - getMarginAxis(currentAbsoluteChild, axis) - getPosition(currentAbsoluteChild, leading[axis]) - getPosition(currentAbsoluteChild, trailing[axis])), // You never want to go smaller than padding
7820 getPaddingAndBorderAxis(currentAbsoluteChild, axis));
7821 }
7822
7823 if (isPosDefined(currentAbsoluteChild, trailing[axis]) && !isPosDefined(currentAbsoluteChild, leading[axis])) {
7824 currentAbsoluteChild.layout[leading[axis]] = node.layout[dim[axis]] - currentAbsoluteChild.layout[dim[axis]] - getPosition(currentAbsoluteChild, trailing[axis]);
7825 }
7826 }
7827
7828 child = currentAbsoluteChild;
7829 currentAbsoluteChild = currentAbsoluteChild.nextAbsoluteChild;
7830 child.nextAbsoluteChild = null;
7831 }
7832 } // 在外层做的margin补丁
7833
7834
7835 function saveMargin(node) {
7836 var style = node.style;
7837 var margin = {};
7838 ['marginTop', 'marginRight', 'marginBottom', 'marginLeft' // 只支持marginLeft
7839 ].forEach(function (key) {
7840 // 只处理百分号
7841 var value = style[key];
7842
7843 if (value && /^-?\d+%$/.test(value)) {
7844 margin[key] = value;
7845 style[key] = 0;
7846 }
7847 });
7848 node.margin = margin;
7849 }
7850
7851 function percent2Num(value) {
7852 var percent = Number(value.substr(0, value.length - 1));
7853 return percent / 100;
7854 }
7855
7856 function layoutMargin(node) {
7857 var margin = node.margin,
7858 layout = node.layout;
7859 Object.keys(margin).forEach(function (key) {
7860 var percent = percent2Num(margin[key]);
7861
7862 if ((key === 'marginLeft' || key === 'marginRight') && layout.width) {
7863 layout.left += layout.width * percent;
7864 } else if ((key === 'marginTop' || key === 'marginBottom') && layout.height) {
7865 layout.top += layout.height * percent;
7866 }
7867 });
7868 }
7869
7870 function layoutNode(node, parentMaxWidth, parentDirection) {
7871 node.shouldUpdate = true; // hack
7872
7873 saveMargin(node);
7874 var direction = node.style.direction || CSS_DIRECTION_LTR;
7875 var skipLayout = !node.isDirty && node.lastLayout && node.lastLayout.requestedHeight === node.layout.height && node.lastLayout.requestedWidth === node.layout.width && node.lastLayout.parentMaxWidth === parentMaxWidth && node.lastLayout.direction === direction;
7876
7877 if (skipLayout) {
7878 node.layout.width = node.lastLayout.width;
7879 node.layout.height = node.lastLayout.height;
7880 node.layout.top = node.lastLayout.top;
7881 node.layout.left = node.lastLayout.left;
7882 } else {
7883 if (!node.lastLayout) {
7884 node.lastLayout = {};
7885 }
7886
7887 node.lastLayout.requestedWidth = node.layout.width;
7888 node.lastLayout.requestedHeight = node.layout.height;
7889 node.lastLayout.parentMaxWidth = parentMaxWidth;
7890 node.lastLayout.direction = direction; // Reset child layouts
7891
7892 node.children.forEach(function (child) {
7893 child.layout.width = undefined;
7894 child.layout.height = undefined;
7895 child.layout.top = 0;
7896 child.layout.left = 0;
7897 });
7898 layoutNodeImpl(node, parentMaxWidth, parentDirection);
7899 node.lastLayout.width = node.layout.width;
7900 node.lastLayout.height = node.layout.height;
7901 node.lastLayout.top = node.layout.top;
7902 node.lastLayout.left = node.layout.left;
7903 } // hack
7904
7905
7906 layoutMargin(node);
7907 }
7908 /* eslint-enable */
7909
7910
7911 function computeLayout(node) {
7912 if (!node) return node;
7913 var style = node.style,
7914 children = node.children;
7915
7916 if (style) {
7917 fillNodes(node);
7918 layoutNode(node, null, null);
7919 return node;
7920 }
7921
7922 if (children && children.length) {
7923 for (var i = 0, len = children.length; i < len; i++) {
7924 computeLayout(children[i]);
7925 }
7926 }
7927
7928 return node;
7929 }
7930
7931 var rect = (function (layout) {
7932 var left = layout.left,
7933 top = layout.top,
7934 width = layout.width,
7935 height = layout.height;
7936 return {
7937 x: left,
7938 y: top,
7939 width: width,
7940 height: height
7941 };
7942 });
7943
7944 var line = (function (layout) {
7945 var left = layout.left,
7946 top = layout.top,
7947 width = layout.width,
7948 height = layout.height;
7949 return {
7950 x1: left,
7951 y1: top,
7952 x2: left + width,
7953 y2: top + height
7954 };
7955 });
7956
7957 var text = (function (layout) {
7958 var height = layout.height,
7959 left = layout.left,
7960 top = layout.top;
7961 return {
7962 x: left,
7963 y: top + height / 2,
7964 // 通过middle + top 才能比较好的实现文本对齐
7965 textBaseline: 'middle'
7966 };
7967 });
7968
7969 var circle = (function (layout) {
7970 var left = layout.left,
7971 top = layout.top,
7972 width = layout.width;
7973 var r = width / 2;
7974 return {
7975 x: left + r,
7976 y: top + r,
7977 r: r
7978 };
7979 });
7980
7981 var marker = (function (layout) {
7982 var left = layout.left,
7983 top = layout.top,
7984 width = layout.width;
7985 var r = width / 2;
7986 return {
7987 x: left + r,
7988 y: top,
7989 radius: r
7990 };
7991 });
7992
7993 var map$2 = {
7994 rect: rect,
7995 line: line,
7996 text: text,
7997 circle: circle,
7998 marker: marker,
7999 group: rect
8000 };
8001 var getShapeAttrs = (function (type, layout) {
8002 if (!layout) return null;
8003 var fn = map$2[type] || rect;
8004 return fn(layout);
8005 });
8006
8007 var ELEMENT_APPEAR = 'appear'; // 标识元素更新
8008
8009 var ELEMENT_UPDATE = 'update'; // 标识是删除的元素
8010
8011 var ELEMENT_DELETE = 'delete';
8012
8013 function createClipElement(type, config) {
8014 return new Shape[upperFirst(type)](config);
8015 }
8016
8017 var getAnimation = (function (element, animation, nextAttrs, lastAttrs) {
8018 if (!animation) return null; // 获取shape的默认属性
8019
8020 var status = element.get('status');
8021 var clip = animation.clip,
8022 start = animation.start,
8023 end = animation.end,
8024 easing = animation.easing,
8025 delay = animation.delay,
8026 duration = animation.duration;
8027 var clipConfig = isFunction(clip) ? clip(element._attrs.attrs) : clip; // 裁剪动画
8028
8029 if (clipConfig) {
8030 var type = clipConfig.type,
8031 attrs = clipConfig.attrs,
8032 clipStart = clipConfig.start;
8033 var clipElement = createClipElement(type, {
8034 attrs: _objectSpread(_objectSpread({}, attrs), clipStart)
8035 }); // 默认用 animation 配置里的 easing 和 duration
8036
8037 clipConfig.easing = clipConfig.easing || easing;
8038 clipConfig.delay = typeof clipConfig.delay === 'number' ? clipConfig.delay : delay;
8039 clipConfig.duration = clipConfig.duration || duration;
8040 clipConfig.element = clipElement;
8041 }
8042
8043 var defaultAttrs = element.getDefaultAttrs();
8044 return _objectSpread(_objectSpread({}, animation), {}, {
8045 clip: clipConfig,
8046 start: _objectSpread(_objectSpread(_objectSpread({}, defaultAttrs), lastAttrs), start),
8047 end: _objectSpread(_objectSpread({}, status === ELEMENT_DELETE ? null : nextAttrs), end)
8048 });
8049 });
8050
8051 function createNodeTree(element, container, px2hd) {
8052 var key = element.key,
8053 ref = element.ref,
8054 _cache = element._cache,
8055 type = element.type,
8056 props = element.props,
8057 status = element.status,
8058 animation = element.animation;
8059 var children = extendMap(props.children, function (child) {
8060 return createNodeTree(child, container, px2hd);
8061 }); // const { style, attrs } = props;
8062
8063 var style = px2hd(props.style);
8064 var attrs = px2hd(props.attrs); // 文本要自动计算文本的宽高, TODO, 后面再优化
8065
8066 if (type === 'text') {
8067 var shape = container.addShape(type, {
8068 attrs: _objectSpread({
8069 x: 0,
8070 y: 0
8071 }, attrs)
8072 });
8073
8074 var _shape$getBBox = shape.getBBox(),
8075 width = _shape$getBBox.width,
8076 height = _shape$getBBox.height;
8077
8078 style = _objectSpread({
8079 width: width,
8080 height: height
8081 }, style); // 无用,销毁掉
8082
8083 shape.remove(true);
8084 }
8085
8086 return {
8087 key: key,
8088 ref: ref,
8089 _cache: _cache,
8090 type: type,
8091 props: props,
8092 children: children,
8093 status: status,
8094 animation: animation,
8095 // 处理px2hd之后的配置
8096 style: style,
8097 attrs: attrs
8098 };
8099 }
8100
8101 function mergeLayout(parent, layout) {
8102 if (!parent || !layout) return layout;
8103 var parentLeft = parent.left,
8104 parentTop = parent.top;
8105 var left = layout.left,
8106 top = layout.top;
8107 return _objectSpread(_objectSpread({}, layout), {}, {
8108 left: parentLeft + left,
8109 top: parentTop + top
8110 });
8111 }
8112
8113 function createElement(node, container, parentLayout, animate) {
8114 var _node$_cache = node._cache,
8115 _cache = _node$_cache === void 0 ? {} : _node$_cache,
8116 ref = node.ref,
8117 type = node.type,
8118 props = node.props,
8119 attrs = node.attrs,
8120 originLayout = node.layout,
8121 renderChildren = node.renderChildren,
8122 nodeChildren = node.children,
8123 status = node.status,
8124 animation = node.animation;
8125
8126 var layout = mergeLayout(parentLayout, originLayout); // 该元素上一次的attrs
8127
8128 var lastAttrs = _cache.attrs;
8129
8130 var elementAttrs = _objectSpread(_objectSpread(_objectSpread({}, getShapeAttrs(type, layout)), status === ELEMENT_DELETE ? lastAttrs : null), attrs); // 缓存这次新的attrs
8131
8132
8133 _cache.attrs = elementAttrs;
8134
8135 if (elementAttrs.clip) {
8136 var clip = elementAttrs.clip;
8137 var clipConfig = isFunction(clip) ? clip(elementAttrs) : clip;
8138 elementAttrs.clip = createClipElement(clipConfig.type, clipConfig);
8139 }
8140
8141 var element;
8142
8143 if (type === 'group') {
8144 element = container.addGroup(_objectSpread(_objectSpread({}, omit(props, ['children'])), {}, {
8145 status: status,
8146 attrs: elementAttrs
8147 })); // 如果元素被删除了,就不会有renderChildren, 直接拿node.children渲染
8148
8149 var children = renderChildren ? renderChildren : nodeChildren; // 只有group才需要处理children
8150
8151 if (children && children.length) {
8152 for (var i = 0, len = children.length; i < len; i++) {
8153 createElement(children[i], element, layout, animate);
8154 }
8155 }
8156 } else {
8157 element = container.addShape(type, _objectSpread(_objectSpread({}, props), {}, {
8158 status: status,
8159 attrs: elementAttrs
8160 }));
8161 }
8162
8163 if (animate !== false) {
8164 element.set('animation', getAnimation(element, animation, elementAttrs, lastAttrs));
8165 }
8166
8167 if (ref) {
8168 ref.current = element;
8169 }
8170
8171 return element;
8172 } // 过滤删除的元素,让其不参与布局计算
8173
8174
8175 function filterDeleteElement(node) {
8176 var status = node.status,
8177 children = node.children;
8178
8179 if (status === ELEMENT_DELETE) {
8180 return null;
8181 }
8182
8183 if (!children || !children.length) {
8184 return node;
8185 }
8186
8187 var newChildren = children.filter(function (child) {
8188 return !!filterDeleteElement(child);
8189 }); // 要保留引用
8190
8191 node.children = newChildren;
8192 node.renderChildren = children;
8193 return node;
8194 }
8195
8196 function render(element, container, animate) {
8197 var px2hd$1 = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : px2hd;
8198
8199 if (!element) {
8200 return;
8201 }
8202
8203 var nodeTree = createNodeTree(element, container, px2hd$1);
8204 var computeLayoutTree = filterDeleteElement(nodeTree);
8205 computeLayout(computeLayoutTree);
8206 return createElement(nodeTree, container, null, animate);
8207 }
8208 var render$1 = (function (element, container, animate) {
8209 return render(element, container, animate);
8210 });
8211
8212 function renderJSXElement(element, context, updater) {
8213 if (!element) return element;
8214
8215 var _element = element,
8216 type = _element.type,
8217 key = _element.key,
8218 ref = _element.ref,
8219 props = _element.props,
8220 _element$_cache = _element._cache,
8221 _cache = _element$_cache === void 0 ? {} : _element$_cache; // render children first
8222
8223
8224 var children = Children.map(props.children, function (child) {
8225 return renderJSXElement(child, context, updater);
8226 });
8227 element = {
8228 type: type,
8229 key: key,
8230 ref: ref,
8231 _cache: _cache,
8232 props: _objectSpread(_objectSpread({}, props), {}, {
8233 children: children
8234 })
8235 };
8236
8237 if (typeof type === 'function') {
8238 // @ts-ignore
8239 var newElement = type(element.props, context, updater);
8240 if (!newElement) return newElement; // recursive render until type is string
8241
8242 return renderJSXElement(_objectSpread(_objectSpread({}, newElement), {}, {
8243 // 保留原始的key和ref
8244 key: key !== undefined ? key : newElement.key,
8245 ref: ref !== undefined ? ref : newElement.ref
8246 }), context, updater);
8247 } // return element if type is string
8248
8249
8250 return element;
8251 }
8252
8253 var renderJSXElement$1 = (function (element, context, updater) {
8254 return renderJSXElement(element, context, updater);
8255 });
8256
8257 var _excluded$1 = ["children", "animation"],
8258 _excluded2 = ["children", "animation"],
8259 _excluded3 = ["children", "animation"],
8260 _excluded4 = ["animation"],
8261 _excluded5 = ["animation"];
8262
8263 function deleteElement(element) {
8264 // 是否有非空的子元素
8265 var hasElement = false;
8266 var receiveElement = Children.map(element, function (item) {
8267 if (!item) return item;
8268 var ref = item.ref,
8269 key = item.key,
8270 type = item.type,
8271 props = item.props,
8272 _cache = item._cache;
8273
8274 var children = props.children,
8275 animation = props.animation,
8276 receiveProps = _objectWithoutProperties(props, _excluded$1);
8277
8278 var status = ELEMENT_DELETE;
8279 var receiveAnimation = animation && animation.leave;
8280 var receiveChildren = deleteElement(children); // 没有子元素,且自身也不需要动画,则直接删除
8281
8282 if (!receiveChildren && !receiveAnimation) {
8283 return null;
8284 }
8285
8286 hasElement = true;
8287 return {
8288 ref: ref,
8289 key: key,
8290 type: type,
8291 props: _objectSpread(_objectSpread({}, receiveProps), {}, {
8292 children: receiveChildren
8293 }),
8294 _cache: _cache,
8295 animation: receiveAnimation,
8296 status: status
8297 };
8298 }); // 如果没有非空的子元素,都删除
8299
8300 if (!hasElement) {
8301 return null;
8302 }
8303
8304 return receiveElement;
8305 }
8306
8307 function appearElement(element) {
8308 return Children.map(element, function (item) {
8309 if (!item) return item;
8310 var ref = item.ref,
8311 key = item.key,
8312 type = item.type,
8313 props = item.props,
8314 _cache = item._cache;
8315
8316 var children = props.children,
8317 animation = props.animation,
8318 receiveProps = _objectWithoutProperties(props, _excluded2);
8319
8320 var status = ELEMENT_APPEAR;
8321 var receiveAnimation = animation && animation.appear;
8322 var receiveChildren = appearElement(children);
8323 return {
8324 ref: ref,
8325 key: key,
8326 type: type,
8327 props: _objectSpread(_objectSpread({}, receiveProps), {}, {
8328 children: receiveChildren
8329 }),
8330 _cache: _cache,
8331 animation: receiveAnimation,
8332 status: status
8333 };
8334 });
8335 }
8336
8337 function updateElement(nextElement, lastElement) {
8338 var ref = nextElement.ref,
8339 key = nextElement.key,
8340 type = nextElement.type,
8341 _nextCache = nextElement._cache,
8342 nextProps = nextElement.props;
8343 var _lastCache = lastElement._cache,
8344 lastProps = lastElement.props;
8345
8346 var nextChildren = nextProps.children,
8347 nextAnimation = nextProps.animation,
8348 nextReceiveProps = _objectWithoutProperties(nextProps, _excluded3);
8349
8350 var lastChildren = lastProps.children; // 继续比较子元素
8351
8352 var children = compareElement(nextChildren, lastChildren); // 保留缓存值
8353
8354 var _cache = mix(_nextCache, _lastCache); // 动画
8355
8356
8357 var animation = nextAnimation && nextAnimation.update; // 生成新对象
8358
8359 return {
8360 ref: ref,
8361 key: key,
8362 type: type,
8363 props: _objectSpread(_objectSpread({}, nextReceiveProps), {}, {
8364 children: children
8365 }),
8366 _cache: _cache,
8367 animation: animation,
8368 status: ELEMENT_UPDATE
8369 };
8370 } // 形变动画, TODO
8371
8372
8373 function morphElement(nextElement, lastElement) {
8374 return [deleteElement(lastElement), appearElement(nextElement)];
8375 }
8376
8377 function changeTypeToGroup(nextGroupElement, lastShapeElement) {
8378 var key = nextGroupElement.key,
8379 type = nextGroupElement.type,
8380 ref = nextGroupElement.ref,
8381 groupProps = nextGroupElement.props,
8382 _groupCache = nextGroupElement._cache;
8383 var lastType = lastShapeElement.type,
8384 _lastCache = lastShapeElement._cache;
8385 var groupChildren = groupProps.children; // let existTransform = false;
8386
8387 var children = Children.map(groupChildren, function (nextElement) {
8388 if (!nextElement) return nextElement;
8389 var key = nextElement.key,
8390 ref = nextElement.ref,
8391 nextType = nextElement.type,
8392 nextProps = nextElement.props,
8393 _nextCache = nextElement._cache; // if (nextType === 'group') {
8394 // return changeTypeToGroup(nextElement, lastShapeElement);
8395 // }
8396
8397 if (nextType !== lastType) {
8398 return morphElement(nextElement, lastShapeElement);
8399 } // existTransform = true;
8400
8401
8402 var nextAnimation = nextProps.animation,
8403 nextReceiveProps = _objectWithoutProperties(nextProps, _excluded4);
8404
8405 var animation = nextAnimation && nextAnimation.update;
8406 return {
8407 ref: ref,
8408 key: key,
8409 type: nextType,
8410 props: nextReceiveProps,
8411 _cache: mix(_nextCache, _lastCache),
8412 animation: animation,
8413 status: ELEMENT_UPDATE
8414 };
8415 });
8416 return {
8417 key: key,
8418 type: type,
8419 ref: ref,
8420 props: _objectSpread(_objectSpread({}, groupProps), {}, {
8421 children: children
8422 }),
8423 _cache: _groupCache,
8424 status: ELEMENT_UPDATE
8425 };
8426 }
8427
8428 function changeTypeFromGroup(nextShapeElement, lastGroupElement) {
8429 var nextRef = nextShapeElement.ref,
8430 nextKey = nextShapeElement.key,
8431 nextType = nextShapeElement.type,
8432 nextShapeProps = nextShapeElement.props,
8433 _nextCache = nextShapeElement._cache;
8434 var lastType = lastGroupElement.type,
8435 lastProps = lastGroupElement.props;
8436
8437 var nextAnimation = nextShapeProps.animation,
8438 nextReceiveProps = _objectWithoutProperties(nextShapeProps, _excluded5);
8439
8440 var groupChildren = lastProps.children;
8441 var animation = nextAnimation && nextAnimation.update;
8442
8443 if (!animation) {
8444 return [deleteElement(lastGroupElement), appearElement[nextShapeElement]];
8445 }
8446
8447 var transformChild = null;
8448 var children = Children.map(groupChildren, function (child) {
8449 if (!child) return child;
8450 var childType = child.type,
8451 _childCache = child._cache;
8452
8453 if (childType !== nextType) {
8454 // TODO: child 形变
8455 return deleteElement(child);
8456 }
8457
8458 if (!transformChild) {
8459 transformChild = child;
8460 }
8461
8462 return {
8463 type: nextType,
8464 props: nextShapeProps,
8465 _cache: _childCache,
8466 animation: animation,
8467 status: ELEMENT_UPDATE
8468 };
8469 });
8470
8471 if (!transformChild) {
8472 return [deleteElement(lastGroupElement), appearElement(nextShapeElement)];
8473 }
8474
8475 var nextElement = {
8476 ref: nextRef,
8477 key: nextKey,
8478 type: nextType,
8479 props: nextReceiveProps,
8480 _cache: mix(_nextCache, transformChild._cache),
8481 animation: animation,
8482 status: ELEMENT_UPDATE
8483 }; // 保留group 结构
8484
8485 return [{
8486 type: lastType,
8487 props: _objectSpread(_objectSpread({}, lastProps), {}, {
8488 children: children
8489 }),
8490 status: ELEMENT_DELETE
8491 }, nextElement];
8492 }
8493
8494 function changeElementType(nextElement, lastElement) {
8495 var nextType = nextElement.type;
8496 var lastType = lastElement.type;
8497
8498 if (nextType === 'group') {
8499 return changeTypeToGroup(nextElement, lastElement);
8500 }
8501
8502 if (lastType === 'group') {
8503 return changeTypeFromGroup(nextElement, lastElement);
8504 } // 都不是group, 形变动画 TODO
8505
8506
8507 return morphElement(nextElement, lastElement);
8508 } // 对比2个数组
8509
8510
8511 function compareArray$1(nextElements, lastElements) {
8512 var keyed = {};
8513 var nextLength = nextElements.length;
8514 var lastLength = lastElements.length;
8515
8516 for (var i = 0; i < lastLength; i++) {
8517 var element = lastElements[i];
8518
8519 if (element && !isNil(element.key)) {
8520 var key = element.key;
8521 keyed[key] = element;
8522 }
8523 } // 比较元素
8524
8525
8526 var maxLength = Math.max(nextLength, lastLength);
8527 var returnElements = [];
8528
8529 for (var _i = 0; _i < maxLength; _i++) {
8530 var nextElement = nextElements[_i];
8531
8532 if (!nextElement) {
8533 returnElements.push(compareElement(nextElement, lastElements[_i]));
8534 continue;
8535 }
8536
8537 var _key = nextElement.key; // 有key值定义
8538
8539 if (!isNil(_key)) {
8540 var lastElement = keyed[_key];
8541 if (lastElement) delete keyed[_key];
8542 returnElements.push(compareElement(nextElement, lastElement));
8543 continue;
8544 }
8545
8546 returnElements.push(compareElement(nextElement, lastElements[_i]));
8547 } // 说明是删除的元素
8548
8549
8550 Object.keys(keyed).forEach(function (key) {
8551 returnElements.push(compareElement(null, keyed[key]));
8552 });
8553 return returnElements;
8554 } // 比较2个元素,会被递归执行
8555
8556
8557 function compareElement(nextElement, lastElement) {
8558 // 都为空
8559 if (!nextElement && !lastElement) {
8560 return null;
8561 } // 新增
8562
8563
8564 if (!lastElement) {
8565 return appearElement(nextElement);
8566 } // 删除
8567
8568
8569 if (!nextElement) {
8570 return deleteElement(lastElement);
8571 } // nextElement & lastElement 都不为空了
8572 // 如果有数组,比较数组
8573
8574
8575 if (isArray(nextElement) || isArray(lastElement)) {
8576 var nextElementArray = isArray(nextElement) ? nextElement : [nextElement];
8577 var lastElementArray = isArray(lastElement) ? lastElement : [lastElement];
8578 return compareArray$1(nextElementArray, lastElementArray);
8579 } // 普通的jsx元素, 且都非空
8580
8581
8582 var nextKey = nextElement.key,
8583 nextType = nextElement.type;
8584 var lastKey = lastElement.key,
8585 lastType = lastElement.type; // key 值不相等
8586
8587 if (!isNil(nextKey) && nextKey !== lastKey) {
8588 return [deleteElement(lastElement), appearElement(nextElement)];
8589 } // shape 类型的变化
8590
8591
8592 if (nextType !== lastType) {
8593 // return [deleteElement(lastElement), nextElement];
8594 return changeElementType(nextElement, lastElement);
8595 }
8596
8597 return updateElement(nextElement, lastElement);
8598 } // 因为要实现删除元素的动画,所以需要保留删除的元素,diff 后需要创建一颗新树, 实际渲染也需要拿这颗树来进行
8599
8600 var Animator = /*#__PURE__*/function () {
8601 function Animator(element, animation) {
8602 _classCallCheck(this, Animator);
8603
8604 // 是否是裁剪动画
8605 this.isClip = false;
8606 this.end = false;
8607 this.element = element;
8608 this.animation = animation;
8609 var _animation$property = animation.property,
8610 property = _animation$property === void 0 ? [] : _animation$property,
8611 easing = animation.easing,
8612 duration = animation.duration,
8613 _animation$delay = animation.delay,
8614 delay = _animation$delay === void 0 ? 0 : _animation$delay,
8615 start = animation.start,
8616 end = animation.end,
8617 onFrame = animation.onFrame,
8618 isClip = animation.isClip;
8619 var interpolates = property.map(function (name) {
8620 if (isString(name)) {
8621 return interpolate$1(start[name], end[name]);
8622 } // @ts-ignore
8623
8624
8625 if (name.interpolate) {
8626 // @ts-ignore
8627 return name.interpolate(start, end);
8628 }
8629 });
8630 this.easing = typeof easing === 'function' ? easing : Easing[easing] || linear$1;
8631 this.property = property;
8632 this.interpolates = interpolates;
8633 this.duration = duration;
8634 this.delay = delay;
8635 this.onFrame = onFrame;
8636 this.totalDuration = duration + delay;
8637 this.isClip = isClip; // 更新到初始状态
8638
8639 this.update(0, 0);
8640 }
8641
8642 _createClass(Animator, [{
8643 key: "to",
8644 value: function to(time) {
8645 var duration = this.duration,
8646 delay = this.delay,
8647 totalDuration = this.totalDuration,
8648 easing = this.easing,
8649 end = this.end; // 已结束
8650
8651 if (end) {
8652 return;
8653 } // 未开始
8654
8655
8656 if (time <= delay || !duration) {
8657 return;
8658 } // 最大为1
8659
8660
8661 var t = time >= totalDuration ? 1 : (time - delay) / duration;
8662 this.update(easing(t), time); // 最后一帧
8663
8664 if (t === 1) {
8665 this.onEnd();
8666 }
8667 }
8668 }, {
8669 key: "update",
8670 value: function update(t, time) {
8671 var element = this.element,
8672 interpolates = this.interpolates,
8673 property = this.property,
8674 onFrame = this.onFrame;
8675 var attrs = {};
8676
8677 for (var i = property.length - 1; i >= 0; i--) {
8678 var name = property[i];
8679
8680 if (isString(name)) {
8681 attrs[name] = interpolates[i](t);
8682 } else {
8683 // @ts-ignore
8684 attrs[name.name] = interpolates[i](t);
8685 }
8686 }
8687
8688 if (onFrame) {
8689 attrs = _objectSpread(_objectSpread({}, attrs), this.onFrame(t, time));
8690 }
8691
8692 element.attr(attrs);
8693 }
8694 }, {
8695 key: "onEnd",
8696 value: function onEnd() {
8697 var animation = this.animation,
8698 isClip = this.isClip,
8699 element = this.element;
8700 var onEnd = animation.onEnd;
8701 onEnd && onEnd.call(this);
8702
8703 if (isClip) {
8704 // 如果是裁剪区动画,要移除裁剪区
8705 element.remove(true);
8706 } // 如果当前元素状态被标记为删除,等动画结束后直接删除
8707
8708
8709 if (element._attrs.status === ELEMENT_DELETE) {
8710 element.remove(true);
8711 } // 清空 不需要重复执行
8712
8713
8714 element.set('animation', null);
8715 this.end = true;
8716 }
8717 }]);
8718
8719 return Animator;
8720 }();
8721
8722 function eachElement(element, fn) {
8723 fn(element);
8724 var children = element.get('children');
8725
8726 if (children && children.length) {
8727 for (var i = 0, len = children.length; i < len; i++) {
8728 var child = children[i];
8729 eachElement(child, fn);
8730 }
8731 }
8732 }
8733
8734 var Animation = /*#__PURE__*/function () {
8735 function Animation(canvas) {
8736 _classCallCheck(this, Animation);
8737
8738 this.timeline = new Timeline$1();
8739 this.canvas = canvas;
8740 }
8741
8742 _createClass(Animation, [{
8743 key: "createAnimator",
8744 value: function createAnimator(element, animation) {
8745 var duration = animation.duration,
8746 property = animation.property,
8747 onFrame = animation.onFrame; // 校验关键参数
8748
8749 if (!duration || (!property || !property.length) && !onFrame) {
8750 return;
8751 }
8752
8753 return new Animator(element, animation);
8754 }
8755 }, {
8756 key: "play",
8757 value: function play(container, onAnimationEnd) {
8758 var _this = this;
8759
8760 var canvas = this.canvas;
8761 var animators = [];
8762 var maxDuration = 0;
8763 var deleteElements = []; // 遍历整个树,找到全部需要动画的元素
8764
8765 eachElement(container, function (element) {
8766 // TODO: status 需要提取状态
8767 var _element$_attrs = element._attrs,
8768 animation = _element$_attrs.animation,
8769 status = _element$_attrs.status;
8770
8771 if (!animation) {
8772 if (status === ELEMENT_DELETE) {
8773 // element.remove(true);
8774 deleteElements.push(element);
8775 }
8776
8777 return;
8778 }
8779
8780 var animator = _this.createAnimator(element, animation);
8781
8782 if (animator) {
8783 maxDuration = Math.max(maxDuration, animator.totalDuration);
8784 animators.push(animator);
8785 }
8786
8787 var clip = animation.clip; // 如果有裁剪区动画,处理裁剪区动画
8788
8789 if (clip) {
8790 clip.isClip = true;
8791 var clipElement = clip.element;
8792
8793 var _animator = _this.createAnimator(clipElement, clip);
8794
8795 if (_animator) {
8796 maxDuration = Math.max(maxDuration, _animator.totalDuration);
8797 element.attr('clip', clipElement);
8798 animators.push(_animator);
8799 }
8800 }
8801 });
8802
8803 for (var i = 0, len = deleteElements.length; i < len; i++) {
8804 var element = deleteElements[i];
8805 var children = element._attrs.children; // 因为group的子元素也有可能有动画,所以这里先把叶子节点删除掉,等动画结束后,再把所有删除的元素删除掉
8806
8807 if (!children || !children.length) {
8808 element.remove(true);
8809 }
8810 } // 开始播放动画
8811
8812
8813 this.timeline.play(maxDuration, function (time) {
8814 for (var _i = 0, _len = animators.length; _i < _len; _i++) {
8815 var animator = animators[_i];
8816 animator.to(time);
8817 } // 最后一帧放在end里统一draw, 避免重复draw
8818
8819
8820 if (time < maxDuration) {
8821 canvas.draw();
8822 }
8823 }, function () {
8824 for (var _i2 = 0, _len2 = deleteElements.length; _i2 < _len2; _i2++) {
8825 var _element = deleteElements[_i2];
8826
8827 _element.remove(true);
8828 }
8829
8830 canvas.draw();
8831 onAnimationEnd && onAnimationEnd();
8832 });
8833 } // 直接跳到动画最终态
8834
8835 }, {
8836 key: "end",
8837 value: function end() {
8838 this.timeline.end();
8839 }
8840 }, {
8841 key: "abort",
8842 value: function abort() {
8843 this.timeline.abort();
8844 }
8845 }]);
8846
8847 return Animation;
8848 }();
8849
8850 function createUpdater(canvas) {
8851 var setStateQueue = [];
8852 var renderQueue = [];
8853 var callbackQueue = [];
8854
8855 function process() {
8856 var item; // let component;
8857
8858 while (item = setStateQueue.shift()) {
8859 var _item = item,
8860 state = _item.state,
8861 component = _item.component,
8862 callback = _item.callback;
8863
8864 if (component.destroyed) {
8865 continue;
8866 } // 如果没有prevState,则将当前的state作为初始的prevState
8867
8868
8869 if (!component.prevState) {
8870 component.prevState = Object.assign({}, component.state);
8871 } // 如果stateChange是一个方法,也就是setState的第二种形式
8872
8873
8874 if (typeof state === 'function') {
8875 Object.assign(component.state, state(component.prevState, component.props));
8876 } else {
8877 // 如果stateChange是一个对象,则直接合并到setState中
8878 Object.assign(component.state, state);
8879 }
8880
8881 component.prevState = component.state;
8882
8883 if (typeof callback === 'function') {
8884 callbackQueue.push({
8885 callback: callback,
8886 component: component
8887 });
8888 }
8889 }
8890
8891 var renderComponents = [].concat(renderQueue);
8892 canvas.renderComponents(renderComponents); // callback queue
8893
8894 commitRenderQueue(); // 清空
8895
8896 renderQueue.length = 0;
8897 callbackQueue.length = 0;
8898 }
8899
8900 function enqueueSetState(component, state, callback) {
8901 if (setStateQueue.length === 0) {
8902 setTimeout(process, 0);
8903 }
8904
8905 setStateQueue.push({
8906 component: component,
8907 state: state,
8908 callback: callback
8909 });
8910
8911 if (renderQueue.indexOf(component) < 0) {
8912 renderQueue.push(component);
8913 }
8914 }
8915
8916 function commitRenderQueue() {
8917 for (var i = 0; i < callbackQueue.length; i++) {
8918 var _callbackQueue$i = callbackQueue[i],
8919 callback = _callbackQueue$i.callback,
8920 component = _callbackQueue$i.component;
8921 callback.call(component);
8922 }
8923 }
8924
8925 var updater = {
8926 // isMounted: function(publicInstance) {
8927 // return false;
8928 // },
8929 enqueueForceUpdate: enqueueSetState,
8930 // enqueueReplaceState: function(publicInstance, completeState) {
8931 // },
8932 enqueueSetState: enqueueSetState
8933 };
8934 return updater;
8935 }
8936
8937 var axis = {
8938 labelOffset: '15px',
8939 line: {
8940 stroke: '#E8E8E8',
8941 lineWidth: '1px'
8942 },
8943 label: {
8944 fill: '#808080',
8945 fontSize: '20px'
8946 },
8947 grid: {
8948 stroke: '#E8E8E8',
8949 lineWidth: '1px',
8950 lineDash: ['4px']
8951 }
8952 };
8953 var guide = {
8954 line: {
8955 style: {
8956 stroke: '#a3a3a3',
8957 lineWidth: 1
8958 },
8959 offsetX: 0,
8960 offsetY: 0
8961 },
8962 text: {
8963 style: {
8964 fill: '#787878',
8965 // textAlign: 'center',
8966 textBaseline: 'middle'
8967 },
8968 offsetX: 0,
8969 offsetY: 0
8970 },
8971 rect: {
8972 style: {
8973 fill: '#fafafa'
8974 }
8975 },
8976 arc: {
8977 style: {
8978 stroke: '#a3a3a3'
8979 }
8980 },
8981 html: {
8982 offsetX: 0,
8983 offsetY: 0,
8984 alignX: 'center',
8985 alignY: 'middle'
8986 },
8987 tag: {
8988 offsetX: 0,
8989 offsetY: 0,
8990 side: 4,
8991 background: {
8992 padding: 5,
8993 radius: 2,
8994 fill: '#1890FF'
8995 },
8996 textStyle: {
8997 fontSize: 12,
8998 fill: '#fff',
8999 textAlign: 'center',
9000 textBaseline: 'middle'
9001 }
9002 },
9003 point: {
9004 offsetX: 0,
9005 offsetY: 0,
9006 style: {
9007 fill: '#fff',
9008 r: 3,
9009 lineWidth: 2,
9010 stroke: '#1890ff'
9011 }
9012 }
9013 };
9014 var chart = {
9015 padding: ['30px', '30px', '30px', '30px']
9016 };
9017 var Theme = {
9018 fontFamily: '"Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif',
9019 pixelRatio: 1,
9020 padding: [0, 0, 0, 0],
9021 chart: chart,
9022 colors: ['#1890FF', '#2FC25B', '#FACC14', '#223273', '#8543E0', '#13C2C2', '#3436C7', '#F04864'],
9023 shapes: {
9024 line: ['line', 'dash', 'smooth'],
9025 point: ['circle', 'hollowCircle', 'rect'],
9026 area: ['area', 'smooth'],
9027 interval: ['rect', 'pyramid', 'funnel']
9028 },
9029 sizes: ['4px', '6px', '8px', '10px', '12px'],
9030 shape: {
9031 line: {
9032 default: {
9033 lineWidth: '4px',
9034 lineJoin: 'round',
9035 lineCap: 'round'
9036 },
9037 smooth: {
9038 smooth: true
9039 },
9040 dash: {
9041 lineDash: ['8px', '8px']
9042 }
9043 },
9044 point: {
9045 default: {
9046 size: '6px'
9047 },
9048 hollowCircle: {
9049 lineWidth: '2px'
9050 }
9051 },
9052 area: {
9053 default: {
9054 fillOpacity: 0.1
9055 }
9056 },
9057 interval: {
9058 default: {}
9059 }
9060 },
9061 axis: axis,
9062 guide: guide
9063 };
9064
9065 var _excluded$2 = ["transformFrom"];
9066
9067 function pickElement(element) {
9068 if (!element) return element;
9069 return Children.map(element, function (item) {
9070 if (!item) return item; // 只需要这几个元素就可以了
9071
9072 return pick(item, ['key', 'ref', 'type', 'props']);
9073 });
9074 }
9075
9076 function renderShape(component, children, animate) {
9077 var container = component.container,
9078 context = component.context,
9079 updater = component.updater,
9080 __lastElement = component.__lastElement,
9081 transformFrom = component.transformFrom,
9082 componentAnimate = component.animate; // 先清空绘制内容
9083
9084 container.clear();
9085 animate = isBoolean(animate) ? animate : componentAnimate;
9086 var px2hd = context.px2hd;
9087 var lastElement = __lastElement || transformFrom && transformFrom.__lastElement; // children 是 shape 的 jsx 结构, component.render() 返回的结构
9088
9089 var shapeElement = renderJSXElement$1(children, context, updater); // @ts-ignore
9090
9091 component.__lastElement = shapeElement;
9092 var renderElement = animate !== false ? compareElement(shapeElement, lastElement) : shapeElement;
9093 if (!renderElement) return null; // 生成G的节点树, 存在数组的情况是根节点有变化,之前的树删除,新的树创建
9094
9095 if (isArray(renderElement)) {
9096 return renderElement.map(function (element) {
9097 return render(element, container, animate, px2hd);
9098 });
9099 } else {
9100 return render(renderElement, container, animate, px2hd);
9101 }
9102 }
9103
9104 function setComponentAnimate(child, parent) {
9105 var parentAnimate = parent.animate; // 如果父组件不需要动画,子组件全不不执行动画
9106
9107 if (parentAnimate === false) {
9108 child.animate = false;
9109 return;
9110 }
9111
9112 var childProps = child.props;
9113 var childAnimate = childProps.animate;
9114 child.animate = isBoolean(childAnimate) ? childAnimate : parentAnimate;
9115 }
9116
9117 function getTransformComponent(component) {
9118 if (!component) return null; // @ts-ignore
9119
9120 var __lastElement = component.__lastElement,
9121 children = component.children;
9122
9123 if (__lastElement) {
9124 return component;
9125 }
9126
9127 if (!children) {
9128 return null;
9129 }
9130
9131 var componentFromChildren = null;
9132 Children.map(children, function (item) {
9133 if (componentFromChildren) return;
9134 if (!item) return;
9135 var component = getTransformComponent(item.component);
9136
9137 if (component) {
9138 componentFromChildren = component;
9139 }
9140 });
9141 return componentFromChildren;
9142 }
9143
9144 function getTransformFromComponentRef(transformFromRef) {
9145 if (!transformFromRef || !transformFromRef.current) {
9146 return null;
9147 }
9148
9149 var transformFromComponent = transformFromRef.current;
9150 return getTransformComponent(transformFromComponent);
9151 }
9152
9153 function createComponent(parent, element) {
9154 var type = element.type,
9155 props = element.props,
9156 ref = element.ref;
9157 var container = parent.container,
9158 context = parent.context,
9159 updater = parent.updater,
9160 transformFrom = parent.transformFrom;
9161
9162 var transformFromRef = props.transformFrom,
9163 receiveProps = _objectWithoutProperties(props, _excluded$2);
9164
9165 var component; // @ts-ignore
9166
9167 if (type.prototype && type.prototype.isF2Component) {
9168 // @ts-ignore
9169 component = new type(receiveProps, context, updater);
9170 } else {
9171 component = new Component(receiveProps, context, updater);
9172
9173 component.render = function () {
9174 // @ts-ignore
9175 return type(this.props, context, updater);
9176 };
9177 } // 设置ref
9178
9179
9180 if (ref) {
9181 ref.current = component;
9182 } // 因为view 可能在子组件,所以这里要透传到子组件
9183
9184
9185 if (transformFrom) {
9186 // @ts-ignore
9187 component.transformFrom = transformFrom;
9188 }
9189
9190 if (transformFromRef) {
9191 var transformFromComponent = transformFromRef ? getTransformFromComponentRef(transformFromRef) : null; // @ts-ignore
9192
9193 component.transformFrom = transformFromComponent;
9194 }
9195
9196 var zIndex = props.zIndex; // 每个组件都新建一个独立容器
9197
9198 component.container = container.addGroup({
9199 zIndex: zIndex
9200 });
9201 component.context = context;
9202 component.updater = updater;
9203 return component;
9204 }
9205
9206 function renderComponent(component) {
9207 Children.map(component, function (item) {
9208 var lastChildren = item.children;
9209 var mount = isUndefined(lastChildren);
9210
9211 if (mount) {
9212 if (item.willMount) item.willMount();
9213 } else if (item.willUpdate) {
9214 item.willUpdate();
9215 }
9216 });
9217 Children.map(component, function (item) {
9218 var lastChildren = item.children;
9219 var mount = isUndefined(lastChildren);
9220 var newChildren = item.render();
9221 renderChildren(item, newChildren, lastChildren);
9222
9223 if (mount) {
9224 if (item.didMount) item.didMount();
9225 } else if (item.didUpdate) {
9226 item.didUpdate();
9227 }
9228 });
9229 }
9230
9231 function destroyElement(elements) {
9232 Children.map(elements, function (element) {
9233 if (!element) return;
9234 var component = element.component;
9235
9236 if (!component) {
9237 return;
9238 }
9239
9240 if (component.willUnmount) {
9241 component.willUnmount();
9242 }
9243
9244 destroyElement(component.children);
9245 var container = component.container;
9246 container.remove(true);
9247
9248 if (component.didUnmount) {
9249 component.didUnmount();
9250 }
9251
9252 component.destroy();
9253 });
9254 }
9255
9256 function diffElement(parent, nextElement, lastElement) {
9257 if (!nextElement && !lastElement) {
9258 return null;
9259 } // 删除
9260
9261
9262 if (!nextElement && lastElement) {
9263 destroyElement(lastElement);
9264 return null;
9265 } // 新建
9266
9267
9268 if (nextElement && !lastElement) {
9269 return nextElement;
9270 } // diff
9271
9272
9273 var nextType = nextElement.type,
9274 nextProps = nextElement.props;
9275 var lastType = lastElement.type,
9276 lastProps = lastElement.props,
9277 lastComponent = lastElement.component;
9278
9279 if (nextType !== lastType) {
9280 destroyElement(lastElement);
9281 return nextElement;
9282 } // 保留component, 等下一阶段处理
9283
9284
9285 nextElement.component = lastComponent;
9286
9287 if (equal(nextProps, lastProps) && lastComponent.context === parent.context) {
9288 return null;
9289 }
9290
9291 return nextElement;
9292 }
9293
9294 function diff(parent, nextChildren, lastChildren) {
9295 // destroy
9296 // 生命周期的几个阶段
9297 // should create / update
9298 // create / Receive props
9299 // willMount / willUpdate
9300 // render
9301 // didMount / didUpdate
9302 var childrenArray = []; // 1. 第一轮比较, 直接destroy的元素处理掉,destroy 的元素不需要进入下一阶段
9303
9304 Children.compare(nextChildren, lastChildren, function (next, last) {
9305 var element = diffElement(parent, next, last);
9306
9307 if (element) {
9308 childrenArray = childrenArray.concat(Children.toArray(element).filter(Boolean));
9309 }
9310 }); // 2. 处理 shouldCreate 和 shouldUpdate
9311
9312 var shouldProcessChildren = childrenArray.filter(function (element) {
9313 var component = element.component,
9314 props = element.props; // 说明是新增的元素,需要新建
9315
9316 if (!component) return true; // 不需要更新
9317
9318 if (component.shouldUpdate && component.shouldUpdate(props) === false) {
9319 return false;
9320 }
9321
9322 return true;
9323 }); // 3. 处理 create 和 Receive props
9324
9325 var shouldRenderComponent = shouldProcessChildren.map(function (element) {
9326 var component = element.component;
9327
9328 if (!component) {
9329 component = createComponent(parent, element);
9330 } else {
9331 var props = element.props;
9332
9333 if (component.willReceiveProps) {
9334 component.willReceiveProps(props, parent.context);
9335 }
9336
9337 var zIndex = props.zIndex;
9338 component.container.set('zIndex', zIndex);
9339 component.props = props;
9340 component.context = parent.context;
9341 }
9342
9343 element.component = component;
9344 setComponentAnimate(component, parent);
9345 return component;
9346 }); // 4. 处理 render
9347
9348 renderComponent(shouldRenderComponent); // 按子组件顺序渲染内容
9349
9350 childrenArray.forEach(function (element) {
9351 var component = element.component;
9352 var parentGroup = parent.container;
9353 parentGroup.add(component.container);
9354 });
9355 return nextChildren;
9356 }
9357
9358 function isContainer(children) {
9359 if (!children) return false;
9360
9361 if (!isArray(children)) {
9362 var type = children.type;
9363 return typeof type === 'function';
9364 }
9365
9366 for (var i = 0, len = children.length; i < len; i++) {
9367 if (isContainer(children[i])) {
9368 return true;
9369 }
9370 }
9371
9372 return false;
9373 }
9374
9375 function renderChildren(parent, nextChildren, lastChildren) {
9376 // react 生成的 element 是 not extensible 的,这里新建一个新对象,并把需要的内容pick 出来
9377 nextChildren = pickElement(nextChildren);
9378 parent.children = nextChildren;
9379
9380 if (isContainer(nextChildren)) {
9381 nextChildren = diff(parent, nextChildren, lastChildren);
9382 } else {
9383 renderShape(parent, nextChildren);
9384 }
9385
9386 return nextChildren;
9387 }
9388
9389 var WILDCARD = '*';
9390 /* event-emitter */
9391 var EventEmitter = /** @class */ (function () {
9392 function EventEmitter() {
9393 this._events = {};
9394 }
9395 /**
9396 * 监听一个事件
9397 * @param evt
9398 * @param callback
9399 * @param once
9400 */
9401 EventEmitter.prototype.on = function (evt, callback, once) {
9402 if (!this._events[evt]) {
9403 this._events[evt] = [];
9404 }
9405 this._events[evt].push({
9406 callback: callback,
9407 once: !!once,
9408 });
9409 return this;
9410 };
9411 /**
9412 * 监听一个事件一次
9413 * @param evt
9414 * @param callback
9415 */
9416 EventEmitter.prototype.once = function (evt, callback) {
9417 return this.on(evt, callback, true);
9418 };
9419 /**
9420 * 触发一个事件
9421 * @param evt
9422 * @param args
9423 */
9424 EventEmitter.prototype.emit = function (evt) {
9425 var _this = this;
9426 var args = [];
9427 for (var _i = 1; _i < arguments.length; _i++) {
9428 args[_i - 1] = arguments[_i];
9429 }
9430 var events = this._events[evt] || [];
9431 var wildcardEvents = this._events[WILDCARD] || [];
9432 // 实际的处理 emit 方法
9433 var doEmit = function (es) {
9434 var length = es.length;
9435 for (var i = 0; i < length; i++) {
9436 if (!es[i]) {
9437 continue;
9438 }
9439 var _a = es[i], callback = _a.callback, once = _a.once;
9440 if (once) {
9441 es.splice(i, 1);
9442 if (es.length === 0) {
9443 delete _this._events[evt];
9444 }
9445 length--;
9446 i--;
9447 }
9448 callback.apply(_this, args);
9449 }
9450 };
9451 doEmit(events);
9452 doEmit(wildcardEvents);
9453 };
9454 /**
9455 * 取消监听一个事件,或者一个channel
9456 * @param evt
9457 * @param callback
9458 */
9459 EventEmitter.prototype.off = function (evt, callback) {
9460 if (!evt) {
9461 // evt 为空全部清除
9462 this._events = {};
9463 }
9464 else {
9465 if (!callback) {
9466 // evt 存在,callback 为空,清除事件所有方法
9467 delete this._events[evt];
9468 }
9469 else {
9470 // evt 存在,callback 存在,清除匹配的
9471 var events = this._events[evt] || [];
9472 var length_1 = events.length;
9473 for (var i = 0; i < length_1; i++) {
9474 if (events[i].callback === callback) {
9475 events.splice(i, 1);
9476 length_1--;
9477 i--;
9478 }
9479 }
9480 if (events.length === 0) {
9481 delete this._events[evt];
9482 }
9483 }
9484 }
9485 return this;
9486 };
9487 /* 当前所有的事件 */
9488 EventEmitter.prototype.getEvents = function () {
9489 return this._events;
9490 };
9491 return EventEmitter;
9492 }());
9493
9494 function measureText$2(canvas, px2hd) {
9495 return function (text, font) {
9496 var _ref = font || {},
9497 fontSize = _ref.fontSize,
9498 fontFamily = _ref.fontFamily,
9499 fontStyle = _ref.fontStyle,
9500 fontWeight = _ref.fontWeight,
9501 fontVariant = _ref.fontVariant;
9502
9503 var shape = canvas.addShape('text', {
9504 attrs: {
9505 x: 0,
9506 y: 0,
9507 fontSize: px2hd(fontSize),
9508 fontFamily: fontFamily,
9509 fontStyle: fontStyle,
9510 fontWeight: fontWeight,
9511 fontVariant: fontVariant,
9512 text: text
9513 }
9514 });
9515
9516 var _shape$getBBox = shape.getBBox(),
9517 width = _shape$getBBox.width,
9518 height = _shape$getBBox.height;
9519
9520 shape.remove(true);
9521 return {
9522 width: width,
9523 height: height
9524 };
9525 };
9526 } // 顶层Canvas标签
9527
9528
9529 var Canvas$1 = /*#__PURE__*/function (_Component) {
9530 _inherits(Canvas, _Component);
9531
9532 var _super = _createSuper(Canvas);
9533
9534 function Canvas(props) {
9535 var _this;
9536
9537 _classCallCheck(this, Canvas);
9538
9539 _this = _super.call(this, props);
9540 var context = props.context,
9541 pixelRatio = props.pixelRatio,
9542 width = props.width,
9543 height = props.height,
9544 _props$animate = props.animate,
9545 animate = _props$animate === void 0 ? true : _props$animate,
9546 customPx2hd = props.px2hd,
9547 customTheme = props.theme,
9548 customStyle = props.style,
9549 createImage = props.createImage,
9550 landscape = props.landscape;
9551 var px2hd$1 = isFunction(customPx2hd) ? batch2hd(customPx2hd) : px2hd;
9552 var theme = px2hd$1(deepMix({}, Theme, customTheme)); // 创建G的canvas
9553
9554 var canvas = createCanvas({
9555 context: context,
9556 pixelRatio: pixelRatio,
9557 fontFamily: theme.fontFamily,
9558 width: width,
9559 height: height,
9560 createImage: createImage,
9561 landscape: landscape
9562 }); // 组件更新器
9563
9564 var updater = createUpdater(_assertThisInitialized(_this)); // 供全局使用的一些变量
9565
9566 var componentContext = {
9567 root: _assertThisInitialized(_this),
9568 canvas: canvas,
9569 theme: theme,
9570 px2hd: px2hd$1,
9571 measureText: measureText$2(canvas, px2hd$1)
9572 }; // 动画模块
9573
9574 var animation = new Animation(canvas);
9575 _this.canvas = canvas;
9576 _this.container = canvas;
9577 _this.context = componentContext;
9578 _this.updater = updater;
9579 _this.animate = animate;
9580 _this.animation = animation;
9581 _this.theme = theme;
9582 _this._ee = new EventEmitter();
9583
9584 _this.updateLayout(props);
9585
9586 return _this;
9587 }
9588
9589 _createClass(Canvas, [{
9590 key: "renderComponents",
9591 value: function renderComponents(components) {
9592 if (!components || !components.length) {
9593 return;
9594 }
9595
9596 renderComponent(components);
9597 this.draw();
9598 }
9599 }, {
9600 key: "update",
9601 value: function update(nextProps) {
9602 var props = this.props;
9603
9604 if (equal(nextProps, props)) {
9605 return;
9606 }
9607
9608 this.props = nextProps;
9609 this.render();
9610 }
9611 }, {
9612 key: "resize",
9613 value: function resize(width, height) {
9614 var _this$canvas$_attrs = this.canvas._attrs,
9615 canvasWidth = _this$canvas$_attrs.width,
9616 canvasHeight = _this$canvas$_attrs.height;
9617 this.canvas.changeSize(width || canvasWidth, height || canvasHeight); // this.canvas.clear();
9618 // this.children = null;
9619
9620 this.updateLayout(_objectSpread(_objectSpread({}, this.props), {}, {
9621 width: width,
9622 height: height
9623 }));
9624 this.render();
9625 }
9626 }, {
9627 key: "updateLayout",
9628 value: function updateLayout(props) {
9629 var _this$canvas$_attrs2 = this.canvas._attrs,
9630 canvasWidth = _this$canvas$_attrs2.width,
9631 canvasHeight = _this$canvas$_attrs2.height;
9632 var style = this.context.px2hd(_objectSpread({
9633 left: 0,
9634 top: 0,
9635 width: (props === null || props === void 0 ? void 0 : props.width) || canvasWidth,
9636 height: (props === null || props === void 0 ? void 0 : props.height) || canvasHeight,
9637 padding: this.theme.padding
9638 }, props.style));
9639 this.layout = Layout.fromStyle(style);
9640 this.context = _objectSpread(_objectSpread({}, this.context), {}, {
9641 left: this.layout.left,
9642 top: this.layout.top,
9643 width: this.layout.width,
9644 height: this.layout.height
9645 });
9646 }
9647 }, {
9648 key: "draw",
9649 value: function draw() {
9650 var canvas = this.canvas,
9651 animate = this.animate;
9652
9653 if (animate === false) {
9654 canvas.draw();
9655 return;
9656 }
9657
9658 this.play();
9659 }
9660 }, {
9661 key: "play",
9662 value: function play() {
9663 var _this2 = this;
9664
9665 var canvas = this.canvas,
9666 animation = this.animation; // 执行动画
9667
9668 animation.abort();
9669 animation.play(canvas, function () {
9670 _this2.emit('animationEnd');
9671 });
9672 }
9673 }, {
9674 key: "render",
9675 value: function render() {
9676 var lastChildren = this.children,
9677 props = this.props;
9678 var nextChildren = props.children;
9679 renderChildren(this, nextChildren, lastChildren);
9680 this.draw();
9681 return null;
9682 }
9683 }, {
9684 key: "destroy",
9685 value: function destroy() {
9686 var canvas = this.canvas;
9687 canvas.destroy();
9688 }
9689 }, {
9690 key: "on",
9691 value: function on(type, listener) {
9692 this._ee.on(type, listener);
9693 }
9694 }, {
9695 key: "emit",
9696 value: function emit(type, event) {
9697 this._ee.emit(type, event);
9698 }
9699 }, {
9700 key: "off",
9701 value: function off(type, listener) {
9702 this._ee.off(type, listener);
9703 }
9704 }]);
9705
9706 return Canvas;
9707 }(Component);
9708
9709 var LayoutController = /*#__PURE__*/function () {
9710 function LayoutController() {
9711 _classCallCheck(this, LayoutController);
9712 }
9713
9714 _createClass(LayoutController, [{
9715 key: "getRectRange",
9716 value: function getRectRange(style) {
9717 var left = style.left,
9718 top = style.top,
9719 width = style.width,
9720 height = style.height,
9721 padding = style.padding;
9722
9723 var _padding = _slicedToArray(padding, 4),
9724 paddingTop = _padding[0],
9725 paddingRight = _padding[1],
9726 paddingBottom = _padding[2],
9727 paddingLeft = _padding[3];
9728
9729 return {
9730 left: left + paddingLeft,
9731 top: top + paddingTop,
9732 width: width - paddingLeft - paddingRight,
9733 height: height - paddingTop - paddingBottom
9734 };
9735 }
9736 }, {
9737 key: "create",
9738 value: function create(style) {
9739 var rectRange = this.getRectRange(style);
9740 var layout = new Layout(rectRange);
9741 this.layout = layout;
9742 return layout;
9743 }
9744 }, {
9745 key: "update",
9746 value: function update(style) {
9747 var rectRange = this.getRectRange(style);
9748 var layout = this.layout;
9749 layout.update(rectRange);
9750 return layout;
9751 }
9752 }]);
9753
9754 return LayoutController;
9755 }();
9756
9757 var superPropBase = createCommonjsModule(function (module) {
9758 function _superPropBase(object, property) {
9759 while (!Object.prototype.hasOwnProperty.call(object, property)) {
9760 object = getPrototypeOf(object);
9761 if (object === null) break;
9762 }
9763
9764 return object;
9765 }
9766
9767 module.exports = _superPropBase, module.exports.__esModule = true, module.exports["default"] = module.exports;
9768 });
9769
9770 var get$1 = createCommonjsModule(function (module) {
9771 function _get() {
9772 if (typeof Reflect !== "undefined" && Reflect.get) {
9773 module.exports = _get = Reflect.get.bind(), module.exports.__esModule = true, module.exports["default"] = module.exports;
9774 } else {
9775 module.exports = _get = function _get(target, property, receiver) {
9776 var base = superPropBase(target, property);
9777 if (!base) return;
9778 var desc = Object.getOwnPropertyDescriptor(base, property);
9779
9780 if (desc.get) {
9781 return desc.get.call(arguments.length < 3 ? target : receiver);
9782 }
9783
9784 return desc.value;
9785 }, module.exports.__esModule = true, module.exports["default"] = module.exports;
9786 }
9787
9788 return _get.apply(this, arguments);
9789 }
9790
9791 module.exports = _get, module.exports.__esModule = true, module.exports["default"] = module.exports;
9792 });
9793
9794 var _get$1 = /*@__PURE__*/getDefaultExportFromCjs(get$1);
9795
9796 function transposedRect(_ref) {
9797 var xMin = _ref.xMin,
9798 xMax = _ref.xMax,
9799 yMin = _ref.yMin,
9800 yMax = _ref.yMax;
9801 return {
9802 xMin: yMin,
9803 xMax: yMax,
9804 yMin: xMin,
9805 yMax: xMax
9806 };
9807 }
9808
9809 function _convertRect(_ref2) {
9810 var x = _ref2.x,
9811 y = _ref2.y,
9812 size = _ref2.size,
9813 y0 = _ref2.y0;
9814 var xMin;
9815 var xMax;
9816
9817 if (isArray(x)) {
9818 xMin = x[0];
9819 xMax = x[1];
9820 } else {
9821 xMin = x - size / 2;
9822 xMax = x + size / 2;
9823 }
9824
9825 var yMin;
9826 var yMax;
9827
9828 if (isArray(y)) {
9829 yMin = y[0];
9830 yMax = y[1];
9831 } else {
9832 yMin = Math.min(y0, y);
9833 yMax = Math.max(y0, y);
9834 }
9835
9836 return {
9837 xMin: xMin,
9838 xMax: xMax,
9839 yMin: yMin,
9840 yMax: yMax
9841 };
9842 }
9843 /**
9844 * 直角坐标系
9845 * convert相关的方法,涉及将标准坐标系映射到实际坐标系内
9846 * transform相关的方法,是仅将某一种关键点转换成另一种关键点 (比如将x/y/size/y0转换成yMin/yMax/..)
9847 */
9848
9849
9850 var Base = /*#__PURE__*/function (_Layout) {
9851 _inherits(Base, _Layout);
9852
9853 var _super = _createSuper(Base);
9854
9855 function Base(option) {
9856 var _this;
9857
9858 _classCallCheck(this, Base);
9859
9860 _this = _super.call(this, option); // x y 调换
9861
9862 _this.transposed = false; // x,y 的值域,在极坐标中对应的就是弧度和半径
9863
9864 _this.x = [0, 1];
9865 _this.y = [0, 1];
9866
9867 _this.update(option);
9868
9869 return _this;
9870 }
9871
9872 _createClass(Base, [{
9873 key: "update",
9874 value: function update(option) {
9875 _get$1(_getPrototypeOf(Base.prototype), "update", this).call(this, option);
9876
9877 var left = this.left,
9878 top = this.top,
9879 width = this.width,
9880 height = this.height;
9881 this.center = {
9882 x: left + width / 2,
9883 y: top + height / 2
9884 };
9885 return this;
9886 } // 是循环, 比如极坐标是以 2π 循环的
9887
9888 }, {
9889 key: "isCyclic",
9890 value: function isCyclic() {
9891 return false;
9892 }
9893 }, {
9894 key: "_zoomVal",
9895 value: function _zoomVal(val, func) {
9896 return isArray(val) ? val.map(function (v) {
9897 return func(v);
9898 }) : func(val);
9899 }
9900 /**
9901 * 把归一后的值映射到对应的定义域
9902 * @param point
9903 */
9904
9905 }, {
9906 key: "convert",
9907 value: function convert(point) {
9908 var transposed = this.transposed,
9909 x = this.x,
9910 y = this.y;
9911 var xDim = transposed ? 'y' : 'x';
9912 var yDim = transposed ? 'x' : 'y';
9913 var pointX = point[xDim];
9914 var pointY = point[yDim]; // 超出边界不绘制
9915
9916 if (pointX < 0 || pointX > 1 || pointY < 0 || pointY > 1) {
9917 return {
9918 x: NaN,
9919 y: NaN
9920 };
9921 }
9922
9923 return {
9924 x: this._zoomVal(point[xDim], function (v) {
9925 return x[0] + (x[1] - x[0]) * v;
9926 }),
9927 y: this._zoomVal(point[yDim], function (v) {
9928 return y[0] + (y[1] - y[0]) * v;
9929 })
9930 };
9931 }
9932 /**
9933 * convert 的反处理,把定义域的值,反处理到归一的值
9934 */
9935
9936 }, {
9937 key: "invert",
9938 value: function invert(point) {
9939 var _ref3;
9940
9941 var transposed = this.transposed,
9942 x = this.x,
9943 y = this.y;
9944 var xDim = transposed ? 'y' : 'x';
9945 var yDim = transposed ? 'x' : 'y';
9946 return _ref3 = {}, _defineProperty(_ref3, xDim, this._zoomVal(point.x, function (v) {
9947 return (v - x[0]) / (x[1] - x[0]);
9948 })), _defineProperty(_ref3, yDim, this._zoomVal(point.y, function (v) {
9949 return (v - y[0]) / (y[1] - y[0]);
9950 })), _ref3;
9951 }
9952 /**
9953 * 把归一化的值映射到 canvas 的坐标点
9954 * @param point
9955 * @returns
9956 */
9957
9958 }, {
9959 key: "convertPoint",
9960 value: function convertPoint(point) {
9961 return this.convert(point);
9962 }
9963 /**
9964 * 把canvas坐标的点位映射回归一的值
9965 */
9966
9967 }, {
9968 key: "invertPoint",
9969 value: function invertPoint(point) {
9970 return this.invert(point);
9971 } // 将标准坐标系下的矩形绘制关键点映射成实际绘制的坐标点
9972
9973 }, {
9974 key: "convertRect",
9975 value: function convertRect(rectPoint) {
9976 var xRange = this.x,
9977 yRange = this.y,
9978 transposed = this.transposed;
9979
9980 var _xRange = _slicedToArray(xRange, 2),
9981 xStart = _xRange[0],
9982 xEnd = _xRange[1];
9983
9984 var _yRange = _slicedToArray(yRange, 2),
9985 yStart = _yRange[0],
9986 yEnd = _yRange[1];
9987
9988 var rect = _convertRect(rectPoint);
9989
9990 var _ref4 = transposed ? transposedRect(rect) : rect,
9991 xMin = _ref4.xMin,
9992 xMax = _ref4.xMax,
9993 yMin = _ref4.yMin,
9994 yMax = _ref4.yMax;
9995
9996 var x0 = xStart + (xEnd - xStart) * xMin;
9997 var x1 = xStart + (xEnd - xStart) * xMax;
9998 var y0 = yStart + (yEnd - yStart) * yMin;
9999 var y1 = yStart + (yEnd - yStart) * yMax;
10000 return {
10001 xMin: Math.min(x0, x1),
10002 xMax: Math.max(x0, x1),
10003 yMin: Math.min(y0, y1),
10004 yMax: Math.max(y0, y1)
10005 };
10006 } // 将已经映射好的矩形绘制关键点转换成实际绘制的坐标点
10007
10008 }, {
10009 key: "transformToRect",
10010 value: function transformToRect(rectPoint) {
10011 var x = rectPoint.x,
10012 y = rectPoint.y,
10013 y0 = rectPoint.y0,
10014 size = rectPoint.size;
10015 var coordOrigin = this.convertPoint({
10016 x: 0,
10017 y: y0
10018 });
10019 var transposed = this.transposed;
10020 var _rectPoint = {
10021 size: size,
10022 x: transposed ? y : x,
10023 y: transposed ? x : y,
10024 y0: transposed ? coordOrigin.x : coordOrigin.y
10025 };
10026
10027 var rect = _convertRect(_rectPoint);
10028
10029 var _ref5 = transposed ? transposedRect(rect) : rect,
10030 xMin = _ref5.xMin,
10031 xMax = _ref5.xMax,
10032 yMin = _ref5.yMin,
10033 yMax = _ref5.yMax;
10034
10035 return {
10036 xMin: xMin,
10037 xMax: xMax,
10038 yMin: yMin,
10039 yMax: yMax
10040 };
10041 }
10042 }]);
10043
10044 return Base;
10045 }(Layout);
10046
10047 var Rect$2 = /*#__PURE__*/function (_Base) {
10048 _inherits(Rect, _Base);
10049
10050 var _super = _createSuper(Rect);
10051
10052 function Rect() {
10053 var _this;
10054
10055 _classCallCheck(this, Rect);
10056
10057 _this = _super.apply(this, arguments);
10058 _this.type = 'rect';
10059 return _this;
10060 }
10061
10062 _createClass(Rect, [{
10063 key: "update",
10064 value: function update(option) {
10065 _get$1(_getPrototypeOf(Rect.prototype), "update", this).call(this, option);
10066
10067 var left = this.left,
10068 top = this.top,
10069 right = this.right,
10070 bottom = this.bottom;
10071 var x = [left, right];
10072 var y = [bottom, top];
10073 this.x = x;
10074 this.y = y;
10075 return this;
10076 }
10077 }]);
10078
10079 return Rect;
10080 }(Base);
10081
10082 var Polar = /*#__PURE__*/function (_Base) {
10083 _inherits(Polar, _Base);
10084
10085 var _super = _createSuper(Polar);
10086
10087 function Polar() {
10088 var _this;
10089
10090 _classCallCheck(this, Polar);
10091
10092 _this = _super.apply(this, arguments);
10093 _this.type = 'polar';
10094 _this.isPolar = true;
10095 return _this;
10096 }
10097
10098 _createClass(Polar, [{
10099 key: "update",
10100 value: function update(option) {
10101 _get$1(_getPrototypeOf(Polar.prototype), "update", this).call(this, option);
10102
10103 if (!this.option) {
10104 this.option = option;
10105 }
10106
10107 var _this$option = this.option,
10108 _this$option$radius = _this$option.radius,
10109 radiusRatio = _this$option$radius === void 0 ? 1 : _this$option$radius,
10110 _this$option$innerRad = _this$option.innerRadius,
10111 innerRadiusRatio = _this$option$innerRad === void 0 ? 0 : _this$option$innerRad;
10112 var width = this.width,
10113 height = this.height,
10114 _this$startAngle = this.startAngle,
10115 startAngle = _this$startAngle === void 0 ? -Math.PI / 2 : _this$startAngle,
10116 _this$endAngle = this.endAngle,
10117 endAngle = _this$endAngle === void 0 ? Math.PI * 3 / 2 : _this$endAngle; // 半径取宽高的最小值
10118
10119 var radius = radiusRatio * (Math.min(width, height) / 2); // 极坐标下 x 表示弧度, y 代表 半径
10120
10121 var x = [startAngle, endAngle];
10122 var y = [innerRadiusRatio * radius, radius];
10123 this.x = x;
10124 this.y = y;
10125 this.startAngle = startAngle;
10126 this.endAngle = endAngle;
10127 this.radius = radius;
10128 this.innnerRadius = innerRadiusRatio * radius;
10129 return this;
10130 }
10131 }, {
10132 key: "isCyclic",
10133 value: function isCyclic() {
10134 var startAngle = this.startAngle,
10135 endAngle = this.endAngle;
10136
10137 if (endAngle - startAngle < Math.PI * 2) {
10138 return false;
10139 }
10140
10141 return true;
10142 }
10143 }, {
10144 key: "convertPoint",
10145 value: function convertPoint(point) {
10146 var center = this.center,
10147 transposed = this.transposed,
10148 x = this.x,
10149 y = this.y;
10150 var xDim = transposed ? 'y' : 'x';
10151 var yDim = transposed ? 'x' : 'y';
10152
10153 var _x = _slicedToArray(x, 2),
10154 xStart = _x[0],
10155 xEnd = _x[1];
10156
10157 var _y = _slicedToArray(y, 2),
10158 yStart = _y[0],
10159 yEnd = _y[1];
10160
10161 var angle = xStart + (xEnd - xStart) * point[xDim];
10162 var radius = yStart + (yEnd - yStart) * point[yDim];
10163 return {
10164 x: center.x + Math.cos(angle) * radius,
10165 y: center.y + Math.sin(angle) * radius
10166 };
10167 }
10168 }, {
10169 key: "invertPoint",
10170 value: function invertPoint(point) {
10171 var center = this.center,
10172 transposed = this.transposed,
10173 x = this.x,
10174 y = this.y;
10175 var xDim = transposed ? 'y' : 'x';
10176 var yDim = transposed ? 'x' : 'y';
10177
10178 var _x2 = _slicedToArray(x, 2),
10179 xStart = _x2[0],
10180 xEnd = _x2[1];
10181
10182 var _y2 = _slicedToArray(y, 2),
10183 yStart = _y2[0],
10184 yEnd = _y2[1];
10185
10186 var m = [1, 0, 0, 1, 0, 0];
10187 Matrix.rotate(m, m, xStart);
10188 var startV = [1, 0];
10189 Vector2.transformMat2d(startV, startV, m);
10190 startV = [startV[0], startV[1]];
10191 var pointV = [point.x - center.x, point.y - center.y];
10192
10193 if (Vector2.zero(pointV)) {
10194 return {
10195 x: 0,
10196 y: 0
10197 };
10198 }
10199
10200 var theta = Vector2.angleTo(startV, pointV, xEnd < xStart);
10201
10202 if (Math.abs(theta - Math.PI * 2) < 0.001) {
10203 theta = 0;
10204 }
10205
10206 var l = Vector2.length(pointV);
10207 var percentX = theta / (xEnd - xStart);
10208 percentX = xEnd - xStart > 0 ? percentX : -percentX;
10209 var percentY = (l - yStart) / (yEnd - yStart);
10210 var rst = {};
10211 rst[xDim] = percentX;
10212 rst[yDim] = percentY;
10213 return rst;
10214 }
10215 }]);
10216
10217 return Polar;
10218 }(Base);
10219
10220 var coordMap = {
10221 rect: Rect$2,
10222 polar: Polar
10223 };
10224
10225 var coordController = /*#__PURE__*/function () {
10226 function coordController() {
10227 _classCallCheck(this, coordController);
10228 }
10229
10230 _createClass(coordController, [{
10231 key: "getOption",
10232 value: function getOption(cfg) {
10233 if (isString(cfg)) {
10234 return {
10235 type: coordMap[cfg] || Rect$2
10236 };
10237 }
10238
10239 if (isFunction(cfg)) {
10240 return {
10241 type: cfg
10242 };
10243 }
10244
10245 var _ref = cfg || {},
10246 type = _ref.type;
10247
10248 return _objectSpread(_objectSpread({}, cfg), {}, {
10249 // 默认直角坐标系
10250 type: isFunction(type) ? type : coordMap[type] || Rect$2
10251 });
10252 }
10253 }, {
10254 key: "create",
10255 value: function create(cfg, layout) {
10256 var option = this.getOption(cfg);
10257 var type = option.type;
10258 var coord = new type(_objectSpread(_objectSpread({}, option), layout));
10259 this.coord = coord;
10260 return coord;
10261 }
10262 }, {
10263 key: "updateLayout",
10264 value: function updateLayout(layout) {
10265 this.coord.update(layout);
10266 }
10267 }, {
10268 key: "update",
10269 value: function update() {}
10270 }]);
10271
10272 return coordController;
10273 }();
10274
10275 var methodCache = {};
10276 /**
10277 * 获取计算 ticks 的方法
10278 * @param key 键值
10279 * @returns 计算 ticks 的方法
10280 */
10281 function getTickMethod(key) {
10282 return methodCache[key];
10283 }
10284 /**
10285 * 注册计算 ticks 的方法
10286 * @param key 键值
10287 * @param method 方法
10288 */
10289 function registerTickMethod(key, method) {
10290 methodCache[key] = method;
10291 }
10292
10293 var Scale = /** @class */ (function () {
10294 function Scale(cfg) {
10295 /**
10296 * 度量的类型
10297 */
10298 this.type = 'base';
10299 /**
10300 * 是否分类类型的度量
10301 */
10302 this.isCategory = false;
10303 /**
10304 * 是否线性度量,有linear, time 度量
10305 */
10306 this.isLinear = false;
10307 /**
10308 * 是否连续类型的度量,linear,time,log, pow, quantile, quantize 都支持
10309 */
10310 this.isContinuous = false;
10311 /**
10312 * 是否是常量的度量,传入和传出一致
10313 */
10314 this.isIdentity = false;
10315 this.values = [];
10316 this.range = [0, 1];
10317 this.ticks = [];
10318 this.__cfg__ = cfg;
10319 this.initCfg();
10320 this.init();
10321 }
10322 // 对于原始值的必要转换,如分类、时间字段需转换成数值,用transform/map命名可能更好
10323 Scale.prototype.translate = function (v) {
10324 return v;
10325 };
10326 /** 重新初始化 */
10327 Scale.prototype.change = function (cfg) {
10328 // 覆盖配置项,而不替代
10329 mix(this.__cfg__, cfg);
10330 this.init();
10331 };
10332 Scale.prototype.clone = function () {
10333 return this.constructor(this.__cfg__);
10334 };
10335 /** 获取坐标轴需要的ticks */
10336 Scale.prototype.getTicks = function () {
10337 var _this = this;
10338 return map(this.ticks, function (tick, idx) {
10339 if (isObject(tick)) {
10340 // 仅当符合Tick类型时才有意义
10341 return tick;
10342 }
10343 return {
10344 text: _this.getText(tick, idx),
10345 tickValue: tick,
10346 value: _this.scale(tick),
10347 };
10348 });
10349 };
10350 /** 获取Tick的格式化结果 */
10351 Scale.prototype.getText = function (value, key) {
10352 var formatter = this.formatter;
10353 var res = formatter ? formatter(value, key) : value;
10354 if (isNil(res) || !isFunction(res.toString)) {
10355 return '';
10356 }
10357 return res.toString();
10358 };
10359 // 获取配置项中的值,当前 scale 上的值可能会被修改
10360 Scale.prototype.getConfig = function (key) {
10361 return this.__cfg__[key];
10362 };
10363 // scale初始化
10364 Scale.prototype.init = function () {
10365 mix(this, this.__cfg__);
10366 this.setDomain();
10367 if (isEmpty(this.getConfig('ticks'))) {
10368 this.ticks = this.calculateTicks();
10369 }
10370 };
10371 // 子类上覆盖某些属性,不能直接在类上声明,否则会被覆盖
10372 Scale.prototype.initCfg = function () { };
10373 Scale.prototype.setDomain = function () { };
10374 Scale.prototype.calculateTicks = function () {
10375 var tickMethod = this.tickMethod;
10376 var ticks = [];
10377 if (isString(tickMethod)) {
10378 var method = getTickMethod(tickMethod);
10379 if (!method) {
10380 throw new Error('There is no method to to calculate ticks!');
10381 }
10382 ticks = method(this);
10383 }
10384 else if (isFunction(tickMethod)) {
10385 ticks = tickMethod(this);
10386 }
10387 return ticks;
10388 };
10389 // range 的最小值
10390 Scale.prototype.rangeMin = function () {
10391 return this.range[0];
10392 };
10393 // range 的最大值
10394 Scale.prototype.rangeMax = function () {
10395 return this.range[1];
10396 };
10397 /** 定义域转 0~1 */
10398 Scale.prototype.calcPercent = function (value, min, max) {
10399 if (isNumber(value)) {
10400 return (value - min) / (max - min);
10401 }
10402 return NaN;
10403 };
10404 /** 0~1转定义域 */
10405 Scale.prototype.calcValue = function (percent, min, max) {
10406 return min + percent * (max - min);
10407 };
10408 return Scale;
10409 }());
10410
10411 /**
10412 * 分类度量
10413 * @class
10414 */
10415 var Category = /** @class */ (function (_super) {
10416 __extends(Category, _super);
10417 function Category() {
10418 var _this = _super !== null && _super.apply(this, arguments) || this;
10419 _this.type = 'cat';
10420 _this.isCategory = true;
10421 return _this;
10422 }
10423 Category.prototype.buildIndexMap = function () {
10424 if (!this.translateIndexMap) {
10425 this.translateIndexMap = new Map();
10426 // 重新构建缓存
10427 for (var i = 0; i < this.values.length; i++) {
10428 this.translateIndexMap.set(this.values[i], i);
10429 }
10430 }
10431 };
10432 Category.prototype.translate = function (value) {
10433 // 按需构建 map
10434 this.buildIndexMap();
10435 // 找得到
10436 var idx = this.translateIndexMap.get(value);
10437 if (idx === undefined) {
10438 idx = isNumber(value) ? value : NaN;
10439 }
10440 return idx;
10441 };
10442 Category.prototype.scale = function (value) {
10443 var order = this.translate(value);
10444 // 分类数据允许 0.5 范围内调整
10445 // if (order < this.min - 0.5 || order > this.max + 0.5) {
10446 // return NaN;
10447 // }
10448 var percent = this.calcPercent(order, this.min, this.max);
10449 return this.calcValue(percent, this.rangeMin(), this.rangeMax());
10450 };
10451 Category.prototype.invert = function (scaledValue) {
10452 var domainRange = this.max - this.min;
10453 var percent = this.calcPercent(scaledValue, this.rangeMin(), this.rangeMax());
10454 var idx = Math.round(domainRange * percent) + this.min;
10455 if (idx < this.min || idx > this.max) {
10456 return NaN;
10457 }
10458 return this.values[idx];
10459 };
10460 Category.prototype.getText = function (value) {
10461 var args = [];
10462 for (var _i = 1; _i < arguments.length; _i++) {
10463 args[_i - 1] = arguments[_i];
10464 }
10465 var v = value;
10466 // value为index
10467 if (isNumber(value) && !this.values.includes(value)) {
10468 v = this.values[v];
10469 }
10470 return _super.prototype.getText.apply(this, __spreadArrays([v], args));
10471 };
10472 // 复写属性
10473 Category.prototype.initCfg = function () {
10474 this.tickMethod = 'cat';
10475 };
10476 // 设置 min, max
10477 Category.prototype.setDomain = function () {
10478 // 用户有可能设置 min
10479 if (isNil(this.getConfig('min'))) {
10480 this.min = 0;
10481 }
10482 if (isNil(this.getConfig('max'))) {
10483 var size = this.values.length;
10484 this.max = size > 1 ? size - 1 : size;
10485 }
10486 // scale.init 的时候清除缓存
10487 if (this.translateIndexMap) {
10488 this.translateIndexMap = undefined;
10489 }
10490 };
10491 return Category;
10492 }(Scale));
10493
10494 var token = /d{1,4}|M{1,4}|YY(?:YY)?|S{1,3}|Do|ZZ|Z|([HhMsDm])\1?|[aA]|"[^"]*"|'[^']*'/g;
10495 var twoDigitsOptional = "\\d\\d?";
10496 var twoDigits = "\\d\\d";
10497 var threeDigits = "\\d{3}";
10498 var fourDigits = "\\d{4}";
10499 var word = "[^\\s]+";
10500 var literal = /\[([^]*?)\]/gm;
10501 function shorten(arr, sLen) {
10502 var newArr = [];
10503 for (var i = 0, len = arr.length; i < len; i++) {
10504 newArr.push(arr[i].substr(0, sLen));
10505 }
10506 return newArr;
10507 }
10508 var monthUpdate = function (arrName) { return function (v, i18n) {
10509 var lowerCaseArr = i18n[arrName].map(function (v) { return v.toLowerCase(); });
10510 var index = lowerCaseArr.indexOf(v.toLowerCase());
10511 if (index > -1) {
10512 return index;
10513 }
10514 return null;
10515 }; };
10516 function assign(origObj) {
10517 var args = [];
10518 for (var _i = 1; _i < arguments.length; _i++) {
10519 args[_i - 1] = arguments[_i];
10520 }
10521 for (var _a = 0, args_1 = args; _a < args_1.length; _a++) {
10522 var obj = args_1[_a];
10523 for (var key in obj) {
10524 // @ts-ignore ex
10525 origObj[key] = obj[key];
10526 }
10527 }
10528 return origObj;
10529 }
10530 var dayNames = [
10531 "Sunday",
10532 "Monday",
10533 "Tuesday",
10534 "Wednesday",
10535 "Thursday",
10536 "Friday",
10537 "Saturday"
10538 ];
10539 var monthNames = [
10540 "January",
10541 "February",
10542 "March",
10543 "April",
10544 "May",
10545 "June",
10546 "July",
10547 "August",
10548 "September",
10549 "October",
10550 "November",
10551 "December"
10552 ];
10553 var monthNamesShort = shorten(monthNames, 3);
10554 var dayNamesShort = shorten(dayNames, 3);
10555 var defaultI18n = {
10556 dayNamesShort: dayNamesShort,
10557 dayNames: dayNames,
10558 monthNamesShort: monthNamesShort,
10559 monthNames: monthNames,
10560 amPm: ["am", "pm"],
10561 DoFn: function (dayOfMonth) {
10562 return (dayOfMonth +
10563 ["th", "st", "nd", "rd"][dayOfMonth % 10 > 3
10564 ? 0
10565 : ((dayOfMonth - (dayOfMonth % 10) !== 10 ? 1 : 0) * dayOfMonth) % 10]);
10566 }
10567 };
10568 var globalI18n = assign({}, defaultI18n);
10569 var setGlobalDateI18n = function (i18n) {
10570 return (globalI18n = assign(globalI18n, i18n));
10571 };
10572 var regexEscape = function (str) {
10573 return str.replace(/[|\\{()[^$+*?.-]/g, "\\$&");
10574 };
10575 var pad = function (val, len) {
10576 if (len === void 0) { len = 2; }
10577 val = String(val);
10578 while (val.length < len) {
10579 val = "0" + val;
10580 }
10581 return val;
10582 };
10583 var formatFlags = {
10584 D: function (dateObj) { return String(dateObj.getDate()); },
10585 DD: function (dateObj) { return pad(dateObj.getDate()); },
10586 Do: function (dateObj, i18n) {
10587 return i18n.DoFn(dateObj.getDate());
10588 },
10589 d: function (dateObj) { return String(dateObj.getDay()); },
10590 dd: function (dateObj) { return pad(dateObj.getDay()); },
10591 ddd: function (dateObj, i18n) {
10592 return i18n.dayNamesShort[dateObj.getDay()];
10593 },
10594 dddd: function (dateObj, i18n) {
10595 return i18n.dayNames[dateObj.getDay()];
10596 },
10597 M: function (dateObj) { return String(dateObj.getMonth() + 1); },
10598 MM: function (dateObj) { return pad(dateObj.getMonth() + 1); },
10599 MMM: function (dateObj, i18n) {
10600 return i18n.monthNamesShort[dateObj.getMonth()];
10601 },
10602 MMMM: function (dateObj, i18n) {
10603 return i18n.monthNames[dateObj.getMonth()];
10604 },
10605 YY: function (dateObj) {
10606 return pad(String(dateObj.getFullYear()), 4).substr(2);
10607 },
10608 YYYY: function (dateObj) { return pad(dateObj.getFullYear(), 4); },
10609 h: function (dateObj) { return String(dateObj.getHours() % 12 || 12); },
10610 hh: function (dateObj) { return pad(dateObj.getHours() % 12 || 12); },
10611 H: function (dateObj) { return String(dateObj.getHours()); },
10612 HH: function (dateObj) { return pad(dateObj.getHours()); },
10613 m: function (dateObj) { return String(dateObj.getMinutes()); },
10614 mm: function (dateObj) { return pad(dateObj.getMinutes()); },
10615 s: function (dateObj) { return String(dateObj.getSeconds()); },
10616 ss: function (dateObj) { return pad(dateObj.getSeconds()); },
10617 S: function (dateObj) {
10618 return String(Math.round(dateObj.getMilliseconds() / 100));
10619 },
10620 SS: function (dateObj) {
10621 return pad(Math.round(dateObj.getMilliseconds() / 10), 2);
10622 },
10623 SSS: function (dateObj) { return pad(dateObj.getMilliseconds(), 3); },
10624 a: function (dateObj, i18n) {
10625 return dateObj.getHours() < 12 ? i18n.amPm[0] : i18n.amPm[1];
10626 },
10627 A: function (dateObj, i18n) {
10628 return dateObj.getHours() < 12
10629 ? i18n.amPm[0].toUpperCase()
10630 : i18n.amPm[1].toUpperCase();
10631 },
10632 ZZ: function (dateObj) {
10633 var offset = dateObj.getTimezoneOffset();
10634 return ((offset > 0 ? "-" : "+") +
10635 pad(Math.floor(Math.abs(offset) / 60) * 100 + (Math.abs(offset) % 60), 4));
10636 },
10637 Z: function (dateObj) {
10638 var offset = dateObj.getTimezoneOffset();
10639 return ((offset > 0 ? "-" : "+") +
10640 pad(Math.floor(Math.abs(offset) / 60), 2) +
10641 ":" +
10642 pad(Math.abs(offset) % 60, 2));
10643 }
10644 };
10645 var monthParse = function (v) { return +v - 1; };
10646 var emptyDigits = [null, twoDigitsOptional];
10647 var emptyWord = [null, word];
10648 var amPm = [
10649 "isPm",
10650 word,
10651 function (v, i18n) {
10652 var val = v.toLowerCase();
10653 if (val === i18n.amPm[0]) {
10654 return 0;
10655 }
10656 else if (val === i18n.amPm[1]) {
10657 return 1;
10658 }
10659 return null;
10660 }
10661 ];
10662 var timezoneOffset = [
10663 "timezoneOffset",
10664 "[^\\s]*?[\\+\\-]\\d\\d:?\\d\\d|[^\\s]*?Z?",
10665 function (v) {
10666 var parts = (v + "").match(/([+-]|\d\d)/gi);
10667 if (parts) {
10668 var minutes = +parts[1] * 60 + parseInt(parts[2], 10);
10669 return parts[0] === "+" ? minutes : -minutes;
10670 }
10671 return 0;
10672 }
10673 ];
10674 var parseFlags = {
10675 D: ["day", twoDigitsOptional],
10676 DD: ["day", twoDigits],
10677 Do: ["day", twoDigitsOptional + word, function (v) { return parseInt(v, 10); }],
10678 M: ["month", twoDigitsOptional, monthParse],
10679 MM: ["month", twoDigits, monthParse],
10680 YY: [
10681 "year",
10682 twoDigits,
10683 function (v) {
10684 var now = new Date();
10685 var cent = +("" + now.getFullYear()).substr(0, 2);
10686 return +("" + (+v > 68 ? cent - 1 : cent) + v);
10687 }
10688 ],
10689 h: ["hour", twoDigitsOptional, undefined, "isPm"],
10690 hh: ["hour", twoDigits, undefined, "isPm"],
10691 H: ["hour", twoDigitsOptional],
10692 HH: ["hour", twoDigits],
10693 m: ["minute", twoDigitsOptional],
10694 mm: ["minute", twoDigits],
10695 s: ["second", twoDigitsOptional],
10696 ss: ["second", twoDigits],
10697 YYYY: ["year", fourDigits],
10698 S: ["millisecond", "\\d", function (v) { return +v * 100; }],
10699 SS: ["millisecond", twoDigits, function (v) { return +v * 10; }],
10700 SSS: ["millisecond", threeDigits],
10701 d: emptyDigits,
10702 dd: emptyDigits,
10703 ddd: emptyWord,
10704 dddd: emptyWord,
10705 MMM: ["month", word, monthUpdate("monthNamesShort")],
10706 MMMM: ["month", word, monthUpdate("monthNames")],
10707 a: amPm,
10708 A: amPm,
10709 ZZ: timezoneOffset,
10710 Z: timezoneOffset
10711 };
10712 // Some common format strings
10713 var globalMasks = {
10714 default: "ddd MMM DD YYYY HH:mm:ss",
10715 shortDate: "M/D/YY",
10716 mediumDate: "MMM D, YYYY",
10717 longDate: "MMMM D, YYYY",
10718 fullDate: "dddd, MMMM D, YYYY",
10719 isoDate: "YYYY-MM-DD",
10720 isoDateTime: "YYYY-MM-DDTHH:mm:ssZ",
10721 shortTime: "HH:mm",
10722 mediumTime: "HH:mm:ss",
10723 longTime: "HH:mm:ss.SSS"
10724 };
10725 var setGlobalDateMasks = function (masks) { return assign(globalMasks, masks); };
10726 /***
10727 * Format a date
10728 * @method format
10729 * @param {Date|number} dateObj
10730 * @param {string} mask Format of the date, i.e. 'mm-dd-yy' or 'shortDate'
10731 * @returns {string} Formatted date string
10732 */
10733 var format = function (dateObj, mask, i18n) {
10734 if (mask === void 0) { mask = globalMasks["default"]; }
10735 if (i18n === void 0) { i18n = {}; }
10736 if (typeof dateObj === "number") {
10737 dateObj = new Date(dateObj);
10738 }
10739 if (Object.prototype.toString.call(dateObj) !== "[object Date]" ||
10740 isNaN(dateObj.getTime())) {
10741 throw new Error("Invalid Date pass to format");
10742 }
10743 mask = globalMasks[mask] || mask;
10744 var literals = [];
10745 // Make literals inactive by replacing them with @@@
10746 mask = mask.replace(literal, function ($0, $1) {
10747 literals.push($1);
10748 return "@@@";
10749 });
10750 var combinedI18nSettings = assign(assign({}, globalI18n), i18n);
10751 // Apply formatting rules
10752 mask = mask.replace(token, function ($0) {
10753 return formatFlags[$0](dateObj, combinedI18nSettings);
10754 });
10755 // Inline literal values back into the formatted value
10756 return mask.replace(/@@@/g, function () { return literals.shift(); });
10757 };
10758 /**
10759 * Parse a date string into a Javascript Date object /
10760 * @method parse
10761 * @param {string} dateStr Date string
10762 * @param {string} format Date parse format
10763 * @param {i18n} I18nSettingsOptional Full or subset of I18N settings
10764 * @returns {Date|null} Returns Date object. Returns null what date string is invalid or doesn't match format
10765 */
10766 function parse(dateStr, format, i18n) {
10767 if (i18n === void 0) { i18n = {}; }
10768 if (typeof format !== "string") {
10769 throw new Error("Invalid format in fecha parse");
10770 }
10771 // Check to see if the format is actually a mask
10772 format = globalMasks[format] || format;
10773 // Avoid regular expression denial of service, fail early for really long strings
10774 // https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS
10775 if (dateStr.length > 1000) {
10776 return null;
10777 }
10778 // Default to the beginning of the year.
10779 var today = new Date();
10780 var dateInfo = {
10781 year: today.getFullYear(),
10782 month: 0,
10783 day: 1,
10784 hour: 0,
10785 minute: 0,
10786 second: 0,
10787 millisecond: 0,
10788 isPm: null,
10789 timezoneOffset: null
10790 };
10791 var parseInfo = [];
10792 var literals = [];
10793 // Replace all the literals with @@@. Hopefully a string that won't exist in the format
10794 var newFormat = format.replace(literal, function ($0, $1) {
10795 literals.push(regexEscape($1));
10796 return "@@@";
10797 });
10798 var specifiedFields = {};
10799 var requiredFields = {};
10800 // Change every token that we find into the correct regex
10801 newFormat = regexEscape(newFormat).replace(token, function ($0) {
10802 var info = parseFlags[$0];
10803 var field = info[0], regex = info[1], requiredField = info[3];
10804 // Check if the person has specified the same field twice. This will lead to confusing results.
10805 if (specifiedFields[field]) {
10806 throw new Error("Invalid format. " + field + " specified twice in format");
10807 }
10808 specifiedFields[field] = true;
10809 // Check if there are any required fields. For instance, 12 hour time requires AM/PM specified
10810 if (requiredField) {
10811 requiredFields[requiredField] = true;
10812 }
10813 parseInfo.push(info);
10814 return "(" + regex + ")";
10815 });
10816 // Check all the required fields are present
10817 Object.keys(requiredFields).forEach(function (field) {
10818 if (!specifiedFields[field]) {
10819 throw new Error("Invalid format. " + field + " is required in specified format");
10820 }
10821 });
10822 // Add back all the literals after
10823 newFormat = newFormat.replace(/@@@/g, function () { return literals.shift(); });
10824 // Check if the date string matches the format. If it doesn't return null
10825 var matches = dateStr.match(new RegExp(newFormat, "i"));
10826 if (!matches) {
10827 return null;
10828 }
10829 var combinedI18nSettings = assign(assign({}, globalI18n), i18n);
10830 // For each match, call the parser function for that date part
10831 for (var i = 1; i < matches.length; i++) {
10832 var _a = parseInfo[i - 1], field = _a[0], parser = _a[2];
10833 var value = parser
10834 ? parser(matches[i], combinedI18nSettings)
10835 : +matches[i];
10836 // If the parser can't make sense of the value, return null
10837 if (value == null) {
10838 return null;
10839 }
10840 dateInfo[field] = value;
10841 }
10842 if (dateInfo.isPm === 1 && dateInfo.hour != null && +dateInfo.hour !== 12) {
10843 dateInfo.hour = +dateInfo.hour + 12;
10844 }
10845 else if (dateInfo.isPm === 0 && +dateInfo.hour === 12) {
10846 dateInfo.hour = 0;
10847 }
10848 var dateTZ;
10849 if (dateInfo.timezoneOffset == null) {
10850 dateTZ = new Date(dateInfo.year, dateInfo.month, dateInfo.day, dateInfo.hour, dateInfo.minute, dateInfo.second, dateInfo.millisecond);
10851 var validateFields = [
10852 ["month", "getMonth"],
10853 ["day", "getDate"],
10854 ["hour", "getHours"],
10855 ["minute", "getMinutes"],
10856 ["second", "getSeconds"]
10857 ];
10858 for (var i = 0, len = validateFields.length; i < len; i++) {
10859 // Check to make sure the date field is within the allowed range. Javascript dates allows values
10860 // outside the allowed range. If the values don't match the value was invalid
10861 if (specifiedFields[validateFields[i][0]] &&
10862 dateInfo[validateFields[i][0]] !== dateTZ[validateFields[i][1]]()) {
10863 return null;
10864 }
10865 }
10866 }
10867 else {
10868 dateTZ = new Date(Date.UTC(dateInfo.year, dateInfo.month, dateInfo.day, dateInfo.hour, dateInfo.minute - dateInfo.timezoneOffset, dateInfo.second, dateInfo.millisecond));
10869 // We can't validate dates in another timezone unfortunately. Do a basic check instead
10870 if (dateInfo.month > 11 ||
10871 dateInfo.month < 0 ||
10872 dateInfo.day > 31 ||
10873 dateInfo.day < 1 ||
10874 dateInfo.hour > 23 ||
10875 dateInfo.hour < 0 ||
10876 dateInfo.minute > 59 ||
10877 dateInfo.minute < 0 ||
10878 dateInfo.second > 59 ||
10879 dateInfo.second < 0) {
10880 return null;
10881 }
10882 }
10883 // Don't allow invalid dates
10884 return dateTZ;
10885 }
10886 var fecha = {
10887 format: format,
10888 parse: parse,
10889 defaultI18n: defaultI18n,
10890 setGlobalDateI18n: setGlobalDateI18n,
10891 setGlobalDateMasks: setGlobalDateMasks
10892 };
10893
10894 var fecha1 = /*#__PURE__*/Object.freeze({
10895 __proto__: null,
10896 'default': fecha,
10897 assign: assign,
10898 format: format,
10899 parse: parse,
10900 defaultI18n: defaultI18n,
10901 setGlobalDateI18n: setGlobalDateI18n,
10902 setGlobalDateMasks: setGlobalDateMasks
10903 });
10904
10905 /**
10906 * 二分右侧查找
10907 * https://github.com/d3/d3-array/blob/master/src/bisector.js
10908 */
10909 function bisector (getter) {
10910 /**
10911 * x: 目标值
10912 * lo: 起始位置
10913 * hi: 结束位置
10914 */
10915 return function (a, x, _lo, _hi) {
10916 var lo = isNil(_lo) ? 0 : _lo;
10917 var hi = isNil(_hi) ? a.length : _hi;
10918 while (lo < hi) {
10919 var mid = (lo + hi) >>> 1;
10920 if (getter(a[mid]) > x) {
10921 hi = mid;
10922 }
10923 else {
10924 lo = mid + 1;
10925 }
10926 }
10927 return lo;
10928 };
10929 }
10930
10931 var FORMAT_METHOD = 'format';
10932 function timeFormat(time, mask) {
10933 var method = fecha1[FORMAT_METHOD] || fecha[FORMAT_METHOD];
10934 return method(time, mask);
10935 }
10936 /**
10937 * 转换成时间戳
10938 * @param value 时间值
10939 */
10940 function toTimeStamp$1(value) {
10941 if (isString(value)) {
10942 if (value.indexOf('T') > 0) {
10943 value = new Date(value).getTime();
10944 }
10945 else {
10946 // new Date('2010/01/10') 和 new Date('2010-01-10') 的差别在于:
10947 // 如果仅有年月日时,前者是带有时区的: Fri Jan 10 2020 02:40:13 GMT+0800 (中国标准时间)
10948 // 后者会格式化成 Sun Jan 10 2010 08:00:00 GMT+0800 (中国标准时间)
10949 value = new Date(value.replace(/-/gi, '/')).getTime();
10950 }
10951 }
10952 if (isDate(value)) {
10953 value = value.getTime();
10954 }
10955 return value;
10956 }
10957 var SECOND = 1000;
10958 var MINUTE = 60 * SECOND;
10959 var HOUR = 60 * MINUTE;
10960 var DAY = 24 * HOUR;
10961 var MONTH = DAY * 31;
10962 var YEAR = DAY * 365;
10963 var intervals = [
10964 ['HH:mm:ss', SECOND],
10965 ['HH:mm:ss', SECOND * 10],
10966 ['HH:mm:ss', SECOND * 30],
10967 ['HH:mm', MINUTE],
10968 ['HH:mm', MINUTE * 10],
10969 ['HH:mm', MINUTE * 30],
10970 ['HH', HOUR],
10971 ['HH', HOUR * 6],
10972 ['HH', HOUR * 12],
10973 ['YYYY-MM-DD', DAY],
10974 ['YYYY-MM-DD', DAY * 4],
10975 ['YYYY-WW', DAY * 7],
10976 ['YYYY-MM', MONTH],
10977 ['YYYY-MM', MONTH * 4],
10978 ['YYYY-MM', MONTH * 6],
10979 ['YYYY', DAY * 380],
10980 ];
10981 function getTickInterval(min, max, tickCount) {
10982 var target = (max - min) / tickCount;
10983 var idx = bisector(function (o) { return o[1]; })(intervals, target) - 1;
10984 var interval = intervals[idx];
10985 if (idx < 0) {
10986 interval = intervals[0];
10987 }
10988 else if (idx >= intervals.length) {
10989 interval = last(intervals);
10990 }
10991 return interval;
10992 }
10993
10994 /**
10995 * 时间分类度量
10996 * @class
10997 */
10998 var TimeCat = /** @class */ (function (_super) {
10999 __extends(TimeCat, _super);
11000 function TimeCat() {
11001 var _this = _super !== null && _super.apply(this, arguments) || this;
11002 _this.type = 'timeCat';
11003 return _this;
11004 }
11005 /**
11006 * @override
11007 */
11008 TimeCat.prototype.translate = function (value) {
11009 value = toTimeStamp$1(value);
11010 var index = this.values.indexOf(value);
11011 if (index === -1) {
11012 if (isNumber(value) && value < this.values.length) {
11013 index = value;
11014 }
11015 else {
11016 index = NaN;
11017 }
11018 }
11019 return index;
11020 };
11021 /**
11022 * 由于时间类型数据需要转换一下,所以复写 getText
11023 * @override
11024 */
11025 TimeCat.prototype.getText = function (value, tickIndex) {
11026 var index = this.translate(value);
11027 if (index > -1) {
11028 var result = this.values[index];
11029 var formatter = this.formatter;
11030 result = formatter ? formatter(result, tickIndex) : timeFormat(result, this.mask);
11031 return result;
11032 }
11033 return value;
11034 };
11035 TimeCat.prototype.initCfg = function () {
11036 this.tickMethod = 'time-cat';
11037 this.mask = 'YYYY-MM-DD';
11038 this.tickCount = 7; // 一般时间数据会显示 7, 14, 30 天的数字
11039 };
11040 TimeCat.prototype.setDomain = function () {
11041 var values = this.values;
11042 // 针对时间分类类型,会将时间统一转换为时间戳
11043 each(values, function (v, i) {
11044 values[i] = toTimeStamp$1(v);
11045 });
11046 values.sort(function (v1, v2) {
11047 return v1 - v2;
11048 });
11049 _super.prototype.setDomain.call(this);
11050 };
11051 return TimeCat;
11052 }(Category));
11053
11054 /**
11055 * 连续度量的基类
11056 * @class
11057 */
11058 var Continuous = /** @class */ (function (_super) {
11059 __extends(Continuous, _super);
11060 function Continuous() {
11061 var _this = _super !== null && _super.apply(this, arguments) || this;
11062 _this.isContinuous = true;
11063 return _this;
11064 }
11065 Continuous.prototype.scale = function (value) {
11066 if (isNil(value)) {
11067 return NaN;
11068 }
11069 var rangeMin = this.rangeMin();
11070 var rangeMax = this.rangeMax();
11071 var max = this.max;
11072 var min = this.min;
11073 if (max === min) {
11074 return rangeMin;
11075 }
11076 var percent = this.getScalePercent(value);
11077 return rangeMin + percent * (rangeMax - rangeMin);
11078 };
11079 Continuous.prototype.init = function () {
11080 _super.prototype.init.call(this);
11081 // init 完成后保证 min, max 包含 ticks 的范围
11082 var ticks = this.ticks;
11083 var firstTick = head(ticks);
11084 var lastTick = last(ticks);
11085 if (firstTick < this.min) {
11086 this.min = firstTick;
11087 }
11088 if (lastTick > this.max) {
11089 this.max = lastTick;
11090 }
11091 // strict-limit 方式
11092 if (!isNil(this.minLimit)) {
11093 this.min = firstTick;
11094 }
11095 if (!isNil(this.maxLimit)) {
11096 this.max = lastTick;
11097 }
11098 };
11099 Continuous.prototype.setDomain = function () {
11100 var _a = getRange(this.values), min = _a.min, max = _a.max;
11101 if (isNil(this.min)) {
11102 this.min = min;
11103 }
11104 if (isNil(this.max)) {
11105 this.max = max;
11106 }
11107 if (this.min > this.max) {
11108 this.min = min;
11109 this.max = max;
11110 }
11111 };
11112 Continuous.prototype.calculateTicks = function () {
11113 var _this = this;
11114 var ticks = _super.prototype.calculateTicks.call(this);
11115 if (!this.nice) {
11116 ticks = filter(ticks, function (tick) {
11117 return tick >= _this.min && tick <= _this.max;
11118 });
11119 }
11120 return ticks;
11121 };
11122 // 计算原始值值占的百分比
11123 Continuous.prototype.getScalePercent = function (value) {
11124 var max = this.max;
11125 var min = this.min;
11126 return (value - min) / (max - min);
11127 };
11128 Continuous.prototype.getInvertPercent = function (value) {
11129 return (value - this.rangeMin()) / (this.rangeMax() - this.rangeMin());
11130 };
11131 return Continuous;
11132 }(Scale));
11133
11134 /**
11135 * 线性度量
11136 * @class
11137 */
11138 var Linear = /** @class */ (function (_super) {
11139 __extends(Linear, _super);
11140 function Linear() {
11141 var _this = _super !== null && _super.apply(this, arguments) || this;
11142 _this.type = 'linear';
11143 _this.isLinear = true;
11144 return _this;
11145 }
11146 Linear.prototype.invert = function (value) {
11147 var percent = this.getInvertPercent(value);
11148 return this.min + percent * (this.max - this.min);
11149 };
11150 Linear.prototype.initCfg = function () {
11151 this.tickMethod = 'wilkinson-extended';
11152 this.nice = false;
11153 };
11154 return Linear;
11155 }(Continuous));
11156
11157 // 求以a为次幂,结果为b的基数,如 x^^a = b;求x
11158 // 虽然数学上 b 不支持负数,但是这里需要支持 负数
11159 function calBase(a, b) {
11160 var e = Math.E;
11161 var value;
11162 if (b >= 0) {
11163 value = Math.pow(e, Math.log(b) / a); // 使用换底公式求底
11164 }
11165 else {
11166 value = Math.pow(e, Math.log(-b) / a) * -1; // 使用换底公式求底
11167 }
11168 return value;
11169 }
11170 function log(a, b) {
11171 if (a === 1) {
11172 return 1;
11173 }
11174 return Math.log(b) / Math.log(a);
11175 }
11176 function getLogPositiveMin(values, base, max) {
11177 if (isNil(max)) {
11178 max = Math.max.apply(null, values);
11179 }
11180 var positiveMin = max;
11181 each(values, function (value) {
11182 if (value > 0 && value < positiveMin) {
11183 positiveMin = value;
11184 }
11185 });
11186 if (positiveMin === max) {
11187 positiveMin = max / base;
11188 }
11189 if (positiveMin > 1) {
11190 positiveMin = 1;
11191 }
11192 return positiveMin;
11193 }
11194
11195 /**
11196 * Log 度量,处理非均匀分布
11197 */
11198 var Log = /** @class */ (function (_super) {
11199 __extends(Log, _super);
11200 function Log() {
11201 var _this = _super !== null && _super.apply(this, arguments) || this;
11202 _this.type = 'log';
11203 return _this;
11204 }
11205 /**
11206 * @override
11207 */
11208 Log.prototype.invert = function (value) {
11209 var base = this.base;
11210 var max = log(base, this.max);
11211 var rangeMin = this.rangeMin();
11212 var range = this.rangeMax() - rangeMin;
11213 var min;
11214 var positiveMin = this.positiveMin;
11215 if (positiveMin) {
11216 if (value === 0) {
11217 return 0;
11218 }
11219 min = log(base, positiveMin / base);
11220 var appendPercent = (1 / (max - min)) * range; // 0 到 positiveMin的占比
11221 if (value < appendPercent) {
11222 // 落到 0 - positiveMin 之间
11223 return (value / appendPercent) * positiveMin;
11224 }
11225 }
11226 else {
11227 min = log(base, this.min);
11228 }
11229 var percent = (value - rangeMin) / range;
11230 var tmp = percent * (max - min) + min;
11231 return Math.pow(base, tmp);
11232 };
11233 Log.prototype.initCfg = function () {
11234 this.tickMethod = 'log';
11235 this.base = 10;
11236 this.tickCount = 6;
11237 this.nice = true;
11238 };
11239 // 设置
11240 Log.prototype.setDomain = function () {
11241 _super.prototype.setDomain.call(this);
11242 var min = this.min;
11243 if (min < 0) {
11244 throw new Error('When you use log scale, the minimum value must be greater than zero!');
11245 }
11246 if (min === 0) {
11247 this.positiveMin = getLogPositiveMin(this.values, this.base, this.max);
11248 }
11249 };
11250 // 根据当前值获取占比
11251 Log.prototype.getScalePercent = function (value) {
11252 var max = this.max;
11253 var min = this.min;
11254 if (max === min) {
11255 return 0;
11256 }
11257 // 如果值小于等于0,则按照0处理
11258 if (value <= 0) {
11259 return 0;
11260 }
11261 var base = this.base;
11262 var positiveMin = this.positiveMin;
11263 // 如果min == 0, 则根据比0大的最小值,计算比例关系。这个最小值作为坐标轴上的第二个tick,第一个是0但是不显示
11264 if (positiveMin) {
11265 min = (positiveMin * 1) / base;
11266 }
11267 var percent;
11268 // 如果数值小于次小值,那么就计算 value / 次小值 占整体的比例
11269 if (value < positiveMin) {
11270 percent = value / positiveMin / (log(base, max) - log(base, min));
11271 }
11272 else {
11273 percent = (log(base, value) - log(base, min)) / (log(base, max) - log(base, min));
11274 }
11275 return percent;
11276 };
11277 return Log;
11278 }(Continuous));
11279
11280 /**
11281 * Pow 度量,处理非均匀分布
11282 */
11283 var Pow = /** @class */ (function (_super) {
11284 __extends(Pow, _super);
11285 function Pow() {
11286 var _this = _super !== null && _super.apply(this, arguments) || this;
11287 _this.type = 'pow';
11288 return _this;
11289 }
11290 /**
11291 * @override
11292 */
11293 Pow.prototype.invert = function (value) {
11294 var percent = this.getInvertPercent(value);
11295 var exponent = this.exponent;
11296 var max = calBase(exponent, this.max);
11297 var min = calBase(exponent, this.min);
11298 var tmp = percent * (max - min) + min;
11299 var factor = tmp >= 0 ? 1 : -1;
11300 return Math.pow(tmp, exponent) * factor;
11301 };
11302 Pow.prototype.initCfg = function () {
11303 this.tickMethod = 'pow';
11304 this.exponent = 2;
11305 this.tickCount = 5;
11306 this.nice = true;
11307 };
11308 // 获取度量计算时,value占的定义域百分比
11309 Pow.prototype.getScalePercent = function (value) {
11310 var max = this.max;
11311 var min = this.min;
11312 if (max === min) {
11313 return 0;
11314 }
11315 var exponent = this.exponent;
11316 var percent = (calBase(exponent, value) - calBase(exponent, min)) / (calBase(exponent, max) - calBase(exponent, min));
11317 return percent;
11318 };
11319 return Pow;
11320 }(Continuous));
11321
11322 /**
11323 * 时间度量
11324 * @class
11325 */
11326 var Time = /** @class */ (function (_super) {
11327 __extends(Time, _super);
11328 function Time() {
11329 var _this = _super !== null && _super.apply(this, arguments) || this;
11330 _this.type = 'time';
11331 return _this;
11332 }
11333 /**
11334 * @override
11335 */
11336 Time.prototype.getText = function (value, index) {
11337 var numberValue = this.translate(value);
11338 var formatter = this.formatter;
11339 return formatter ? formatter(numberValue, index) : timeFormat(numberValue, this.mask);
11340 };
11341 /**
11342 * @override
11343 */
11344 Time.prototype.scale = function (value) {
11345 var v = value;
11346 if (isString(v) || isDate(v)) {
11347 v = this.translate(v);
11348 }
11349 return _super.prototype.scale.call(this, v);
11350 };
11351 /**
11352 * 将时间转换成数字
11353 * @override
11354 */
11355 Time.prototype.translate = function (v) {
11356 return toTimeStamp$1(v);
11357 };
11358 Time.prototype.initCfg = function () {
11359 this.tickMethod = 'time-pretty';
11360 this.mask = 'YYYY-MM-DD';
11361 this.tickCount = 7;
11362 this.nice = false;
11363 };
11364 Time.prototype.setDomain = function () {
11365 var values = this.values;
11366 // 是否设置了 min, max,而不是直接取 this.min, this.max
11367 var minConfig = this.getConfig('min');
11368 var maxConfig = this.getConfig('max');
11369 // 如果设置了 min,max 则转换成时间戳
11370 if (!isNil(minConfig) || !isNumber(minConfig)) {
11371 this.min = this.translate(this.min);
11372 }
11373 if (!isNil(maxConfig) || !isNumber(maxConfig)) {
11374 this.max = this.translate(this.max);
11375 }
11376 // 没有设置 min, max 时
11377 if (values && values.length) {
11378 // 重新计算最大最小值
11379 var timeStamps_1 = [];
11380 var min_1 = Infinity; // 最小值
11381 var secondMin_1 = min_1; // 次小值
11382 var max_1 = 0;
11383 // 使用一个循环,计算min,max,secondMin
11384 each(values, function (v) {
11385 var timeStamp = toTimeStamp$1(v);
11386 if (isNaN(timeStamp)) {
11387 throw new TypeError("Invalid Time: " + v + " in time scale!");
11388 }
11389 if (min_1 > timeStamp) {
11390 secondMin_1 = min_1;
11391 min_1 = timeStamp;
11392 }
11393 else if (secondMin_1 > timeStamp) {
11394 secondMin_1 = timeStamp;
11395 }
11396 if (max_1 < timeStamp) {
11397 max_1 = timeStamp;
11398 }
11399 timeStamps_1.push(timeStamp);
11400 });
11401 // 存在多个值时,设置最小间距
11402 if (values.length > 1) {
11403 this.minTickInterval = secondMin_1 - min_1;
11404 }
11405 if (isNil(minConfig)) {
11406 this.min = min_1;
11407 }
11408 if (isNil(maxConfig)) {
11409 this.max = max_1;
11410 }
11411 }
11412 };
11413 return Time;
11414 }(Linear));
11415
11416 /**
11417 * 分段度量
11418 */
11419 var Quantize = /** @class */ (function (_super) {
11420 __extends(Quantize, _super);
11421 function Quantize() {
11422 var _this = _super !== null && _super.apply(this, arguments) || this;
11423 _this.type = 'quantize';
11424 return _this;
11425 }
11426 Quantize.prototype.invert = function (value) {
11427 var ticks = this.ticks;
11428 var length = ticks.length;
11429 var percent = this.getInvertPercent(value);
11430 var minIndex = Math.floor(percent * (length - 1));
11431 // 最后一个
11432 if (minIndex >= length - 1) {
11433 return last(ticks);
11434 }
11435 // 超出左边界, 则取第一个
11436 if (minIndex < 0) {
11437 return head(ticks);
11438 }
11439 var minTick = ticks[minIndex];
11440 var nextTick = ticks[minIndex + 1];
11441 // 比当前值小的 tick 在度量上的占比
11442 var minIndexPercent = minIndex / (length - 1);
11443 var maxIndexPercent = (minIndex + 1) / (length - 1);
11444 return minTick + (percent - minIndexPercent) / (maxIndexPercent - minIndexPercent) * (nextTick - minTick);
11445 };
11446 Quantize.prototype.initCfg = function () {
11447 this.tickMethod = 'r-pretty';
11448 this.tickCount = 5;
11449 this.nice = true;
11450 };
11451 Quantize.prototype.calculateTicks = function () {
11452 var ticks = _super.prototype.calculateTicks.call(this);
11453 if (!this.nice) { // 如果 nice = false ,补充 min, max
11454 if (last(ticks) !== this.max) {
11455 ticks.push(this.max);
11456 }
11457 if (head(ticks) !== this.min) {
11458 ticks.unshift(this.min);
11459 }
11460 }
11461 return ticks;
11462 };
11463 // 计算当前值在刻度中的占比
11464 Quantize.prototype.getScalePercent = function (value) {
11465 var ticks = this.ticks;
11466 // 超出左边界
11467 if (value < head(ticks)) {
11468 return 0;
11469 }
11470 // 超出右边界
11471 if (value > last(ticks)) {
11472 return 1;
11473 }
11474 var minIndex = 0;
11475 each(ticks, function (tick, index) {
11476 if (value >= tick) {
11477 minIndex = index;
11478 }
11479 else {
11480 return false;
11481 }
11482 });
11483 return minIndex / (ticks.length - 1);
11484 };
11485 return Quantize;
11486 }(Continuous));
11487
11488 var Quantile = /** @class */ (function (_super) {
11489 __extends(Quantile, _super);
11490 function Quantile() {
11491 var _this = _super !== null && _super.apply(this, arguments) || this;
11492 _this.type = 'quantile';
11493 return _this;
11494 }
11495 Quantile.prototype.initCfg = function () {
11496 this.tickMethod = 'quantile';
11497 this.tickCount = 5;
11498 this.nice = true;
11499 };
11500 return Quantile;
11501 }(Quantize));
11502
11503 var map$3 = {};
11504 function getClass(key) {
11505 return map$3[key];
11506 }
11507 function registerClass(key, cls) {
11508 if (getClass(key)) {
11509 throw new Error("type '" + key + "' existed.");
11510 }
11511 map$3[key] = cls;
11512 }
11513
11514 /**
11515 * identity scale原则上是定义域和值域一致,scale/invert方法也是一致的
11516 * 参考R的实现:https://github.com/r-lib/scales/blob/master/R/pal-identity.r
11517 * 参考d3的实现(做了下转型):https://github.com/d3/d3-scale/blob/master/src/identity.js
11518 */
11519 var Identity = /** @class */ (function (_super) {
11520 __extends(Identity, _super);
11521 function Identity() {
11522 var _this = _super !== null && _super.apply(this, arguments) || this;
11523 _this.type = 'identity';
11524 _this.isIdentity = true;
11525 return _this;
11526 }
11527 Identity.prototype.calculateTicks = function () {
11528 return this.values;
11529 };
11530 Identity.prototype.scale = function (value) {
11531 // 如果传入的值不等于 identity 的值,则直接返回,用于一维图时的 dodge
11532 if (this.values[0] !== value && isNumber(value)) {
11533 return value;
11534 }
11535 return this.range[0];
11536 };
11537 Identity.prototype.invert = function (value) {
11538 var range = this.range;
11539 if (value < range[0] || value > range[1]) {
11540 return NaN;
11541 }
11542 return this.values[0];
11543 };
11544 return Identity;
11545 }(Scale));
11546
11547 /**
11548 * 计算分类 ticks
11549 * @param cfg 度量的配置项
11550 * @returns 计算后的 ticks
11551 */
11552 function calculateCatTicks(cfg) {
11553 var values = cfg.values, tickInterval = cfg.tickInterval, tickCount = cfg.tickCount, showLast = cfg.showLast;
11554 if (isNumber(tickInterval)) {
11555 var ticks_1 = filter(values, function (__, i) { return i % tickInterval === 0; });
11556 var lastValue = last(values);
11557 if (showLast && last(ticks_1) !== lastValue) {
11558 ticks_1.push(lastValue);
11559 }
11560 return ticks_1;
11561 }
11562 var len = values.length;
11563 var min = cfg.min, max = cfg.max;
11564 if (isNil(min)) {
11565 min = 0;
11566 }
11567 if (isNil(max)) {
11568 max = values.length - 1;
11569 }
11570 if (!isNumber(tickCount) || tickCount >= len)
11571 return values.slice(min, max + 1);
11572 if (tickCount <= 0 || max <= 0)
11573 return [];
11574 var interval = tickCount === 1 ? len : Math.floor(len / (tickCount - 1));
11575 var ticks = [];
11576 var idx = min;
11577 for (var i = 0; i < tickCount; i++) {
11578 if (idx >= max)
11579 break;
11580 idx = Math.min(min + i * interval, max);
11581 if (i === tickCount - 1 && showLast)
11582 ticks.push(values[max]);
11583 else
11584 ticks.push(values[idx]);
11585 }
11586 return ticks;
11587 }
11588
11589 function d3Linear(cfg) {
11590 var min = cfg.min, max = cfg.max, nice = cfg.nice, tickCount = cfg.tickCount;
11591 var linear = new D3Linear();
11592 linear.domain([min, max]);
11593 if (nice) {
11594 linear.nice(tickCount);
11595 }
11596 return linear.ticks(tickCount);
11597 }
11598 var DEFAULT_COUNT = 5;
11599 var e10 = Math.sqrt(50);
11600 var e5 = Math.sqrt(10);
11601 var e2 = Math.sqrt(2);
11602 // https://github.com/d3/d3-scale
11603 var D3Linear = /** @class */ (function () {
11604 function D3Linear() {
11605 this._domain = [0, 1];
11606 }
11607 D3Linear.prototype.domain = function (domain) {
11608 if (domain) {
11609 this._domain = Array.from(domain, Number);
11610 return this;
11611 }
11612 return this._domain.slice();
11613 };
11614 D3Linear.prototype.nice = function (count) {
11615 var _a, _b;
11616 if (count === void 0) { count = DEFAULT_COUNT; }
11617 var d = this._domain.slice();
11618 var i0 = 0;
11619 var i1 = this._domain.length - 1;
11620 var start = this._domain[i0];
11621 var stop = this._domain[i1];
11622 var step;
11623 if (stop < start) {
11624 _a = [stop, start], start = _a[0], stop = _a[1];
11625 _b = [i1, i0], i0 = _b[0], i1 = _b[1];
11626 }
11627 step = tickIncrement(start, stop, count);
11628 if (step > 0) {
11629 start = Math.floor(start / step) * step;
11630 stop = Math.ceil(stop / step) * step;
11631 step = tickIncrement(start, stop, count);
11632 }
11633 else if (step < 0) {
11634 start = Math.ceil(start * step) / step;
11635 stop = Math.floor(stop * step) / step;
11636 step = tickIncrement(start, stop, count);
11637 }
11638 if (step > 0) {
11639 d[i0] = Math.floor(start / step) * step;
11640 d[i1] = Math.ceil(stop / step) * step;
11641 this.domain(d);
11642 }
11643 else if (step < 0) {
11644 d[i0] = Math.ceil(start * step) / step;
11645 d[i1] = Math.floor(stop * step) / step;
11646 this.domain(d);
11647 }
11648 return this;
11649 };
11650 D3Linear.prototype.ticks = function (count) {
11651 if (count === void 0) { count = DEFAULT_COUNT; }
11652 return d3ArrayTicks(this._domain[0], this._domain[this._domain.length - 1], count || DEFAULT_COUNT);
11653 };
11654 return D3Linear;
11655 }());
11656 function d3ArrayTicks(start, stop, count) {
11657 var reverse;
11658 var i = -1;
11659 var n;
11660 var ticks;
11661 var step;
11662 (stop = +stop), (start = +start), (count = +count);
11663 if (start === stop && count > 0) {
11664 return [start];
11665 }
11666 // tslint:disable-next-line
11667 if ((reverse = stop < start)) {
11668 (n = start), (start = stop), (stop = n);
11669 }
11670 // tslint:disable-next-line
11671 if ((step = tickIncrement(start, stop, count)) === 0 || !isFinite(step)) {
11672 return [];
11673 }
11674 if (step > 0) {
11675 start = Math.ceil(start / step);
11676 stop = Math.floor(stop / step);
11677 ticks = new Array((n = Math.ceil(stop - start + 1)));
11678 while (++i < n) {
11679 ticks[i] = (start + i) * step;
11680 }
11681 }
11682 else {
11683 start = Math.floor(start * step);
11684 stop = Math.ceil(stop * step);
11685 ticks = new Array((n = Math.ceil(start - stop + 1)));
11686 while (++i < n) {
11687 ticks[i] = (start - i) / step;
11688 }
11689 }
11690 if (reverse) {
11691 ticks.reverse();
11692 }
11693 return ticks;
11694 }
11695 function tickIncrement(start, stop, count) {
11696 var step = (stop - start) / Math.max(0, count);
11697 var power = Math.floor(Math.log(step) / Math.LN10);
11698 var error = step / Math.pow(10, power);
11699 return power >= 0
11700 ? (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1) * Math.pow(10, power)
11701 : -Math.pow(10, -power) / (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1);
11702 }
11703
11704 function snapMultiple(v, base, snapType) {
11705 var div;
11706 if (snapType === 'ceil') {
11707 div = Math.ceil(v / base);
11708 }
11709 else if (snapType === 'floor') {
11710 div = Math.floor(v / base);
11711 }
11712 else {
11713 div = Math.round(v / base);
11714 }
11715 return div * base;
11716 }
11717 function intervalTicks(min, max, interval) {
11718 // 变成 interval 的倍数
11719 var minTick = snapMultiple(min, interval, 'floor');
11720 var maxTick = snapMultiple(max, interval, 'ceil');
11721 // 统一小数位数
11722 minTick = fixedBase(minTick, interval);
11723 maxTick = fixedBase(maxTick, interval);
11724 var ticks = [];
11725 // https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Errors/Invalid_array_length
11726 var availableInterval = Math.max((maxTick - minTick) / (Math.pow(2, 12) - 1), interval);
11727 for (var i = minTick; i <= maxTick; i = i + availableInterval) {
11728 var tickValue = fixedBase(i, availableInterval); // 防止浮点数加法出现问题
11729 ticks.push(tickValue);
11730 }
11731 return {
11732 min: minTick,
11733 max: maxTick,
11734 ticks: ticks
11735 };
11736 }
11737
11738 /**
11739 * 按照给定的 minLimit/maxLimit/tickCount 均匀计算出刻度 ticks
11740 *
11741 * @param cfg Scale 配置项
11742 * @return ticks
11743 */
11744 function strictLimit(cfg, defaultMin, defaultMax) {
11745 var _a;
11746 var minLimit = cfg.minLimit, maxLimit = cfg.maxLimit, min = cfg.min, max = cfg.max, _b = cfg.tickCount, tickCount = _b === void 0 ? 5 : _b;
11747 var tickMin = isNil(minLimit) ? (isNil(defaultMin) ? min : defaultMin) : minLimit;
11748 var tickMax = isNil(maxLimit) ? (isNil(defaultMax) ? max : defaultMax) : maxLimit;
11749 if (tickMin > tickMax) {
11750 _a = [tickMin, tickMax], tickMax = _a[0], tickMin = _a[1];
11751 }
11752 if (tickCount <= 2) {
11753 return [tickMin, tickMax];
11754 }
11755 var step = (tickMax - tickMin) / (tickCount - 1);
11756 var ticks = [];
11757 for (var i = 0; i < tickCount; i++) {
11758 ticks.push(tickMin + step * i);
11759 }
11760 return ticks;
11761 }
11762
11763 function d3LinearTickMethod(cfg) {
11764 var min = cfg.min, max = cfg.max, tickInterval = cfg.tickInterval, minLimit = cfg.minLimit, maxLimit = cfg.maxLimit;
11765 var ticks = d3Linear(cfg);
11766 if (!isNil(minLimit) || !isNil(maxLimit)) {
11767 return strictLimit(cfg, head(ticks), last(ticks));
11768 }
11769 if (tickInterval) {
11770 return intervalTicks(min, max, tickInterval).ticks;
11771 }
11772 return ticks;
11773 }
11774
11775 // 为了解决 js 运算的精度问题
11776 function prettyNumber(n) {
11777 return Math.abs(n) < 1e-15 ? n : parseFloat(n.toFixed(15));
11778 }
11779
11780 var DEFAULT_Q = [1, 5, 2, 2.5, 4, 3];
11781 var eps = Number.EPSILON * 100;
11782 function mod(n, m) {
11783 return ((n % m) + m) % m;
11784 }
11785 function round(n) {
11786 return Math.round(n * 1e12) / 1e12;
11787 }
11788 function simplicity(q, Q, j, lmin, lmax, lstep) {
11789 var n = size(Q);
11790 var i = indexOf(Q, q);
11791 var v = 0;
11792 var m = mod(lmin, lstep);
11793 if ((m < eps || lstep - m < eps) && lmin <= 0 && lmax >= 0) {
11794 v = 1;
11795 }
11796 return 1 - i / (n - 1) - j + v;
11797 }
11798 function simplicityMax(q, Q, j) {
11799 var n = size(Q);
11800 var i = indexOf(Q, q);
11801 var v = 1;
11802 return 1 - i / (n - 1) - j + v;
11803 }
11804 function density(k, m, dMin, dMax, lMin, lMax) {
11805 var r = (k - 1) / (lMax - lMin);
11806 var rt = (m - 1) / (Math.max(lMax, dMax) - Math.min(dMin, lMin));
11807 return 2 - Math.max(r / rt, rt / r);
11808 }
11809 function densityMax(k, m) {
11810 if (k >= m) {
11811 return 2 - (k - 1) / (m - 1);
11812 }
11813 return 1;
11814 }
11815 function coverage(dMin, dMax, lMin, lMax) {
11816 var range = dMax - dMin;
11817 return 1 - (0.5 * (Math.pow((dMax - lMax), 2) + Math.pow((dMin - lMin), 2))) / Math.pow((0.1 * range), 2);
11818 }
11819 function coverageMax(dMin, dMax, span) {
11820 var range = dMax - dMin;
11821 if (span > range) {
11822 var half = (span - range) / 2;
11823 return 1 - Math.pow(half, 2) / Math.pow((0.1 * range), 2);
11824 }
11825 return 1;
11826 }
11827 function legibility() {
11828 return 1;
11829 }
11830 /**
11831 * An Extension of Wilkinson's Algorithm for Position Tick Labels on Axes
11832 * https://www.yuque.com/preview/yuque/0/2019/pdf/185317/1546999150858-45c3b9c2-4e86-4223-bf1a-8a732e8195ed.pdf
11833 * @param dMin 最小值
11834 * @param dMax 最大值
11835 * @param m tick个数
11836 * @param onlyLoose 是否允许扩展min、max,不绝对强制,例如[3, 97]
11837 * @param Q nice numbers集合
11838 * @param w 四个优化组件的权重
11839 */
11840 function extended(dMin, dMax, n, onlyLoose, Q, w) {
11841 if (n === void 0) { n = 5; }
11842 if (onlyLoose === void 0) { onlyLoose = true; }
11843 if (Q === void 0) { Q = DEFAULT_Q; }
11844 if (w === void 0) { w = [0.25, 0.2, 0.5, 0.05]; }
11845 // 处理小于 0 和小数的 tickCount
11846 var m = n < 0 ? 0 : Math.round(n);
11847 // nan 也会导致异常
11848 if (Number.isNaN(dMin) || Number.isNaN(dMax) || typeof dMin !== 'number' || typeof dMax !== 'number' || !m) {
11849 return {
11850 min: 0,
11851 max: 0,
11852 ticks: [],
11853 };
11854 }
11855 // js 极大值极小值问题,差值小于 1e-15 会导致计算出错
11856 if (dMax - dMin < 1e-15 || m === 1) {
11857 return {
11858 min: dMin,
11859 max: dMax,
11860 ticks: [dMin],
11861 };
11862 }
11863 // js 超大值问题
11864 if (dMax - dMin > 1e148) {
11865 var count = n || 5;
11866 var step_1 = (dMax - dMin) / count;
11867 return {
11868 min: dMin,
11869 max: dMax,
11870 ticks: Array(count).fill(null).map(function (_, idx) {
11871 return prettyNumber(dMin + step_1 * idx);
11872 }),
11873 };
11874 }
11875 var best = {
11876 score: -2,
11877 lmin: 0,
11878 lmax: 0,
11879 lstep: 0,
11880 };
11881 var j = 1;
11882 while (j < Infinity) {
11883 for (var i = 0; i < Q.length; i += 1) {
11884 var q = Q[i];
11885 var sm = simplicityMax(q, Q, j);
11886 if (w[0] * sm + w[1] + w[2] + w[3] < best.score) {
11887 j = Infinity;
11888 break;
11889 }
11890 var k = 2;
11891 while (k < Infinity) {
11892 var dm = densityMax(k, m);
11893 if (w[0] * sm + w[1] + w[2] * dm + w[3] < best.score) {
11894 break;
11895 }
11896 var delta = (dMax - dMin) / (k + 1) / j / q;
11897 var z = Math.ceil(Math.log10(delta));
11898 while (z < Infinity) {
11899 var step = j * q * Math.pow(10, z);
11900 var cm = coverageMax(dMin, dMax, step * (k - 1));
11901 if (w[0] * sm + w[1] * cm + w[2] * dm + w[3] < best.score) {
11902 break;
11903 }
11904 var minStart = Math.floor(dMax / step) * j - (k - 1) * j;
11905 var maxStart = Math.ceil(dMin / step) * j;
11906 if (minStart <= maxStart) {
11907 var count = maxStart - minStart;
11908 for (var i_1 = 0; i_1 <= count; i_1 += 1) {
11909 var start = minStart + i_1;
11910 var lMin = start * (step / j);
11911 var lMax = lMin + step * (k - 1);
11912 var lStep = step;
11913 var s = simplicity(q, Q, j, lMin, lMax, lStep);
11914 var c = coverage(dMin, dMax, lMin, lMax);
11915 var g = density(k, m, dMin, dMax, lMin, lMax);
11916 var l = legibility();
11917 var score = w[0] * s + w[1] * c + w[2] * g + w[3] * l;
11918 if (score > best.score && (!onlyLoose || (lMin <= dMin && lMax >= dMax))) {
11919 best.lmin = lMin;
11920 best.lmax = lMax;
11921 best.lstep = lStep;
11922 best.score = score;
11923 }
11924 }
11925 }
11926 z += 1;
11927 }
11928 k += 1;
11929 }
11930 }
11931 j += 1;
11932 }
11933 // 处理精度问题,保证这三个数没有精度问题
11934 var lmax = prettyNumber(best.lmax);
11935 var lmin = prettyNumber(best.lmin);
11936 var lstep = prettyNumber(best.lstep);
11937 // 加 round 是为处理 extended(0.94, 1, 5)
11938 // 保证生成的 tickCount 没有精度问题
11939 var tickCount = Math.floor(round((lmax - lmin) / lstep)) + 1;
11940 var ticks = new Array(tickCount);
11941 // 少用乘法:防止出现 -1.2 + 1.2 * 3 = 2.3999999999999995 的情况
11942 ticks[0] = prettyNumber(lmin);
11943 for (var i = 1; i < tickCount; i++) {
11944 ticks[i] = prettyNumber(ticks[i - 1] + lstep);
11945 }
11946 return {
11947 min: Math.min(dMin, head(ticks)),
11948 max: Math.max(dMax, last(ticks)),
11949 ticks: ticks,
11950 };
11951 }
11952
11953 /**
11954 * 计算线性的 ticks,使用 wilkinson extended 方法
11955 * @param cfg 度量的配置项
11956 * @returns 计算后的 ticks
11957 */
11958 function linear$2(cfg) {
11959 var min = cfg.min, max = cfg.max, tickCount = cfg.tickCount, nice = cfg.nice, tickInterval = cfg.tickInterval, minLimit = cfg.minLimit, maxLimit = cfg.maxLimit;
11960 var ticks = extended(min, max, tickCount, nice).ticks;
11961 if (!isNil(minLimit) || !isNil(maxLimit)) {
11962 return strictLimit(cfg, head(ticks), last(ticks));
11963 }
11964 if (tickInterval) {
11965 return intervalTicks(min, max, tickInterval).ticks;
11966 }
11967 return ticks;
11968 }
11969
11970 /**
11971 * 计算 log 的 ticks,考虑 min = 0 的场景
11972 * @param cfg 度量的配置项
11973 * @returns 计算后的 ticks
11974 */
11975 function calculateLogTicks(cfg) {
11976 var base = cfg.base, tickCount = cfg.tickCount, min = cfg.min, max = cfg.max, values = cfg.values;
11977 var minTick;
11978 var maxTick = log(base, max);
11979 if (min > 0) {
11980 minTick = Math.floor(log(base, min));
11981 }
11982 else {
11983 var positiveMin = getLogPositiveMin(values, base, max);
11984 minTick = Math.floor(log(base, positiveMin));
11985 }
11986 var count = maxTick - minTick;
11987 var avg = Math.ceil(count / tickCount);
11988 var ticks = [];
11989 for (var i = minTick; i < maxTick + avg; i = i + avg) {
11990 ticks.push(Math.pow(base, i));
11991 }
11992 if (min <= 0) {
11993 // 最小值 <= 0 时显示 0
11994 ticks.unshift(0);
11995 }
11996 return ticks;
11997 }
11998
11999 function pretty(min, max, m) {
12000 if (m === void 0) { m = 5; }
12001 if (min === max) {
12002 return {
12003 max: max,
12004 min: min,
12005 ticks: [min],
12006 };
12007 }
12008 var n = m < 0 ? 0 : Math.round(m);
12009 if (n === 0)
12010 return { max: max, min: min, ticks: [] };
12011 /*
12012 R pretty:
12013 https://svn.r-project.org/R/trunk/src/appl/pretty.c
12014 https://www.rdocumentation.org/packages/base/versions/3.5.2/topics/pretty
12015 */
12016 var h = 1.5; // high.u.bias
12017 var h5 = 0.5 + 1.5 * h; // u5.bias
12018 // 反正我也不会调参,跳过所有判断步骤
12019 var d = max - min;
12020 var c = d / n;
12021 // 当d非常小的时候触发,但似乎没什么用
12022 // const min_n = Math.floor(n / 3);
12023 // const shrink_sml = Math.pow(2, 5);
12024 // if (Math.log10(d) < -2) {
12025 // c = (_.max([ Math.abs(max), Math.abs(min) ]) * shrink_sml) / min_n;
12026 // }
12027 var base = Math.pow(10, Math.floor(Math.log10(c)));
12028 var unit = base;
12029 if (2 * base - c < h * (c - unit)) {
12030 unit = 2 * base;
12031 if (5 * base - c < h5 * (c - unit)) {
12032 unit = 5 * base;
12033 if (10 * base - c < h * (c - unit)) {
12034 unit = 10 * base;
12035 }
12036 }
12037 }
12038 var nu = Math.ceil(max / unit);
12039 var ns = Math.floor(min / unit);
12040 var hi = Math.max(nu * unit, max);
12041 var lo = Math.min(ns * unit, min);
12042 var size = Math.floor((hi - lo) / unit) + 1;
12043 var ticks = new Array(size);
12044 for (var i = 0; i < size; i++) {
12045 ticks[i] = prettyNumber(lo + i * unit);
12046 }
12047 return {
12048 min: lo,
12049 max: hi,
12050 ticks: ticks,
12051 };
12052 }
12053
12054 /**
12055 * 计算 Pow 的 ticks
12056 * @param cfg 度量的配置项
12057 * @returns 计算后的 ticks
12058 */
12059 function calculatePowTicks(cfg) {
12060 var exponent = cfg.exponent, tickCount = cfg.tickCount;
12061 var max = Math.ceil(calBase(exponent, cfg.max));
12062 var min = Math.floor(calBase(exponent, cfg.min));
12063 var ticks = pretty(min, max, tickCount).ticks;
12064 return ticks.map(function (tick) {
12065 var factor = tick >= 0 ? 1 : -1;
12066 return Math.pow(tick, exponent) * factor;
12067 });
12068 }
12069
12070 /**
12071 * 计算几分位 https://github.com/simple-statistics/simple-statistics/blob/master/src/quantile_sorted.js
12072 * @param x 数组
12073 * @param p 百分比
12074 */
12075 function quantileSorted(x, p) {
12076 var idx = x.length * p;
12077 /*if (x.length === 0) { // 当前场景这些条件不可能命中
12078 throw new Error('quantile requires at least one value.');
12079 } else if (p < 0 || p > 1) {
12080 throw new Error('quantiles must be between 0 and 1');
12081 } else */
12082 if (p === 1) {
12083 // If p is 1, directly return the last element
12084 return x[x.length - 1];
12085 }
12086 else if (p === 0) {
12087 // If p is 0, directly return the first element
12088 return x[0];
12089 }
12090 else if (idx % 1 !== 0) {
12091 // If p is not integer, return the next element in array
12092 return x[Math.ceil(idx) - 1];
12093 }
12094 else if (x.length % 2 === 0) {
12095 // If the list has even-length, we'll take the average of this number
12096 // and the next value, if there is one
12097 return (x[idx - 1] + x[idx]) / 2;
12098 }
12099 else {
12100 // Finally, in the simple case of an integer value
12101 // with an odd-length list, return the x value at the index.
12102 return x[idx];
12103 }
12104 }
12105 function calculateTicks(cfg) {
12106 var tickCount = cfg.tickCount, values = cfg.values;
12107 if (!values || !values.length) {
12108 return [];
12109 }
12110 var sorted = values.slice().sort(function (a, b) {
12111 return a - b;
12112 });
12113 var ticks = [];
12114 for (var i = 0; i < tickCount; i++) {
12115 var p = i / (tickCount - 1);
12116 ticks.push(quantileSorted(sorted, p));
12117 }
12118 return ticks;
12119 }
12120
12121 /**
12122 * 计算线性的 ticks,使用 R's pretty 方法
12123 * @param cfg 度量的配置项
12124 * @returns 计算后的 ticks
12125 */
12126 function linearPretty(cfg) {
12127 var min = cfg.min, max = cfg.max, tickCount = cfg.tickCount, tickInterval = cfg.tickInterval, minLimit = cfg.minLimit, maxLimit = cfg.maxLimit;
12128 var ticks = pretty(min, max, tickCount).ticks;
12129 if (!isNil(minLimit) || !isNil(maxLimit)) {
12130 return strictLimit(cfg, head(ticks), last(ticks));
12131 }
12132 if (tickInterval) {
12133 return intervalTicks(min, max, tickInterval).ticks;
12134 }
12135 return ticks;
12136 }
12137
12138 function calculateTimeTicks(cfg) {
12139 var min = cfg.min, max = cfg.max, minTickInterval = cfg.minTickInterval;
12140 var tickInterval = cfg.tickInterval;
12141 var tickCount = cfg.tickCount;
12142 // 指定 tickInterval 后 tickCount 不生效,需要重新计算
12143 if (tickInterval) {
12144 tickCount = Math.ceil((max - min) / tickInterval);
12145 }
12146 else {
12147 tickInterval = getTickInterval(min, max, tickCount)[1];
12148 var count = (max - min) / tickInterval;
12149 var ratio = count / tickCount;
12150 if (ratio > 1) {
12151 tickInterval = tickInterval * Math.ceil(ratio);
12152 }
12153 // 如果设置了最小间距,则使用最小间距
12154 if (minTickInterval && tickInterval < minTickInterval) {
12155 tickInterval = minTickInterval;
12156 }
12157 }
12158 tickInterval = Math.max(Math.floor((max - min) / (Math.pow(2, 12) - 1)), tickInterval);
12159 var ticks = [];
12160 for (var i = min; i < max + tickInterval; i += tickInterval) {
12161 ticks.push(i);
12162 }
12163 return ticks;
12164 }
12165
12166 /**
12167 * 计算时间分类的 ticks, 保头,保尾
12168 * @param cfg 度量的配置项
12169 * @returns 计算后的 ticks
12170 */
12171 function timeCat(cfg) {
12172 // 默认保留最后一条
12173 var ticks = calculateCatTicks(__assign({ showLast: true }, cfg));
12174 return ticks;
12175 }
12176
12177 function getYear(date) {
12178 return new Date(date).getFullYear();
12179 }
12180 function createYear(year) {
12181 return new Date(year, 0, 1).getTime();
12182 }
12183 function getMonth(date) {
12184 return new Date(date).getMonth();
12185 }
12186 function diffMonth(min, max) {
12187 var minYear = getYear(min);
12188 var maxYear = getYear(max);
12189 var minMonth = getMonth(min);
12190 var maxMonth = getMonth(max);
12191 return (maxYear - minYear) * 12 + ((maxMonth - minMonth) % 12);
12192 }
12193 function creatMonth(year, month) {
12194 return new Date(year, month, 1).getTime();
12195 }
12196 function diffDay(min, max) {
12197 return Math.ceil((max - min) / DAY);
12198 }
12199 function diffHour(min, max) {
12200 return Math.ceil((max - min) / HOUR);
12201 }
12202 function diffMinus(min, max) {
12203 return Math.ceil((max - min) / (60 * 1000));
12204 }
12205 /**
12206 * 计算 time 的 ticks,对 month, year 进行 pretty 处理
12207 * @param cfg 度量的配置项
12208 * @returns 计算后的 ticks
12209 */
12210 function timePretty(cfg) {
12211 var min = cfg.min, max = cfg.max, minTickInterval = cfg.minTickInterval, tickCount = cfg.tickCount;
12212 var tickInterval = cfg.tickInterval;
12213 var ticks = [];
12214 // 指定 tickInterval 后 tickCount 不生效,需要重新计算
12215 if (!tickInterval) {
12216 tickInterval = (max - min) / tickCount;
12217 // 如果设置了最小间距,则使用最小间距
12218 if (minTickInterval && tickInterval < minTickInterval) {
12219 tickInterval = minTickInterval;
12220 }
12221 }
12222 tickInterval = Math.max(Math.floor((max - min) / (Math.pow(2, 12) - 1)), tickInterval);
12223 var minYear = getYear(min);
12224 // 如果间距大于 1 年,则将开始日期从整年开始
12225 if (tickInterval > YEAR) {
12226 var maxYear = getYear(max);
12227 var yearInterval = Math.ceil(tickInterval / YEAR);
12228 for (var i = minYear; i <= maxYear + yearInterval; i = i + yearInterval) {
12229 ticks.push(createYear(i));
12230 }
12231 }
12232 else if (tickInterval > MONTH) {
12233 // 大于月时
12234 var monthInterval = Math.ceil(tickInterval / MONTH);
12235 var mmMoth = getMonth(min);
12236 var dMonths = diffMonth(min, max);
12237 for (var i = 0; i <= dMonths + monthInterval; i = i + monthInterval) {
12238 ticks.push(creatMonth(minYear, i + mmMoth));
12239 }
12240 }
12241 else if (tickInterval > DAY) {
12242 // 大于天
12243 var date = new Date(min);
12244 var year = date.getFullYear();
12245 var month = date.getMonth();
12246 var mday = date.getDate();
12247 var day = Math.ceil(tickInterval / DAY);
12248 var ddays = diffDay(min, max);
12249 for (var i = 0; i < ddays + day; i = i + day) {
12250 ticks.push(new Date(year, month, mday + i).getTime());
12251 }
12252 }
12253 else if (tickInterval > HOUR) {
12254 // 大于小时
12255 var date = new Date(min);
12256 var year = date.getFullYear();
12257 var month = date.getMonth();
12258 var day = date.getDate();
12259 var hour = date.getHours();
12260 var hours = Math.ceil(tickInterval / HOUR);
12261 var dHours = diffHour(min, max);
12262 for (var i = 0; i <= dHours + hours; i = i + hours) {
12263 ticks.push(new Date(year, month, day, hour + i).getTime());
12264 }
12265 }
12266 else if (tickInterval > MINUTE) {
12267 // 大于分钟
12268 var dMinus = diffMinus(min, max);
12269 var minutes = Math.ceil(tickInterval / MINUTE);
12270 for (var i = 0; i <= dMinus + minutes; i = i + minutes) {
12271 ticks.push(min + i * MINUTE);
12272 }
12273 }
12274 else {
12275 // 小于分钟
12276 var interval = tickInterval;
12277 if (interval < SECOND) {
12278 interval = SECOND;
12279 }
12280 var minSecond = Math.floor(min / SECOND) * SECOND;
12281 var dSeconds = Math.ceil((max - min) / SECOND);
12282 var seconds = Math.ceil(interval / SECOND);
12283 for (var i = 0; i < dSeconds + seconds; i = i + seconds) {
12284 ticks.push(minSecond + i * SECOND);
12285 }
12286 }
12287 // 最好是能从算法能解决这个问题,但是如果指定了 tickInterval,计算 ticks,也只能这么算,所以
12288 // 打印警告提示
12289 if (ticks.length >= 512) {
12290 console.warn("Notice: current ticks length(" + ticks.length + ") >= 512, may cause performance issues, even out of memory. Because of the configure \"tickInterval\"(in milliseconds, current is " + tickInterval + ") is too small, increase the value to solve the problem!");
12291 }
12292 return ticks;
12293 }
12294
12295 registerTickMethod('cat', calculateCatTicks);
12296 registerTickMethod('time-cat', timeCat);
12297 registerTickMethod('wilkinson-extended', linear$2);
12298 registerTickMethod('r-pretty', linearPretty);
12299 registerTickMethod('time', calculateTimeTicks);
12300 registerTickMethod('time-pretty', timePretty);
12301 registerTickMethod('log', calculateLogTicks);
12302 registerTickMethod('pow', calculatePowTicks);
12303 registerTickMethod('quantile', calculateTicks);
12304 registerTickMethod('d3-linear', d3LinearTickMethod);
12305
12306 registerClass('cat', Category);
12307 registerClass('category', Category);
12308 registerClass('identity', Identity);
12309 registerClass('linear', Linear);
12310 registerClass('log', Log);
12311 registerClass('pow', Pow);
12312 registerClass('time', Time);
12313 registerClass('timeCat', TimeCat);
12314 registerClass('quantize', Quantize);
12315 registerClass('quantile', Quantile);
12316
12317 // cat平均算法,保头保尾
12318 var CatTick = (function (cfg) {
12319 var values = cfg.values,
12320 tickCount = cfg.tickCount;
12321
12322 if (!tickCount) {
12323 return values;
12324 }
12325
12326 if (values.length <= 1) {
12327 return values;
12328 } // 获取间隔步长, 最小是1
12329
12330
12331 var step = Math.floor(values.length / (tickCount - 1)) || 1;
12332 var ticks = []; // 按间隔数取对应节点
12333
12334 for (var index = 0; index < values.length; index = index + step) {
12335 ticks.push(values[index]);
12336 }
12337
12338 var last = values[values.length - 1]; // 如果最后一个tick不等于原数据的最后一个
12339
12340 if (ticks[ticks.length - 1] !== last) {
12341 if (ticks.length >= tickCount) {
12342 // 如果当前的tick个数满足要求
12343 ticks[ticks.length - 1] = last;
12344 } else {
12345 // 不满足tickCount则直接加入最后一个
12346 ticks.push(last);
12347 }
12348 }
12349
12350 return ticks;
12351 });
12352
12353 // 认为是nice的刻度
12354 var SNAP_COUNT_ARRAY = [1, 1.2, 1.5, 2, 2.2, 2.4, 2.5, 3, 4, 5, 6, 7.5, 8, 10];
12355 var DEFAULT_COUNT$1 = 5; // 默认刻度值
12356
12357 var LinearTick = (function (cfg) {
12358 var _ref = cfg || {},
12359 tickCount = _ref.tickCount,
12360 tickInterval = _ref.tickInterval;
12361
12362 var _ref2 = cfg || {},
12363 min = _ref2.min,
12364 max = _ref2.max;
12365
12366 min = isNaN(min) ? 0 : min;
12367 max = isNaN(max) ? 0 : max;
12368 var count = tickCount && tickCount >= 2 ? tickCount : DEFAULT_COUNT$1; // 计算interval, 优先取tickInterval
12369
12370 var interval = tickInterval || getBestInterval({
12371 tickCount: count,
12372 max: max,
12373 min: min
12374 }); // 通过interval计算最小tick
12375
12376 var minTick = Math.floor(min / interval) * interval; // 如果指定了tickInterval, count 需要根据指定的tickInterval来算计
12377
12378 if (tickInterval) {
12379 var intervalCount = Math.abs(Math.ceil((max - minTick) / tickInterval)) + 1; // tickCount 作为最小 count 处理
12380
12381 count = Math.max(count, intervalCount);
12382 }
12383
12384 var ticks = [];
12385 var tickLength = 0;
12386 var fixedLength = getFixedLength(interval);
12387
12388 while (tickLength < count) {
12389 ticks.push(toFixed(minTick + tickLength * interval, fixedLength));
12390 tickLength++;
12391 }
12392
12393 return ticks;
12394 });
12395 var DECIMAL_LENGTH = 12;
12396
12397 function getFactor(number) {
12398 // 取正数
12399 number = Math.abs(number);
12400 var factor = 1;
12401
12402 if (number === 0) {
12403 return factor;
12404 } // 小于1,逐渐放大
12405
12406
12407 if (number < 1) {
12408 var count = 0;
12409
12410 while (number < 1) {
12411 factor = factor / 10;
12412 number = number * 10;
12413 count++;
12414 } // 浮点数计算出现问题
12415
12416
12417 if (factor.toString().length > DECIMAL_LENGTH) {
12418 factor = parseFloat(factor.toFixed(count));
12419 }
12420
12421 return factor;
12422 } // 大于10逐渐缩小
12423
12424
12425 while (number > 10) {
12426 factor = factor * 10;
12427 number = number / 10;
12428 }
12429
12430 return factor;
12431 } // 获取最佳匹配刻度
12432
12433
12434 function getBestInterval(_ref3) {
12435 var tickCount = _ref3.tickCount,
12436 min = _ref3.min,
12437 max = _ref3.max;
12438
12439 // 如果最大最小相等,则直接按1处理
12440 if (min === max) {
12441 return 1 * getFactor(max);
12442 } // 1.计算平均刻度间隔
12443
12444
12445 var avgInterval = (max - min) / (tickCount - 1); // 2.数据标准归一化 映射到[1-10]区间
12446
12447 var factor = getFactor(avgInterval);
12448 var calInterval = avgInterval / factor;
12449 var calMax = max / factor;
12450 var calMin = min / factor; // 根据平均值推算最逼近刻度值
12451
12452 var similarityIndex = 0;
12453
12454 for (var index = 0; index < SNAP_COUNT_ARRAY.length; index++) {
12455 var item = SNAP_COUNT_ARRAY[index];
12456
12457 if (calInterval <= item) {
12458 similarityIndex = index;
12459 break;
12460 }
12461 }
12462
12463 var similarityInterval = getInterval(similarityIndex, tickCount, calMin, calMax); // 小数点位数还原到数据的位数, 因为similarityIndex有可能是小数,所以需要保留similarityIndex自己的小数位数
12464
12465 var fixedLength = getFixedLength(similarityInterval) + getFixedLength(factor);
12466 return toFixed(similarityInterval * factor, fixedLength);
12467 }
12468
12469 function getInterval(startIndex, tickCount, min, max) {
12470 var verify = false;
12471 var interval = SNAP_COUNT_ARRAY[startIndex]; // 刻度值校验,如果不满足,循环下去
12472
12473 for (var i = startIndex; i < SNAP_COUNT_ARRAY.length; i++) {
12474 if (intervalIsVerify({
12475 interval: SNAP_COUNT_ARRAY[i],
12476 tickCount: tickCount,
12477 max: max,
12478 min: min
12479 })) {
12480 // 有符合条件的interval
12481 interval = SNAP_COUNT_ARRAY[i];
12482 verify = true;
12483 break;
12484 }
12485 } // 如果不满足, 依次缩小10倍,再计算
12486
12487
12488 if (!verify) {
12489 return 10 * getInterval(0, tickCount, min / 10, max / 10);
12490 }
12491
12492 return interval;
12493 } // 刻度是否满足展示需求
12494
12495
12496 function intervalIsVerify(_ref4) {
12497 var interval = _ref4.interval,
12498 tickCount = _ref4.tickCount,
12499 max = _ref4.max,
12500 min = _ref4.min;
12501 var minTick = Math.floor(min / interval) * interval;
12502
12503 if (minTick + (tickCount - 1) * interval >= max) {
12504 return true;
12505 }
12506
12507 return false;
12508 } // 计算小数点应该保留的位数
12509
12510
12511 function getFixedLength(num) {
12512 var str = num.toString();
12513 var index = str.indexOf('.');
12514 var indexOfExp = str.indexOf('e-');
12515 var length = indexOfExp >= 0 ? parseInt(str.substr(indexOfExp + 2), 10) : str.substr(index + 1).length;
12516
12517 if (length > 20) {
12518 // 最多保留20位小数
12519 length = 20;
12520 }
12521
12522 return length;
12523 } // @antv/util fixedbase不支持科学计数法的判断,需要提mr
12524
12525
12526 function toFixed(v, length) {
12527 return parseFloat(v.toFixed(length));
12528 }
12529
12530 registerTickMethod('cat', CatTick);
12531 registerTickMethod('time-cat', CatTick); // 覆盖linear 度量的tick算法
12532
12533 registerTickMethod('wilkinson-extended', LinearTick);
12534
12535 var ScaleController = /*#__PURE__*/function () {
12536 function ScaleController(data) {
12537 _classCallCheck(this, ScaleController);
12538
12539 this.data = data;
12540 this.options = {};
12541 this.scales = {};
12542 }
12543
12544 _createClass(ScaleController, [{
12545 key: "_getType",
12546 value: function _getType(option) {
12547 var type = option.type,
12548 values = option.values,
12549 field = option.field;
12550
12551 if (type) {
12552 return type;
12553 }
12554
12555 if (isNumber(field) || isNil(values[0]) && field) {
12556 return 'identity';
12557 }
12558
12559 if (typeof values[0] === 'number') {
12560 return 'linear';
12561 }
12562
12563 return 'cat';
12564 }
12565 }, {
12566 key: "_getOption",
12567 value: function _getOption(option) {
12568 var values = option.values,
12569 field = option.field,
12570 justifyContent = option.justifyContent;
12571
12572 var type = this._getType(option);
12573
12574 option.type = type; // identity
12575
12576 if (type === 'identity') {
12577 option.field = field.toString();
12578 option.values = [field];
12579 return option;
12580 } // linear 类型
12581
12582
12583 if (type === 'linear') {
12584 // 设置默认nice
12585 if (typeof option.nice !== 'boolean') {
12586 option.nice = true;
12587 } // 重置最大最小
12588
12589
12590 var _getRange = getRange(values),
12591 min = _getRange.min,
12592 max = _getRange.max;
12593
12594 if (isNil(option.min)) {
12595 option.min = min;
12596 }
12597
12598 if (isNil(option.max)) {
12599 option.max = max;
12600 }
12601
12602 option.values = values.sort(function (a, b) {
12603 return a - b;
12604 });
12605 return option;
12606 } // 分类类型和 timeCat 类型,调整 range
12607
12608
12609 if (type === 'cat' || type === 'timeCat') {
12610 if (option.range) {
12611 return option;
12612 }
12613
12614 var count = values.length;
12615 var range = [0, 1]; // 如果只有一项,显示在中间
12616
12617 if (count === 1) {
12618 range = [0.5, 1];
12619 } else if (justifyContent) {
12620 // 居中
12621 var offset = 1 / count * 0.5;
12622 range = [offset, 1 - offset];
12623 } else {
12624 // 最后留 1 / count
12625 var _offset = 1 / count;
12626
12627 range = [0, 1 - _offset];
12628 }
12629
12630 option.range = range;
12631 }
12632
12633 return option;
12634 }
12635 }, {
12636 key: "createScale",
12637 value: function createScale(option) {
12638 var type = option.type;
12639
12640 if (isFunction(type)) {
12641 return new type(option);
12642 }
12643
12644 var ScaleClass = getClass(type);
12645 return new ScaleClass(option);
12646 } // 更新或创建scale
12647
12648 }, {
12649 key: "setScale",
12650 value: function setScale(field, option) {
12651 var options = this.options,
12652 scales = this.scales;
12653 options[field] = mix({}, options[field], option); // 如果scale有更新,scale 也需要重新创建
12654
12655 if (scales[field]) {
12656 delete scales[field];
12657 }
12658 }
12659 }, {
12660 key: "create",
12661 value: function create(options) {
12662 this.update(options);
12663 }
12664 }, {
12665 key: "update",
12666 value: function update(options) {
12667 var _this = this;
12668
12669 if (!options) return;
12670 each(options, function (option, field) {
12671 _this.setScale(field, option);
12672 }); // 为了让外部感知到scale有变化
12673
12674 this.scales = _objectSpread({}, this.scales);
12675 }
12676 }, {
12677 key: "changeData",
12678 value: function changeData(data) {
12679 this.data = data;
12680 this.scales = {};
12681 }
12682 }, {
12683 key: "getData",
12684 value: function getData() {
12685 return this.data;
12686 }
12687 }, {
12688 key: "getScale",
12689 value: function getScale(field) {
12690 var scales = this.scales,
12691 options = this.options,
12692 data = this.data;
12693 var scale = scales[field];
12694
12695 if (scale) {
12696 return scale;
12697 }
12698
12699 var option = options[field];
12700
12701 if (!option) {
12702 return null;
12703 }
12704
12705 var values = option.values ? option.values : data ? valuesOfKey(data, field) : [];
12706
12707 var scaleOption = this._getOption(_objectSpread(_objectSpread({}, option), {}, {
12708 field: field,
12709 values: values
12710 }));
12711
12712 var newScale = this.createScale(scaleOption);
12713 scales[field] = newScale;
12714 return newScale;
12715 }
12716 }, {
12717 key: "getScales",
12718 value: function getScales() {
12719 var _this2 = this;
12720
12721 var options = this.options,
12722 scales = this.scales;
12723 each(options, function (option, field) {
12724 _this2.getScale(field);
12725 });
12726 return scales;
12727 }
12728 }, {
12729 key: "adjustStartZero",
12730 value: function adjustStartZero(scale) {
12731 var options = this.options;
12732 var field = scale.field,
12733 min = scale.min,
12734 max = scale.max;
12735 var option = options[field]; // 如果有定义,则不处理
12736
12737 if (option && option.min) {
12738 return;
12739 }
12740
12741 if (min > 0) {
12742 scale.change({
12743 min: 0
12744 });
12745 } else if (max < 0) {
12746 scale.change({
12747 max: 0
12748 });
12749 }
12750 } // 饼图下的scale调整
12751
12752 }, {
12753 key: "adjustPieScale",
12754 value: function adjustPieScale(scale) {
12755 var options = this.options;
12756 var field = scale.field;
12757 var option = options[field];
12758
12759 if (option && !isNil(option.nice)) {
12760 return null;
12761 }
12762
12763 scale.change({
12764 nice: false
12765 });
12766 } // 获取scale 在 0点对位置的值
12767
12768 }, {
12769 key: "getZeroValue",
12770 value: function getZeroValue(scale) {
12771 var min = scale.min,
12772 max = scale.max;
12773 var value;
12774
12775 if (min >= 0) {
12776 value = min;
12777 } else if (max <= 0) {
12778 value = max;
12779 } else {
12780 value = 0;
12781 }
12782
12783 return scale.scale(value);
12784 }
12785 }]);
12786
12787 return ScaleController;
12788 }();
12789
12790 var Chart = /*#__PURE__*/function (_Component) {
12791 _inherits(Chart, _Component);
12792
12793 var _super = _createSuper(Chart);
12794
12795 function Chart(props, context, updater) {
12796 var _this;
12797
12798 _classCallCheck(this, Chart);
12799
12800 _this = _super.call(this, props, context, updater);
12801 _this.componentsPosition = [];
12802 var data = props.data,
12803 coordOption = props.coord,
12804 _props$scale = props.scale,
12805 scale = _props$scale === void 0 ? [] : _props$scale;
12806 _this.layoutController = new LayoutController();
12807 _this.coordController = new coordController();
12808 _this.scaleController = new ScaleController(data);
12809 _this.scale = _this.scaleController;
12810
12811 var _assertThisInitialize = _assertThisInitialized(_this),
12812 layoutController = _assertThisInitialize.layoutController,
12813 coordController$1 = _assertThisInitialize.coordController,
12814 scaleController = _assertThisInitialize.scaleController; // 布局
12815
12816
12817 var style = _this.getStyle(props, context);
12818
12819 _this.layout = layoutController.create(style); // 坐标系
12820
12821 _this.coord = coordController$1.create(coordOption, _this.layout); // scale
12822
12823 scaleController.create(scale);
12824 _this.data = data; // state
12825
12826 _this.state = {
12827 filters: {}
12828 };
12829 return _this;
12830 } // props 更新
12831
12832
12833 _createClass(Chart, [{
12834 key: "willReceiveProps",
12835 value: function willReceiveProps(nextProps, context) {
12836 var layoutController = this.layoutController,
12837 coordController = this.coordController,
12838 scaleController = this.scaleController,
12839 lastProps = this.props;
12840 var nextStyle = nextProps.style,
12841 nextData = nextProps.data,
12842 nextScale = nextProps.scale;
12843 var lastStyle = lastProps.style,
12844 lastData = lastProps.data,
12845 lastScale = lastProps.scale; // 布局
12846
12847 if (!equal(nextStyle, lastStyle) || context !== this.context) {
12848 var style = this.getStyle(nextProps, context);
12849 this.layout = layoutController.create(style);
12850 coordController.updateLayout(this.layout);
12851 }
12852
12853 if (nextData !== lastData) {
12854 scaleController.changeData(nextData);
12855 } // scale
12856
12857
12858 if (!equal(nextScale, lastScale)) {
12859 scaleController.update(nextScale);
12860 }
12861 }
12862 }, {
12863 key: "willUpdate",
12864 value: function willUpdate() {
12865 var coordController = this.coordController,
12866 props = this.props; // render 时要重置 coord 范围,重置后需要让所有子组件都重新render
12867 // 所以这里不比较是否有差异,每次都新建,让所有子组件重新render
12868
12869 this.coord = coordController.create(props.coord, this.layout);
12870 }
12871 }, {
12872 key: "getStyle",
12873 value: function getStyle(props, context) {
12874 var theme = context.theme,
12875 px2hd = context.px2hd,
12876 left = context.left,
12877 top = context.top,
12878 width = context.width,
12879 height = context.height;
12880 var style = props.style;
12881 return px2hd(_objectSpread(_objectSpread({
12882 left: left,
12883 top: top,
12884 width: width,
12885 height: height
12886 }, theme.chart), style));
12887 } // 给需要显示的组件留空
12888
12889 }, {
12890 key: "layoutCoord",
12891 value: function layoutCoord(layout) {
12892 var coord = this.coord;
12893 var position = layout.position,
12894 boxWidth = layout.width,
12895 boxHeight = layout.height;
12896 var left = coord.left,
12897 top = coord.top,
12898 width = coord.width,
12899 height = coord.height;
12900
12901 switch (position) {
12902 case 'left':
12903 left += boxWidth;
12904 width = Math.max(0, width - boxWidth);
12905 break;
12906
12907 case 'right':
12908 width = Math.max(0, width - boxWidth);
12909 break;
12910
12911 case 'top':
12912 top += boxHeight;
12913 height = Math.max(0, height - boxHeight);
12914 break;
12915
12916 case 'bottom':
12917 height = Math.max(0, height - boxHeight);
12918 break;
12919 }
12920
12921 coord.update({
12922 left: left,
12923 top: top,
12924 width: width,
12925 height: height
12926 });
12927 }
12928 }, {
12929 key: "resetCoordLayout",
12930 value: function resetCoordLayout() {
12931 var coord = this.coord,
12932 layout = this.layout;
12933 coord.update(layout);
12934 }
12935 }, {
12936 key: "updateCoordLayout",
12937 value: function updateCoordLayout(layout) {
12938 var _this2 = this;
12939
12940 if (isArray(layout)) {
12941 layout.forEach(function (item) {
12942 _this2.layoutCoord(item);
12943 });
12944 return;
12945 }
12946
12947 this.layoutCoord(layout);
12948 }
12949 }, {
12950 key: "updateCoordFor",
12951 value: function updateCoordFor(component, layout) {
12952 var _this3 = this;
12953
12954 if (!layout) return;
12955 var componentsPosition = this.componentsPosition;
12956 var componentPosition = {
12957 component: component,
12958 layout: layout
12959 };
12960 var existIndex = findIndex(componentsPosition, function (item) {
12961 return item.component === component;
12962 }); // 说明是已经存在的组件
12963
12964 if (existIndex > -1) {
12965 componentsPosition.splice(existIndex, 1, componentPosition); // 先重置,然后整体重新算一次
12966
12967 this.resetCoordLayout();
12968 componentsPosition.forEach(function (componentPosition) {
12969 var layout = componentPosition.layout;
12970
12971 _this3.updateCoordLayout(layout);
12972 });
12973 return;
12974 } // 是新组件,直接添加
12975
12976
12977 componentsPosition.push(componentPosition);
12978 this.updateCoordLayout(layout);
12979 }
12980 }, {
12981 key: "getGeometrys",
12982 value: function getGeometrys() {
12983 var children = this.children;
12984 var geometrys = []; // @ts-ignore
12985
12986 Children.toArray(children).forEach(function (element) {
12987 if (!element) return false;
12988 var component = element.component;
12989
12990 if (component && component.isGeometry) {
12991 geometrys.push(component);
12992 }
12993 });
12994 return geometrys;
12995 }
12996 /**
12997 * calculate dataset's position on canvas
12998 * @param {Object} record the dataset
12999 * @return {Object} return the position
13000 */
13001
13002 }, {
13003 key: "getPosition",
13004 value: function getPosition(record) {
13005 var coord = this.getCoord();
13006 var xScale = this.getXScales()[0];
13007 var xField = xScale.field;
13008 var yScales = this.getYScales(); // default first
13009
13010 var yScale = yScales[0];
13011 var yField = yScale.field;
13012
13013 for (var i = 0, len = yScales.length; i < len; i++) {
13014 var scale = yScales[i];
13015 var field = scale.field;
13016
13017 if (record[field]) {
13018 yScale = scale;
13019 yField = field;
13020 break;
13021 }
13022 }
13023
13024 var x = xScale.scale(record[xField]);
13025 var y = yScale.scale(record[yField]);
13026 return coord.convertPoint({
13027 x: x,
13028 y: y
13029 });
13030 }
13031 }, {
13032 key: "getSnapRecords",
13033 value: function getSnapRecords(point, inCoordRange) {
13034 var geometrys = this.getGeometrys();
13035 if (!geometrys.length) return; // @ts-ignore
13036
13037 return geometrys[0].getSnapRecords(point, inCoordRange);
13038 }
13039 }, {
13040 key: "getLegendItems",
13041 value: function getLegendItems(point) {
13042 var geometrys = this.getGeometrys();
13043 if (!geometrys.length) return; // @ts-ignore
13044
13045 return geometrys[0].getLegendItems(point);
13046 }
13047 }, {
13048 key: "setScale",
13049 value: function setScale(field, option) {
13050 this.scaleController.setScale(field, option);
13051 }
13052 }, {
13053 key: "getScale",
13054 value: function getScale(field) {
13055 return this.scaleController.getScale(field);
13056 }
13057 }, {
13058 key: "getScales",
13059 value: function getScales() {
13060 return this.scaleController.getScales();
13061 }
13062 }, {
13063 key: "getXScales",
13064 value: function getXScales() {
13065 var geometrys = this.getGeometrys();
13066 return geometrys.map(function (component) {
13067 // @ts-ignore
13068 return component.getXScale();
13069 });
13070 }
13071 }, {
13072 key: "getYScales",
13073 value: function getYScales() {
13074 var geometrys = this.getGeometrys();
13075 return geometrys.map(function (component) {
13076 // @ts-ignore
13077 return component.getYScale();
13078 });
13079 }
13080 }, {
13081 key: "getCoord",
13082 value: function getCoord() {
13083 return this.coord;
13084 }
13085 }, {
13086 key: "filter",
13087 value: function filter(field, condition) {
13088 var filters = this.state.filters;
13089 this.setState({
13090 filters: _objectSpread(_objectSpread({}, filters), {}, _defineProperty({}, field, condition))
13091 });
13092 }
13093 }, {
13094 key: "_getRenderData",
13095 value: function _getRenderData() {
13096 var props = this.props,
13097 state = this.state;
13098 var data = props.data;
13099 var filters = state.filters;
13100
13101 if (!filters || !Object.keys(filters).length) {
13102 return data;
13103 }
13104
13105 var filteredData = data;
13106 each(filters, function (condition, field) {
13107 if (!condition) return;
13108 filteredData = filteredData.filter(function (record) {
13109 return condition(record[field], record);
13110 });
13111 });
13112 return filteredData;
13113 }
13114 }, {
13115 key: "render",
13116 value: function render() {
13117 var _this4 = this;
13118
13119 var props = this.props,
13120 layout = this.layout,
13121 coord = this.coord;
13122 var children = props.children,
13123 originData = props.data;
13124 if (!originData) return null;
13125
13126 var data = this._getRenderData();
13127
13128 return Children.map(children, function (child) {
13129 return Children.cloneElement(child, {
13130 chart: _this4,
13131 coord: coord,
13132 data: data,
13133 layout: layout
13134 });
13135 });
13136 }
13137 }]);
13138
13139 return Chart;
13140 }(Component);
13141
13142 function isEqual(origin1, origin2, fields) {
13143 if (origin1 === origin2) {
13144 return true;
13145 }
13146
13147 for (var i = 0, len = fields.length; i < len; i++) {
13148 var field = fields[i];
13149
13150 if (origin1[field] !== origin2[field]) {
13151 return false;
13152 }
13153 }
13154
13155 return true;
13156 }
13157
13158 var Selection = /*#__PURE__*/function (_Component) {
13159 _inherits(Selection, _Component);
13160
13161 var _super = _createSuper(Selection);
13162
13163 function Selection(props, context) {
13164 var _this;
13165
13166 _classCallCheck(this, Selection);
13167
13168 _this = _super.call(this, props, context);
13169 var selection = props.selection;
13170 if (!selection) return _possibleConstructorReturn(_this);
13171 var defaultSelected = selection.defaultSelected;
13172 _this.state.selected = defaultSelected;
13173 return _this;
13174 }
13175
13176 _createClass(Selection, [{
13177 key: "didMount",
13178 value: function didMount() {
13179 var _this2 = this;
13180
13181 var props = this.props,
13182 state = this.state,
13183 container = this.container;
13184 var canvas = container.get('canvas');
13185 var selection = props.selection,
13186 chart = props.chart;
13187 if (!selection) return; // 默认为 click
13188
13189 var _selection$triggerOn = selection.triggerOn,
13190 triggerOn = _selection$triggerOn === void 0 ? 'click' : _selection$triggerOn;
13191 canvas.on(triggerOn, function (ev) {
13192 var points = ev.points;
13193
13194 var records = _this2.getSnapRecords(points[0]);
13195
13196 var _selection$type = selection.type,
13197 type = _selection$type === void 0 ? 'single' : _selection$type,
13198 _selection$cancelable = selection.cancelable,
13199 cancelable = _selection$cancelable === void 0 ? true : _selection$cancelable;
13200
13201 if (!records || !records.length) {
13202 if (cancelable) {
13203 _this2.setState({
13204 selected: null
13205 });
13206 }
13207
13208 return;
13209 }
13210
13211 var selected = state.selected;
13212 var origins = records.map(function (record) {
13213 return record.origin;
13214 });
13215
13216 if (!selected || !selected.length) {
13217 _this2.setState({
13218 selected: origins
13219 });
13220 }
13221
13222 if (type === 'single') {
13223 if (!cancelable) {
13224 _this2.setState({
13225 selected: origins
13226 });
13227
13228 return;
13229 }
13230
13231 var _newSelected = [];
13232 records.forEach(function (record) {
13233 if (!_this2.isSelected(record)) {
13234 _newSelected.push(record.origin);
13235 }
13236 });
13237
13238 _this2.setState({
13239 selected: _newSelected
13240 });
13241
13242 return;
13243 } // 多选
13244
13245
13246 var scales = chart.getScales();
13247 var fields = Object.keys(scales);
13248 var selectedMap = {};
13249 selected.forEach(function (item) {
13250 var key = fields.map(function (field) {
13251 return item[field];
13252 }).join('-');
13253 selectedMap[key] = item;
13254 });
13255 records.forEach(function (record) {
13256 var origin = record.origin;
13257 var key = fields.map(function (field) {
13258 return origin[field];
13259 }).join('-');
13260 selectedMap[key] = selectedMap[key] ? null : origin;
13261 });
13262 var newSelected = Object.keys(selectedMap).map(function (key) {
13263 return selectedMap[key];
13264 }).filter(Boolean);
13265
13266 _this2.setState({
13267 selected: newSelected
13268 });
13269 });
13270 }
13271 }, {
13272 key: "willReceiveProps",
13273 value: function willReceiveProps(nextProps) {
13274 var nextSelection = nextProps.selection;
13275 var lastSelection = this.props.selection;
13276
13277 if (!nextSelection || !lastSelection) {
13278 return;
13279 }
13280
13281 var nextDefaultSelected = nextSelection.defaultSelected;
13282 var lastDefaultSelected = lastSelection.defaultSelected;
13283
13284 if (!equal(nextDefaultSelected, lastDefaultSelected)) {
13285 this.state.selected = nextDefaultSelected;
13286 }
13287 }
13288 }, {
13289 key: "getSnapRecords",
13290 value: function getSnapRecords(_point) {
13291 return null;
13292 }
13293 }, {
13294 key: "isSelected",
13295 value: function isSelected(record) {
13296 var state = this.state,
13297 props = this.props;
13298 var selected = state.selected;
13299
13300 if (!selected || !selected.length) {
13301 return false;
13302 }
13303
13304 var chart = props.chart;
13305 var scales = chart.getScales();
13306 var fields = Object.keys(scales);
13307
13308 for (var i = 0, len = selected.length; i < len; i++) {
13309 var item = selected[i];
13310
13311 if (isEqual(record.origin, item, fields)) {
13312 return true;
13313 }
13314 }
13315
13316 return false;
13317 }
13318 }, {
13319 key: "getSelectionStyle",
13320 value: function getSelectionStyle(record) {
13321 var state = this.state,
13322 props = this.props;
13323 var selected = state.selected;
13324
13325 if (!selected || !selected.length) {
13326 return null;
13327 }
13328
13329 var selection = props.selection;
13330 var selectedStyle = selection.selectedStyle,
13331 unSelectedStyle = selection.unSelectedStyle;
13332 var isSelected = this.isSelected(record);
13333
13334 if (isSelected) {
13335 return isFunction(selectedStyle) ? selectedStyle(record) : selectedStyle;
13336 }
13337
13338 return isFunction(unSelectedStyle) ? unSelectedStyle(record) : unSelectedStyle;
13339 }
13340 }]);
13341
13342 return Selection;
13343 }(Component);
13344
13345 var DEFAULT_Y = 0; // 默认的 y 的值
13346 // 偏移之后,间距
13347 var MARGIN_RATIO = 1 / 2;
13348 var DODGE_RATIO = 1 / 2;
13349 // 散点分开之后,距离边界的距离
13350 var GAP = 0.05;
13351
13352 var Adjust = /** @class */ (function () {
13353 function Adjust(cfg) {
13354 var xField = cfg.xField, yField = cfg.yField, _a = cfg.adjustNames, adjustNames = _a === void 0 ? ['x', 'y'] : _a, dimValuesMap = cfg.dimValuesMap;
13355 this.adjustNames = adjustNames;
13356 this.xField = xField;
13357 this.yField = yField;
13358 this.dimValuesMap = dimValuesMap;
13359 }
13360 /**
13361 * 查看维度是否是 adjust 字段
13362 * @param dim
13363 */
13364 Adjust.prototype.isAdjust = function (dim) {
13365 return this.adjustNames.indexOf(dim) >= 0;
13366 };
13367 Adjust.prototype.getAdjustRange = function (dim, dimValue, values) {
13368 var yField = this.yField;
13369 var index = values.indexOf(dimValue);
13370 var length = values.length;
13371 var pre;
13372 var next;
13373 // 没有 y 字段,但是需要根据 y 调整
13374 if (!yField && this.isAdjust('y')) {
13375 pre = 0;
13376 next = 1;
13377 }
13378 else if (length > 1) {
13379 // 如果以其开头,则取之,否则取他前面一个
13380 pre = values[index === 0 ? 0 : index - 1];
13381 // 如果以其结尾,则取之,否则取他后面一个
13382 next = values[index === length - 1 ? length - 1 : index + 1];
13383 if (index !== 0) {
13384 pre += (dimValue - pre) / 2;
13385 }
13386 else {
13387 pre -= (next - dimValue) / 2;
13388 }
13389 if (index !== length - 1) {
13390 next -= (next - dimValue) / 2;
13391 }
13392 else {
13393 next += (dimValue - values[length - 2]) / 2;
13394 }
13395 }
13396 else {
13397 pre = dimValue === 0 ? 0 : dimValue - 0.5;
13398 next = dimValue === 0 ? 1 : dimValue + 0.5;
13399 }
13400 return {
13401 pre: pre,
13402 next: next,
13403 };
13404 };
13405 Adjust.prototype.adjustData = function (groupedDataArray, mergedData) {
13406 var _this = this;
13407 // 所有调整维度的值数组
13408 var dimValuesMap = this.getDimValues(mergedData);
13409 // 按照每一个分组来进行调整
13410 each(groupedDataArray, function (dataArray, index) {
13411 // 遍历所有数据集合
13412 // 每个分组中,分别按照不同的 dim 进行调整
13413 each(dimValuesMap, function (values, dim) {
13414 // 根据不同的度量分别调整位置
13415 _this.adjustDim(dim, values, dataArray, index);
13416 });
13417 });
13418 };
13419 /**
13420 * 对数据进行分组adjustData
13421 * @param data 数据
13422 * @param dim 分组的字段
13423 * @return 分组结果
13424 */
13425 Adjust.prototype.groupData = function (data, dim) {
13426 // 补齐数据空数据为默认值
13427 each(data, function (record) {
13428 if (record[dim] === undefined) {
13429 record[dim] = DEFAULT_Y;
13430 }
13431 });
13432 // 按照 dim 维度分组
13433 return groupBy(data, dim);
13434 };
13435 /** @override */
13436 Adjust.prototype.adjustDim = function (dim, values, data, index) { };
13437 /**
13438 * 获取可调整度量对应的值
13439 * @param mergedData 数据
13440 * @return 值的映射
13441 */
13442 Adjust.prototype.getDimValues = function (mergedData) {
13443 var _a = this, xField = _a.xField, yField = _a.yField;
13444 var dimValuesMap = mix({}, this.dimValuesMap);
13445 // 所有的维度
13446 var dims = [];
13447 if (xField && this.isAdjust('x')) {
13448 dims.push(xField);
13449 }
13450 if (yField && this.isAdjust('y')) {
13451 dims.push(yField);
13452 }
13453 dims.forEach(function (dim) {
13454 if (dimValuesMap && dimValuesMap[dim]) {
13455 return;
13456 }
13457 // 在每个维度上,所有的值
13458 dimValuesMap[dim] = valuesOfKey(mergedData, dim).sort(function (v1, v2) { return v1 - v2; });
13459 });
13460 // 只有一维的情况下,同时调整 y,赋予默认值
13461 if (!yField && this.isAdjust('y')) {
13462 var dim = 'y';
13463 dimValuesMap[dim] = [DEFAULT_Y, 1]; // 默认分布在 y 轴的 0 与 1 之间
13464 }
13465 return dimValuesMap;
13466 };
13467 return Adjust;
13468 }());
13469
13470 var ADJUST_MAP = {};
13471 /**
13472 * 根据类型获取 Adjust 类
13473 * @param type
13474 */
13475 var getAdjust = function (type) {
13476 return ADJUST_MAP[type.toLowerCase()];
13477 };
13478 /**
13479 * 注册自定义 Adjust
13480 * @param type
13481 * @param ctor
13482 */
13483 var registerAdjust = function (type, ctor) {
13484 // 注册的时候,需要校验 type 重名,不区分大小写
13485 if (getAdjust(type)) {
13486 throw new Error("Adjust type '" + type + "' existed.");
13487 }
13488 // 存储到 map 中
13489 ADJUST_MAP[type.toLowerCase()] = ctor;
13490 };
13491
13492 /*! *****************************************************************************
13493 Copyright (c) Microsoft Corporation.
13494
13495 Permission to use, copy, modify, and/or distribute this software for any
13496 purpose with or without fee is hereby granted.
13497
13498 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
13499 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13500 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
13501 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13502 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
13503 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
13504 PERFORMANCE OF THIS SOFTWARE.
13505 ***************************************************************************** */
13506
13507 /* global Reflect, Promise */
13508 var _extendStatics = function extendStatics(d, b) {
13509 _extendStatics = Object.setPrototypeOf || {
13510 __proto__: []
13511 } instanceof Array && function (d, b) {
13512 d.__proto__ = b;
13513 } || function (d, b) {
13514 for (var p in b) {
13515 if (b.hasOwnProperty(p)) d[p] = b[p];
13516 }
13517 };
13518
13519 return _extendStatics(d, b);
13520 };
13521
13522 function __extends$1(d, b) {
13523 _extendStatics(d, b);
13524
13525 function __() {
13526 this.constructor = d;
13527 }
13528
13529 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
13530 }
13531
13532 var _assign = function __assign() {
13533 _assign = Object.assign || function __assign(t) {
13534 for (var s, i = 1, n = arguments.length; i < n; i++) {
13535 s = arguments[i];
13536
13537 for (var p in s) {
13538 if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
13539 }
13540 }
13541
13542 return t;
13543 };
13544
13545 return _assign.apply(this, arguments);
13546 };
13547
13548 var Dodge = /** @class */ (function (_super) {
13549 __extends$1(Dodge, _super);
13550 function Dodge(cfg) {
13551 var _this = _super.call(this, cfg) || this;
13552 _this.cacheMap = {};
13553 _this.adjustDataArray = [];
13554 _this.mergeData = [];
13555 var _a = cfg.marginRatio, marginRatio = _a === void 0 ? MARGIN_RATIO : _a, _b = cfg.dodgeRatio, dodgeRatio = _b === void 0 ? DODGE_RATIO : _b, dodgeBy = cfg.dodgeBy, intervalPadding = cfg.intervalPadding, dodgePadding = cfg.dodgePadding, xDimensionLength = cfg.xDimensionLength, groupNum = cfg.groupNum, defaultSize = cfg.defaultSize, maxColumnWidth = cfg.maxColumnWidth, minColumnWidth = cfg.minColumnWidth, columnWidthRatio = cfg.columnWidthRatio, customOffset = cfg.customOffset;
13556 _this.marginRatio = marginRatio;
13557 _this.dodgeRatio = dodgeRatio;
13558 _this.dodgeBy = dodgeBy;
13559 _this.intervalPadding = intervalPadding;
13560 _this.dodgePadding = dodgePadding;
13561 _this.xDimensionLegenth = xDimensionLength;
13562 _this.groupNum = groupNum;
13563 _this.defaultSize = defaultSize;
13564 _this.maxColumnWidth = maxColumnWidth;
13565 _this.minColumnWidth = minColumnWidth;
13566 _this.columnWidthRatio = columnWidthRatio;
13567 _this.customOffset = customOffset;
13568 return _this;
13569 }
13570 Dodge.prototype.process = function (groupDataArray) {
13571 var groupedDataArray = clone(groupDataArray);
13572 // 将数据数组展开一层
13573 var mergeData = flatten(groupedDataArray);
13574 var dodgeBy = this.dodgeBy;
13575 // 如果指定了分组 dim 的字段
13576 var adjustDataArray = dodgeBy ? group(mergeData, dodgeBy) : groupedDataArray;
13577 this.cacheMap = {};
13578 this.adjustDataArray = adjustDataArray;
13579 this.mergeData = mergeData;
13580 this.adjustData(adjustDataArray, mergeData);
13581 this.adjustDataArray = [];
13582 this.mergeData = [];
13583 return groupedDataArray;
13584 };
13585 Dodge.prototype.adjustDim = function (dim, values, data, frameIndex) {
13586 var _this = this;
13587 var customOffset = this.customOffset;
13588 var map = this.getDistribution(dim);
13589 var groupData = this.groupData(data, dim); // 根据值分组
13590 each(groupData, function (group, key) {
13591 var range;
13592 // xField 中只有一个值,不需要做 dodge
13593 if (values.length === 1) {
13594 range = {
13595 pre: values[0] - 1,
13596 next: values[0] + 1,
13597 };
13598 }
13599 else {
13600 // 如果有多个,则需要获取调整的范围
13601 range = _this.getAdjustRange(dim, parseFloat(key), values);
13602 }
13603 each(group, function (d) {
13604 var value = d[dim];
13605 var valueArr = map[value];
13606 var valIndex = valueArr.indexOf(frameIndex);
13607 if (!isNil(customOffset)) {
13608 var pre = range.pre, next = range.next;
13609 d[dim] = isFunction(customOffset) ? customOffset(d, range) : (pre + next) / 2 + customOffset;
13610 }
13611 else {
13612 d[dim] = _this.getDodgeOffset(range, valIndex, valueArr.length);
13613 }
13614 });
13615 });
13616 return [];
13617 };
13618 Dodge.prototype.getDodgeOffset = function (range, idx, len) {
13619 var _a = this, dodgeRatio = _a.dodgeRatio, marginRatio = _a.marginRatio, intervalPadding = _a.intervalPadding, dodgePadding = _a.dodgePadding;
13620 var pre = range.pre, next = range.next;
13621 var tickLength = next - pre;
13622 var position;
13623 // 分多种输入情况
13624 if (!isNil(intervalPadding) && isNil(dodgePadding) && intervalPadding >= 0) {
13625 // 仅配置intervalPadding
13626 var offset = this.getIntervalOnlyOffset(len, idx);
13627 position = pre + offset;
13628 }
13629 else if (!isNil(dodgePadding) && isNil(intervalPadding) && dodgePadding >= 0) {
13630 // 仅配置dodgePadding
13631 var offset = this.getDodgeOnlyOffset(len, idx);
13632 position = pre + offset;
13633 }
13634 else if (!isNil(intervalPadding) &&
13635 !isNil(dodgePadding) &&
13636 intervalPadding >= 0 &&
13637 dodgePadding >= 0) {
13638 // 同时配置intervalPadding和dodgePadding
13639 var offset = this.getIntervalAndDodgeOffset(len, idx);
13640 position = pre + offset;
13641 }
13642 else {
13643 // 默认情况
13644 var width = (tickLength * dodgeRatio) / len;
13645 var margin = marginRatio * width;
13646 var offset = (1 / 2) * (tickLength - len * width - (len - 1) * margin) +
13647 ((idx + 1) * width + idx * margin) -
13648 (1 / 2) * width -
13649 (1 / 2) * tickLength;
13650 position = (pre + next) / 2 + offset;
13651 }
13652 return position;
13653 };
13654 Dodge.prototype.getIntervalOnlyOffset = function (len, idx) {
13655 var _a = this, defaultSize = _a.defaultSize, intervalPadding = _a.intervalPadding, xDimensionLegenth = _a.xDimensionLegenth, groupNum = _a.groupNum, dodgeRatio = _a.dodgeRatio, maxColumnWidth = _a.maxColumnWidth, minColumnWidth = _a.minColumnWidth, columnWidthRatio = _a.columnWidthRatio;
13656 var normalizedIntervalPadding = intervalPadding / xDimensionLegenth;
13657 var normalizedDodgePadding = (1 - (groupNum - 1) * normalizedIntervalPadding) / groupNum * dodgeRatio / (len - 1);
13658 var geomWidth = ((1 - normalizedIntervalPadding * (groupNum - 1)) / groupNum - normalizedDodgePadding * (len - 1)) / len;
13659 // 根据columnWidthRatio/defaultSize/maxColumnWidth/minColumnWidth调整宽度
13660 geomWidth = (!isNil(columnWidthRatio)) ? 1 / groupNum / len * columnWidthRatio : geomWidth;
13661 if (!isNil(maxColumnWidth)) {
13662 var normalizedMaxWidht = maxColumnWidth / xDimensionLegenth;
13663 geomWidth = Math.min(geomWidth, normalizedMaxWidht);
13664 }
13665 if (!isNil(minColumnWidth)) {
13666 var normalizedMinWidht = minColumnWidth / xDimensionLegenth;
13667 geomWidth = Math.max(geomWidth, normalizedMinWidht);
13668 }
13669 geomWidth = defaultSize ? (defaultSize / xDimensionLegenth) : geomWidth;
13670 // 调整组内间隔
13671 normalizedDodgePadding = ((1 - (groupNum - 1) * normalizedIntervalPadding) / groupNum - len * geomWidth) / (len - 1);
13672 var offset = ((1 / 2 + idx) * geomWidth + idx * normalizedDodgePadding +
13673 (1 / 2) * normalizedIntervalPadding) * groupNum -
13674 normalizedIntervalPadding / 2;
13675 return offset;
13676 };
13677 Dodge.prototype.getDodgeOnlyOffset = function (len, idx) {
13678 var _a = this, defaultSize = _a.defaultSize, dodgePadding = _a.dodgePadding, xDimensionLegenth = _a.xDimensionLegenth, groupNum = _a.groupNum, marginRatio = _a.marginRatio, maxColumnWidth = _a.maxColumnWidth, minColumnWidth = _a.minColumnWidth, columnWidthRatio = _a.columnWidthRatio;
13679 var normalizedDodgePadding = dodgePadding / xDimensionLegenth;
13680 var normalizedIntervalPadding = 1 * marginRatio / (groupNum - 1);
13681 var geomWidth = ((1 - normalizedIntervalPadding * (groupNum - 1)) / groupNum - normalizedDodgePadding * (len - 1)) / len;
13682 // 根据columnWidthRatio/defaultSize/maxColumnWidth/minColumnWidth调整宽度
13683 geomWidth = columnWidthRatio ? 1 / groupNum / len * columnWidthRatio : geomWidth;
13684 if (!isNil(maxColumnWidth)) {
13685 var normalizedMaxWidht = maxColumnWidth / xDimensionLegenth;
13686 geomWidth = Math.min(geomWidth, normalizedMaxWidht);
13687 }
13688 if (!isNil(minColumnWidth)) {
13689 var normalizedMinWidht = minColumnWidth / xDimensionLegenth;
13690 geomWidth = Math.max(geomWidth, normalizedMinWidht);
13691 }
13692 geomWidth = defaultSize ? (defaultSize / xDimensionLegenth) : geomWidth;
13693 // 调整组间距
13694 normalizedIntervalPadding = (1 - (geomWidth * len + normalizedDodgePadding * (len - 1)) * groupNum) / (groupNum - 1);
13695 var offset = ((1 / 2 + idx) * geomWidth + idx * normalizedDodgePadding +
13696 (1 / 2) * normalizedIntervalPadding) * groupNum -
13697 normalizedIntervalPadding / 2;
13698 return offset;
13699 };
13700 Dodge.prototype.getIntervalAndDodgeOffset = function (len, idx) {
13701 var _a = this, intervalPadding = _a.intervalPadding, dodgePadding = _a.dodgePadding, xDimensionLegenth = _a.xDimensionLegenth, groupNum = _a.groupNum;
13702 var normalizedIntervalPadding = intervalPadding / xDimensionLegenth;
13703 var normalizedDodgePadding = dodgePadding / xDimensionLegenth;
13704 var geomWidth = ((1 - normalizedIntervalPadding * (groupNum - 1)) / groupNum - normalizedDodgePadding * (len - 1)) / len;
13705 var offset = ((1 / 2 + idx) * geomWidth + idx * normalizedDodgePadding +
13706 (1 / 2) * normalizedIntervalPadding) * groupNum -
13707 normalizedIntervalPadding / 2;
13708 return offset;
13709 };
13710 Dodge.prototype.getDistribution = function (dim) {
13711 var groupedDataArray = this.adjustDataArray;
13712 var cacheMap = this.cacheMap;
13713 var map = cacheMap[dim];
13714 if (!map) {
13715 map = {};
13716 each(groupedDataArray, function (data, index) {
13717 var values = valuesOfKey(data, dim);
13718 if (!values.length) {
13719 values.push(0);
13720 }
13721 each(values, function (val) {
13722 if (!map[val]) {
13723 map[val] = [];
13724 }
13725 map[val].push(index);
13726 });
13727 });
13728 cacheMap[dim] = map;
13729 }
13730 return map;
13731 };
13732 return Dodge;
13733 }(Adjust));
13734
13735 function randomNumber(min, max) {
13736 return (max - min) * Math.random() + min;
13737 }
13738 var Jitter = /** @class */ (function (_super) {
13739 __extends$1(Jitter, _super);
13740 function Jitter() {
13741 return _super !== null && _super.apply(this, arguments) || this;
13742 }
13743 Jitter.prototype.process = function (groupDataArray) {
13744 var groupedDataArray = clone(groupDataArray);
13745 // 之前分组之后的数据,然后有合并回去(和分组前可以理解成是一样的)
13746 var mergeData = flatten(groupedDataArray);
13747 // 返回值
13748 this.adjustData(groupedDataArray, mergeData);
13749 return groupedDataArray;
13750 };
13751 /**
13752 * 当前数据分组(index)中,按照维度 dim 进行 jitter 调整
13753 * @param dim
13754 * @param values
13755 * @param dataArray
13756 */
13757 Jitter.prototype.adjustDim = function (dim, values, dataArray) {
13758 var _this = this;
13759 // 在每一个分组中,将数据再按照 dim 分组,用于散列
13760 var groupDataArray = this.groupData(dataArray, dim);
13761 return each(groupDataArray, function (data, dimValue) {
13762 return _this.adjustGroup(data, dim, parseFloat(dimValue), values);
13763 });
13764 };
13765 // 随机出来的字段值
13766 Jitter.prototype.getAdjustOffset = function (range) {
13767 var pre = range.pre, next = range.next;
13768 // 随机的范围
13769 var margin = (next - pre) * GAP;
13770 return randomNumber(pre + margin, next - margin);
13771 };
13772 // adjust group data
13773 Jitter.prototype.adjustGroup = function (group, dim, dimValue, values) {
13774 var _this = this;
13775 // 调整范围
13776 var range = this.getAdjustRange(dim, dimValue, values);
13777 each(group, function (data) {
13778 data[dim] = _this.getAdjustOffset(range); // 获取调整的位置
13779 });
13780 return group;
13781 };
13782 return Jitter;
13783 }(Adjust));
13784
13785 var Cache = default_1;
13786 var Stack = /** @class */ (function (_super) {
13787 __extends$1(Stack, _super);
13788 function Stack(cfg) {
13789 var _this = _super.call(this, cfg) || this;
13790 var _a = cfg.adjustNames, adjustNames = _a === void 0 ? ['y'] : _a, _b = cfg.height, height = _b === void 0 ? NaN : _b, _c = cfg.size, size = _c === void 0 ? 10 : _c, _d = cfg.reverseOrder, reverseOrder = _d === void 0 ? false : _d;
13791 _this.adjustNames = adjustNames;
13792 _this.height = height;
13793 _this.size = size;
13794 _this.reverseOrder = reverseOrder;
13795 return _this;
13796 }
13797 /**
13798 * 方法入参是经过数据分组、数据数字化之后的二维数组
13799 * @param groupDataArray 分组之后的数据
13800 */
13801 Stack.prototype.process = function (groupDataArray) {
13802 var _a = this, yField = _a.yField, reverseOrder = _a.reverseOrder;
13803 // 如果有指定 y 字段,那么按照 y 字段来 stack
13804 // 否则,按照高度均分
13805 var d = yField ? this.processStack(groupDataArray) : this.processOneDimStack(groupDataArray);
13806 return reverseOrder ? this.reverse(d) : d;
13807 };
13808 Stack.prototype.reverse = function (groupedDataArray) {
13809 return groupedDataArray.slice(0).reverse();
13810 };
13811 Stack.prototype.processStack = function (groupDataArray) {
13812 var _a = this, xField = _a.xField, yField = _a.yField, reverseOrder = _a.reverseOrder;
13813 // 层叠顺序翻转
13814 var groupedDataArray = reverseOrder ? this.reverse(groupDataArray) : groupDataArray;
13815 // 用来缓存,正数和负数的堆叠问题
13816 var positive = new Cache();
13817 var negative = new Cache();
13818 return groupedDataArray.map(function (dataArray) {
13819 return dataArray.map(function (data) {
13820 var _a;
13821 var x = get(data, xField, 0);
13822 var y = get(data, [yField]);
13823 var xKey = x.toString();
13824 // todo 是否应该取 _origin?因为 y 可能取到的值不正确,比如先 symmetric,再 stack!
13825 y = isArray(y) ? y[1] : y;
13826 if (!isNil(y)) {
13827 var cache = y >= 0 ? positive : negative;
13828 if (!cache.has(xKey)) {
13829 cache.set(xKey, 0);
13830 }
13831 var xValue = cache.get(xKey);
13832 var newXValue = y + xValue;
13833 // 存起来
13834 cache.set(xKey, newXValue);
13835 return _assign(_assign({}, data), (_a = {}, _a[yField] = [xValue, newXValue], _a));
13836 }
13837 // 没有修改,则直接返回
13838 return data;
13839 });
13840 });
13841 };
13842 Stack.prototype.processOneDimStack = function (groupDataArray) {
13843 var _this = this;
13844 var _a = this, xField = _a.xField, height = _a.height, reverseOrder = _a.reverseOrder;
13845 var yField = 'y';
13846 // 如果层叠的顺序翻转
13847 var groupedDataArray = reverseOrder ? this.reverse(groupDataArray) : groupDataArray;
13848 // 缓存累加数据
13849 var cache = new Cache();
13850 return groupedDataArray.map(function (dataArray) {
13851 return dataArray.map(function (data) {
13852 var _a;
13853 var size = _this.size;
13854 var xValue = data[xField];
13855 // todo 没有看到这个 stack 计算原理
13856 var stackHeight = (size * 2) / height;
13857 if (!cache.has(xValue)) {
13858 cache.set(xValue, stackHeight / 2); // 初始值大小
13859 }
13860 var stackValue = cache.get(xValue);
13861 // 增加一层 stackHeight
13862 cache.set(xValue, stackValue + stackHeight);
13863 return _assign(_assign({}, data), (_a = {}, _a[yField] = stackValue, _a));
13864 });
13865 });
13866 };
13867 return Stack;
13868 }(Adjust));
13869
13870 var Symmetric = /** @class */ (function (_super) {
13871 __extends$1(Symmetric, _super);
13872 function Symmetric() {
13873 return _super !== null && _super.apply(this, arguments) || this;
13874 }
13875 Symmetric.prototype.process = function (groupDataArray) {
13876 var mergeData = flatten(groupDataArray);
13877 var _a = this, xField = _a.xField, yField = _a.yField;
13878 // 每个 x 值对应的 最大值
13879 var cache = this.getXValuesMaxMap(mergeData);
13880 // 所有数据的最大的值
13881 var max = Math.max.apply(Math, Object.keys(cache).map(function (key) { return cache[key]; }));
13882 return map(groupDataArray, function (dataArray) {
13883 return map(dataArray, function (data) {
13884 var _a, _b;
13885 var yValue = data[yField];
13886 var xValue = data[xField];
13887 // 数组处理逻辑
13888 if (isArray(yValue)) {
13889 var off_1 = (max - cache[xValue]) / 2;
13890 return _assign(_assign({}, data), (_a = {}, _a[yField] = map(yValue, function (y) { return off_1 + y; }), _a));
13891 }
13892 // 非数组处理逻辑
13893 var offset = (max - yValue) / 2;
13894 return _assign(_assign({}, data), (_b = {}, _b[yField] = [offset, yValue + offset], _b));
13895 });
13896 });
13897 };
13898 // 获取每个 x 对应的最大的值
13899 Symmetric.prototype.getXValuesMaxMap = function (mergeData) {
13900 var _this = this;
13901 var _a = this, xField = _a.xField, yField = _a.yField;
13902 // 根据 xField 的值进行分组
13903 var groupDataArray = groupBy(mergeData, function (data) { return data[xField]; });
13904 // 获取每个 xField 值中的最大值
13905 return mapValues(groupDataArray, function (dataArray) { return _this.getDimMaxValue(dataArray, yField); });
13906 };
13907 Symmetric.prototype.getDimMaxValue = function (mergeData, dim) {
13908 // 所有的 value 值
13909 var dimValues = map(mergeData, function (data) { return get(data, dim, []); });
13910 // 将数组打平(dim value 有可能是数组,比如 stack 之后的)
13911 var flattenValues = flatten(dimValues);
13912 // 求出数组的最大值
13913 return Math.max.apply(Math, flattenValues);
13914 };
13915 return Symmetric;
13916 }(Adjust));
13917
13918 // 注册内置的 adjust
13919 registerAdjust('Dodge', Dodge);
13920 registerAdjust('Jitter', Jitter);
13921 registerAdjust('Stack', Stack);
13922 registerAdjust('Symmetric', Symmetric);
13923
13924 var Base$1 = /*#__PURE__*/function () {
13925 function Base(options) {
13926 _classCallCheck(this, Base);
13927
13928 mix(this, options);
13929 var scale = this.scale,
13930 field = this.field,
13931 data = this.data;
13932
13933 if (!scale && data) {
13934 var values = valuesOfKey(data, field);
13935 this.scale = this.createScale({
13936 values: values,
13937 field: field
13938 });
13939 }
13940 }
13941
13942 _createClass(Base, [{
13943 key: "createScale",
13944 value: function createScale(_scaleConfig) {
13945 return null;
13946 } // 数据映射方法
13947
13948 }, {
13949 key: "_mapping",
13950 value: function _mapping(value) {
13951 return value;
13952 }
13953 }, {
13954 key: "update",
13955 value: function update(options) {
13956 mix(this, options);
13957 }
13958 }, {
13959 key: "setRange",
13960 value: function setRange(range) {
13961 this.range = range;
13962 } // 归一化,参数是原始数据,返回是归一化的数据
13963
13964 }, {
13965 key: "normalize",
13966 value: function normalize(value) {
13967 var scale = this.scale;
13968
13969 if (isArray(value)) {
13970 return value.map(function (v) {
13971 return scale.scale(v);
13972 });
13973 }
13974
13975 return scale.scale(value);
13976 } // convert 参数是归一化的数据,返回定义域的值
13977
13978 }, {
13979 key: "convert",
13980 value: function convert(value) {
13981 return value;
13982 } // 等于 normalize + convert, 参数是原始数据,返回是定义域的值
13983
13984 }, {
13985 key: "mapping",
13986 value: function mapping(value) {
13987 var child = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
13988 var rst = isFunction(this.callback) ? this.callback(value, child) : null;
13989
13990 if (!isNil(rst)) {
13991 return rst;
13992 }
13993
13994 return this._mapping(value);
13995 }
13996 }]);
13997
13998 return Base;
13999 }();
14000
14001 var Linear$1 = /*#__PURE__*/function (_Base) {
14002 _inherits(Linear$1, _Base);
14003
14004 var _super = _createSuper(Linear$1);
14005
14006 function Linear$1(options) {
14007 var _this;
14008
14009 _classCallCheck(this, Linear$1);
14010
14011 _this = _super.call(this, options);
14012
14013 _this._updateInterpolate();
14014
14015 return _this;
14016 }
14017
14018 _createClass(Linear$1, [{
14019 key: "createScale",
14020 value: function createScale(scaleConfig) {
14021 return new Linear(scaleConfig);
14022 }
14023 }, {
14024 key: "_updateInterpolate",
14025 value: function _updateInterpolate() {
14026 var _this$range = _slicedToArray(this.range, 2),
14027 min = _this$range[0],
14028 max = _this$range[1];
14029
14030 this.interpolate = interpolate(min, max);
14031 }
14032 }, {
14033 key: "update",
14034 value: function update(options) {
14035 _get$1(_getPrototypeOf(Linear$1.prototype), "update", this).call(this, options);
14036
14037 this._updateInterpolate();
14038 }
14039 }, {
14040 key: "_mapping",
14041 value: function _mapping(value) {
14042 var scale = this.scale,
14043 interpolate = this.interpolate;
14044
14045 if (isArray(value)) {
14046 return value.map(function (v) {
14047 return interpolate(scale.scale(v));
14048 });
14049 }
14050
14051 return interpolate(scale.scale(value));
14052 }
14053 }, {
14054 key: "normalize",
14055 value: function normalize(value) {
14056 var scale = this.scale;
14057
14058 if (isArray(value)) {
14059 return value.map(function (v) {
14060 return scale.scale(v);
14061 });
14062 }
14063
14064 return scale.scale(value);
14065 }
14066 }, {
14067 key: "convert",
14068 value: function convert(value) {
14069 var range = this.range;
14070
14071 var _range = _slicedToArray(range, 2),
14072 min = _range[0],
14073 max = _range[1];
14074
14075 if (isArray(value)) {
14076 return value.map(function (v) {
14077 return min + (max - min) * v;
14078 });
14079 }
14080
14081 return min + (max - min) * value;
14082 }
14083 }]);
14084
14085 return Linear$1;
14086 }(Base$1);
14087
14088 var Category$1 = /*#__PURE__*/function (_Base) {
14089 _inherits(Category$1, _Base);
14090
14091 var _super = _createSuper(Category$1);
14092
14093 function Category$1() {
14094 _classCallCheck(this, Category$1);
14095
14096 return _super.apply(this, arguments);
14097 }
14098
14099 _createClass(Category$1, [{
14100 key: "createScale",
14101 value: function createScale(scaleConfig) {
14102 return new Category(scaleConfig);
14103 }
14104 }, {
14105 key: "_mapping",
14106 value: function _mapping(value) {
14107 var scale = this.scale,
14108 range = this.range;
14109
14110 if (scale.type === 'cat') {
14111 var _index = scale.translate(value);
14112
14113 return range[_index % range.length];
14114 }
14115
14116 var normalizeValue = scale.scale(value);
14117 var index = Math.round(normalizeValue * (range.length - 1));
14118 return range[index];
14119 }
14120 }]);
14121
14122 return Category$1;
14123 }(Base$1);
14124
14125 var Identity$1 = /*#__PURE__*/function (_Base) {
14126 _inherits(Identity$1, _Base);
14127
14128 var _super = _createSuper(Identity$1);
14129
14130 function Identity$1() {
14131 _classCallCheck(this, Identity$1);
14132
14133 return _super.apply(this, arguments);
14134 }
14135
14136 _createClass(Identity$1, [{
14137 key: "createScale",
14138 value: function createScale(scaleConfig) {
14139 return new Identity(scaleConfig);
14140 }
14141 }, {
14142 key: "_mapping",
14143 value: function _mapping() {
14144 var field = this.field,
14145 range = this.range;
14146 return field || range && range[0];
14147 }
14148 }]);
14149
14150 return Identity$1;
14151 }(Base$1);
14152
14153 var Attrs = /*#__PURE__*/Object.freeze({
14154 __proto__: null,
14155 Attr: Base$1,
14156 Linear: Linear$1,
14157 Category: Category$1,
14158 Identity: Identity$1
14159 });
14160
14161 var Identity$2 = Identity$1,
14162 Linear$2 = Linear$1,
14163 Category$2 = Category$1; // 需要映射的属性名
14164
14165 var ATTRS = ['x', 'y', 'color', 'size', 'shape']; // 分组处理的属性
14166
14167 var GROUP_ATTRS = ['color', 'size', 'shape'];
14168
14169 function cloneScale(scale, scaleConfig) {
14170 // @ts-ignore
14171 return new scale.constructor(_objectSpread(_objectSpread({}, scale.__cfg__), scaleConfig));
14172 }
14173
14174 var AttrController = /*#__PURE__*/function () {
14175 function AttrController(scaleController, attrsRange) {
14176 _classCallCheck(this, AttrController);
14177
14178 this.scaleController = scaleController;
14179 this.attrsRange = attrsRange;
14180 this.options = {};
14181 this.attrs = {};
14182 }
14183
14184 _createClass(AttrController, [{
14185 key: "parseOption",
14186 value: function parseOption(option, attrName) {
14187 if (!option) {
14188 return {
14189 type: 'identity'
14190 };
14191 }
14192
14193 if (isString(option)) {
14194 return {
14195 field: option,
14196 type: 'category'
14197 };
14198 }
14199
14200 if (isNumber(option)) {
14201 if (attrName === 'size') {
14202 return {
14203 type: 'identity',
14204 field: option
14205 };
14206 }
14207 }
14208
14209 if (isArray(option)) {
14210 return {
14211 field: option[0],
14212 range: option[1]
14213 };
14214 }
14215
14216 return option;
14217 }
14218 }, {
14219 key: "getAttrOptions",
14220 value: function getAttrOptions(props, justifyContentCenter) {
14221 var _this = this;
14222
14223 if (!props.x || !props.y) {
14224 throw new Error('x, y are required !');
14225 }
14226
14227 var options = {};
14228 var ranges = this.attrsRange;
14229 ATTRS.forEach(function (attrName) {
14230 if (!props[attrName]) return;
14231
14232 var option = _this.parseOption(props[attrName], attrName);
14233
14234 if (!option.range) {
14235 option.range = ranges[attrName];
14236 }
14237
14238 options[attrName] = option;
14239 }); // @ts-ignore
14240
14241 var x = options.x,
14242 y = options.y;
14243 x.justifyContent = justifyContentCenter; // x, y 都是固定Linear 映射
14244
14245 x.type = Linear$2;
14246 y.type = Linear$2;
14247 return options;
14248 }
14249 }, {
14250 key: "getDefaultAttrValues",
14251 value: function getDefaultAttrValues() {
14252 var _this$attrsRange = this.attrsRange,
14253 color = _this$attrsRange.color,
14254 shape = _this$attrsRange.shape;
14255 return {
14256 color: color[0],
14257 shape: shape && shape[0]
14258 };
14259 }
14260 }, {
14261 key: "getGroupScales",
14262 value: function getGroupScales() {
14263 var attrs = this.attrs;
14264 var scales = [];
14265 each(GROUP_ATTRS, function (attrName) {
14266 var attr = attrs[attrName];
14267
14268 if (!attr) {
14269 return;
14270 }
14271
14272 var scale = attr.scale;
14273
14274 if (scale && scale.isCategory && scales.indexOf(scale) === -1) {
14275 scales.push(scale);
14276 }
14277 });
14278 return scales;
14279 }
14280 }, {
14281 key: "createAttr",
14282 value: function createAttr(option) {
14283 var type = option.type,
14284 field = option.field,
14285 scaleConfig = option.scale;
14286
14287 if (isNil(field) || type === Identity$2) {
14288 return new Identity$2(option);
14289 }
14290
14291 var scale = this.scaleController.getScale(field);
14292
14293 var attrOption = _objectSpread(_objectSpread({}, option), {}, {
14294 data: this.scaleController.getData(),
14295 // scaleConfig 只在属性映射中生效
14296 scale: scaleConfig ? cloneScale(scale, scaleConfig) : scale
14297 }); // identity
14298
14299
14300 if (scale && scale.type === 'identity') {
14301 return new Identity$2(attrOption);
14302 } // Attr的默认类型和scale类型保持一致
14303
14304
14305 var AttrConstructor = scale.isLinear ? Linear$2 : Category$2; // custom Attr Constructor
14306
14307 if (isFunction(type)) {
14308 AttrConstructor = type;
14309 }
14310
14311 if (isString(type) && Attrs[upperFirst(type)]) {
14312 AttrConstructor = Attrs[upperFirst(type)];
14313 }
14314
14315 return new AttrConstructor(attrOption);
14316 }
14317 }, {
14318 key: "create",
14319 value: function create(options) {
14320 this.update(options);
14321 }
14322 }, {
14323 key: "update",
14324 value: function update(nextOptions) {
14325 var scaleController = this.scaleController,
14326 lastOptions = this.options,
14327 lastAttrs = this.attrs;
14328 var nextAttrs = {};
14329 each(nextOptions, function (nextOption, attrName) {
14330 var lastOption = lastOptions[attrName];
14331
14332 if (equal(nextOption, lastOption)) {
14333 nextAttrs[attrName] = lastAttrs[attrName];
14334 }
14335
14336 var field = nextOption.field,
14337 justifyContent = nextOption.justifyContent;
14338
14339 if (field) {
14340 scaleController.setScale(field, {
14341 justifyContent: justifyContent
14342 });
14343 }
14344 });
14345 this.options = nextOptions;
14346 this.attrs = nextAttrs;
14347 }
14348 }, {
14349 key: "getAttr",
14350 value: function getAttr(attrName) {
14351 var attrs = this.attrs,
14352 options = this.options;
14353 var attr = attrs[attrName];
14354
14355 if (attr) {
14356 return attr;
14357 }
14358
14359 var option = options[attrName];
14360
14361 if (!option) {
14362 return null;
14363 }
14364
14365 var newAttr = this.createAttr(option);
14366 attrs[attrName] = newAttr;
14367 return newAttr;
14368 }
14369 }, {
14370 key: "getAttrs",
14371 value: function getAttrs() {
14372 var _this2 = this;
14373
14374 var options = this.options,
14375 attrs = this.attrs;
14376 each(options, function (option, attrName) {
14377 _this2.getAttr(attrName);
14378 });
14379 return attrs;
14380 }
14381 }, {
14382 key: "isGroupAttr",
14383 value: function isGroupAttr(attrName) {
14384 return GROUP_ATTRS.indexOf(attrName) !== -1;
14385 }
14386 }, {
14387 key: "getAttrsByLinear",
14388 value: function getAttrsByLinear() {
14389 var attrs = this.attrs;
14390 var attrNames = Object.keys(attrs);
14391 var linearAttrs = [];
14392 var nonlinearAttrs = [];
14393 attrNames.forEach(function (attrName) {
14394 if (attrName === 'x' || attrName === 'y') {
14395 linearAttrs.push(attrName);
14396 return;
14397 }
14398
14399 var scale = attrs[attrName].scale;
14400
14401 if (scale && scale.type === 'linear') {
14402 linearAttrs.push(attrName);
14403 } else {
14404 nonlinearAttrs.push(attrName);
14405 }
14406 });
14407 return {
14408 linearAttrs: linearAttrs,
14409 nonlinearAttrs: nonlinearAttrs
14410 };
14411 }
14412 }]);
14413
14414 return AttrController;
14415 }();
14416
14417 var _excluded$3 = ["field"];
14418
14419 var FIELD_ORIGIN = 'origin';
14420
14421 var Geometry = /*#__PURE__*/function (_Selection) {
14422 _inherits(Geometry, _Selection);
14423
14424 var _super = _createSuper(Geometry);
14425
14426 function Geometry(props, context) {
14427 var _this;
14428
14429 _classCallCheck(this, Geometry);
14430
14431 _this = _super.call(this, props, context);
14432 _this.isGeometry = true; // x 轴居中
14433
14434 _this.justifyContent = false; // y 轴是否从0开始
14435
14436 _this.startOnZero = false; // 是否连接空值
14437
14438 _this.connectNulls = false; // 是否需要排序
14439
14440 _this.sortable = false;
14441 mix(_assertThisInitialized(_this), _this.getDefaultCfg());
14442 var chart = props.chart,
14443 coord = props.coord;
14444
14445 var attrsRange = _this._getThemeAttrsRange();
14446
14447 _this.attrController = new AttrController(chart.scale, attrsRange);
14448
14449 var _assertThisInitialize = _assertThisInitialized(_this),
14450 attrController = _assertThisInitialize.attrController,
14451 justifyContent = _assertThisInitialize.justifyContent;
14452
14453 var attrOptions = attrController.getAttrOptions(props, !coord.isCyclic() || justifyContent);
14454 attrController.create(attrOptions);
14455 return _this;
14456 }
14457
14458 _createClass(Geometry, [{
14459 key: "getDefaultCfg",
14460 value: function getDefaultCfg() {
14461 return {};
14462 }
14463 }, {
14464 key: "willReceiveProps",
14465 value: function willReceiveProps(nextProps) {
14466 _get$1(_getPrototypeOf(Geometry.prototype), "willReceiveProps", this).call(this, nextProps);
14467
14468 var lastProps = this.props,
14469 attrController = this.attrController,
14470 justifyContent = this.justifyContent;
14471 var nextData = nextProps.data,
14472 nextAdjust = nextProps.adjust,
14473 nextZoomRange = nextProps.zoomRange,
14474 coord = nextProps.coord;
14475 var lastData = lastProps.data,
14476 lastAdjust = lastProps.adjust,
14477 lastZoomRange = lastProps.zoomRange;
14478 var justifyContentCenter = !coord.isCyclic() || justifyContent;
14479 var nextAttrOptions = attrController.getAttrOptions(nextProps, justifyContentCenter);
14480 var lastAttrOptions = attrController.getAttrOptions(lastProps, justifyContentCenter);
14481
14482 if (!equal(nextAttrOptions, lastAttrOptions)) {
14483 attrController.update(nextAttrOptions);
14484 this.records = null;
14485 } // 重新处理数据
14486
14487
14488 if (nextData !== lastData) {
14489 this.records = null;
14490 } // 重新处理数据
14491
14492
14493 if (nextAdjust !== lastAdjust) {
14494 this.records = null;
14495 } // zoomRange发生变化,records也需要重新计算
14496
14497
14498 if (!equal(nextZoomRange, lastZoomRange)) {
14499 this.records = null;
14500 }
14501 }
14502 }, {
14503 key: "willMount",
14504 value: function willMount() {
14505 this._createAttrs();
14506
14507 if (!this.records) {
14508 this._processData();
14509 }
14510 }
14511 }, {
14512 key: "willUpdate",
14513 value: function willUpdate() {
14514 this._createAttrs();
14515
14516 if (!this.records) {
14517 this._processData();
14518 }
14519 }
14520 }, {
14521 key: "didMount",
14522 value: function didMount() {
14523 _get$1(_getPrototypeOf(Geometry.prototype), "didMount", this).call(this);
14524
14525 this._initEvent();
14526 }
14527 }, {
14528 key: "_createAttrs",
14529 value: function _createAttrs() {
14530 var attrController = this.attrController;
14531 attrController.attrs = {};
14532 this.attrs = attrController.getAttrs();
14533 }
14534 }, {
14535 key: "_getThemeAttrsRange",
14536 value: function _getThemeAttrsRange() {
14537 var context = this.context,
14538 props = this.props,
14539 geomType = this.geomType;
14540 var coord = props.coord;
14541 var theme = context.theme;
14542 var colors = theme.colors,
14543 sizes = theme.sizes,
14544 shapes = theme.shapes;
14545 return {
14546 x: coord.x,
14547 y: coord.y,
14548 color: colors,
14549 size: sizes,
14550 shape: shapes[geomType]
14551 };
14552 }
14553 }, {
14554 key: "_adjustScales",
14555 value: function _adjustScales() {
14556 var attrs = this.attrs,
14557 props = this.props,
14558 defaultStartOnZero = this.startOnZero;
14559 var chart = props.chart,
14560 _props$startOnZero = props.startOnZero,
14561 startOnZero = _props$startOnZero === void 0 ? defaultStartOnZero : _props$startOnZero,
14562 coord = props.coord,
14563 adjust = props.adjust;
14564 var isPolar = coord.isPolar,
14565 transposed = coord.transposed;
14566 var y = attrs.y;
14567 var yField = y.field; // 如果从 0 开始,只调整 y 轴 scale
14568
14569 if (startOnZero) {
14570 var _y = attrs.y;
14571 chart.scale.adjustStartZero(_y.scale);
14572 } // 饼图的scale调整,关闭nice
14573
14574
14575 if (isPolar && transposed && (adjust === 'stack' || (adjust === null || adjust === void 0 ? void 0 : adjust.type) === 'stack')) {
14576 var _y2 = attrs.y;
14577 chart.scale.adjustPieScale(_y2.scale);
14578 }
14579
14580 if (adjust === 'stack' || (adjust === null || adjust === void 0 ? void 0 : adjust.type) === 'stack') {
14581 this._updateStackRange(yField, y.scale, this.dataArray);
14582 }
14583 }
14584 }, {
14585 key: "_groupData",
14586 value: function _groupData(data) {
14587 var attrController = this.attrController;
14588 var groupScales = attrController.getGroupScales();
14589
14590 if (!groupScales.length) {
14591 return [{
14592 children: data
14593 }];
14594 }
14595
14596 var names = [];
14597 groupScales.forEach(function (scale) {
14598 var field = scale.field;
14599 names.push(field);
14600 });
14601 var groups = groupToMap(data, names);
14602 var records = [];
14603
14604 for (var key in groups) {
14605 records.push({
14606 key: key.replace(/^_/, ''),
14607 children: groups[key]
14608 });
14609 }
14610
14611 return records;
14612 }
14613 }, {
14614 key: "_saveOrigin",
14615 value: function _saveOrigin(originData) {
14616 var len = originData.length;
14617 var data = new Array(len);
14618
14619 for (var i = 0; i < len; i++) {
14620 var record = originData[i];
14621 data[i] = _objectSpread(_objectSpread({}, record), {}, _defineProperty({}, FIELD_ORIGIN, record));
14622 }
14623
14624 return data;
14625 }
14626 }, {
14627 key: "_numberic",
14628 value: function _numberic(data) {
14629 var attrs = this.attrs;
14630 var scales = [attrs.x.scale, attrs.y.scale];
14631
14632 for (var j = 0, len = data.length; j < len; j++) {
14633 var obj = data[j];
14634 var count = scales.length;
14635
14636 for (var i = 0; i < count; i++) {
14637 var scale = scales[i];
14638
14639 if (scale.isCategory) {
14640 var field = scale.field;
14641 obj[field] = scale.translate(obj[field]);
14642 }
14643 }
14644 }
14645 }
14646 }, {
14647 key: "_adjustData",
14648 value: function _adjustData(records) {
14649 var attrs = this.attrs,
14650 props = this.props;
14651 var adjust = props.adjust; // groupedArray 是二维数组
14652
14653 var groupedArray = records.map(function (record) {
14654 return record.children;
14655 });
14656
14657 if (!adjust) {
14658 return groupedArray;
14659 }
14660
14661 var adjustCfg = typeof adjust === 'string' ? {
14662 type: adjust
14663 } : adjust;
14664 var adjustType = upperFirst(adjustCfg.type);
14665 var AdjustConstructor = getAdjust(adjustType);
14666
14667 if (!AdjustConstructor) {
14668 throw new Error('not support such adjust : ' + adjust);
14669 }
14670
14671 if (adjustType === 'Dodge') {
14672 for (var i = 0, len = groupedArray.length; i < len; i++) {
14673 // 如果是dodge, 需要处理数字再处理
14674 this._numberic(groupedArray[i]);
14675 }
14676
14677 adjustCfg.adjustNames = ['x'];
14678 }
14679
14680 var x = attrs.x,
14681 y = attrs.y;
14682 adjustCfg.xField = x.field;
14683 adjustCfg.yField = y.field;
14684 var adjustInstance = new AdjustConstructor(adjustCfg);
14685 var adjustData = adjustInstance.process(groupedArray);
14686 this.adjust = {
14687 type: adjustCfg.type,
14688 adjust: adjustInstance
14689 }; // process 返回的是新数组,所以要修改 records
14690
14691 records.forEach(function (record, index) {
14692 record.children = adjustData[index];
14693 });
14694 return adjustData;
14695 }
14696 }, {
14697 key: "_updateStackRange",
14698 value: function _updateStackRange(field, scale, dataArray) {
14699 var flattenArray = flatten(dataArray);
14700 var min = Infinity;
14701 var max = -Infinity;
14702
14703 for (var i = 0, len = flattenArray.length; i < len; i++) {
14704 var obj = flattenArray[i];
14705 var tmpMin = Math.min.apply(null, obj[field]);
14706 var tmpMax = Math.max.apply(null, obj[field]);
14707
14708 if (tmpMin < min) {
14709 min = tmpMin;
14710 }
14711
14712 if (tmpMax > max) {
14713 max = tmpMax;
14714 }
14715 }
14716
14717 if (min !== scale.min || max !== scale.max) {
14718 scale.change({
14719 min: min,
14720 max: max
14721 });
14722 }
14723 }
14724 }, {
14725 key: "_processData",
14726 value: function _processData() {
14727 var props = this.props;
14728 var originData = props.data;
14729
14730 var data = this._saveOrigin(originData); // 根据分类度量进行数据分组
14731
14732
14733 var records = this._groupData(data); // 根据adjust分组
14734
14735
14736 var dataArray = this._adjustData(records);
14737
14738 this.dataArray = dataArray; // scale适配调整,主要是调整 y 轴是否从 0 开始 以及 饼图
14739
14740 this._adjustScales(); // 数据排序(非必须)
14741
14742
14743 if (this.sortable) {
14744 this._sortData(records);
14745 }
14746
14747 this.records = records;
14748 }
14749 }, {
14750 key: "_sortData",
14751 value: function _sortData(records) {
14752 var xScale = this.getXScale();
14753 var field = xScale.field,
14754 type = xScale.type;
14755
14756 if (type !== 'identity' && xScale.values.length > 1) {
14757 each(records, function (_ref) {
14758 var children = _ref.children;
14759 children.sort(function (record1, record2) {
14760 if (type === 'timeCat') {
14761 return toTimeStamp(record1[FIELD_ORIGIN][field]) - toTimeStamp(record2[FIELD_ORIGIN][field]);
14762 }
14763
14764 return xScale.translate(record1[FIELD_ORIGIN][field]) - xScale.translate(record2[FIELD_ORIGIN][field]);
14765 });
14766 });
14767 }
14768 }
14769 }, {
14770 key: "_initEvent",
14771 value: function _initEvent() {
14772 var _this2 = this;
14773
14774 var container = this.container,
14775 props = this.props;
14776 var canvas = container.get('canvas');
14777 ['onPressStart', 'onPress', 'onPressEnd', 'onPan', 'onPanStart', 'onPanEnd'].forEach(function (eventName) {
14778 if (props[eventName]) {
14779 canvas.on(eventName.substr(2).toLowerCase(), function (ev) {
14780 ev.geometry = _this2;
14781 props[eventName](ev);
14782 });
14783 }
14784 });
14785 }
14786 }, {
14787 key: "getY0Value",
14788 value: function getY0Value() {
14789 var attrs = this.attrs,
14790 props = this.props;
14791 var chart = props.chart;
14792 var field = attrs.y.field;
14793 var scale = chart.getScale(field);
14794 return chart.scale.getZeroValue(scale);
14795 } // 根据各属性映射的值域来获取真正的绘图属性
14796
14797 }, {
14798 key: "_getShapeStyle",
14799 value: function _getShapeStyle(shape, origin) {
14800 var context = this.context,
14801 props = this.props,
14802 geomType = this.geomType;
14803 var theme = context.theme;
14804 var shapeTheme = theme.shape[geomType] || {};
14805 var defaultShapeStyle = shapeTheme.default;
14806 var shapeThemeStyle = shapeTheme[shape];
14807 var style = props.style;
14808
14809 var shapeStyle = _objectSpread(_objectSpread({}, defaultShapeStyle), shapeThemeStyle);
14810
14811 if (!style || !isObject(style)) {
14812 return shapeStyle;
14813 } // @ts-ignore
14814
14815
14816 var field = style.field,
14817 styles = _objectWithoutProperties(style, _excluded$3);
14818
14819 var value = field ? origin[field] : origin;
14820 each(styles, function (attr, key) {
14821 if (isFunction(attr)) {
14822 shapeStyle[key] = attr(value);
14823 } else {
14824 shapeStyle[key] = attr;
14825 }
14826 });
14827 return shapeStyle;
14828 }
14829 /**
14830 * 数据映射到视图属性核心逻辑
14831 * x、y 每个元素走 normalize 然后 convertPoint
14832 * color、size、shape
14833 * 如果是Linear,则每个元素 走 mapping
14834 * 如果是Category/Identity 则第一个元素走 mapping
14835 */
14836
14837 }, {
14838 key: "_mapping",
14839 value: function _mapping(records) {
14840 var attrs = this.attrs,
14841 props = this.props,
14842 attrController = this.attrController;
14843 var coord = props.coord;
14844
14845 var _attrController$getAt = attrController.getAttrsByLinear(),
14846 linearAttrs = _attrController$getAt.linearAttrs,
14847 nonlinearAttrs = _attrController$getAt.nonlinearAttrs;
14848
14849 var defaultAttrValues = attrController.getDefaultAttrValues();
14850
14851 for (var i = 0, len = records.length; i < len; i++) {
14852 var record = records[i];
14853 var children = record.children;
14854
14855 var attrValues = _objectSpread({}, defaultAttrValues);
14856
14857 var firstChild = children[0];
14858
14859 if (children.length === 0) {
14860 continue;
14861 } // 非线性映射
14862
14863
14864 for (var k = 0, _len = nonlinearAttrs.length; k < _len; k++) {
14865 var attrName = nonlinearAttrs[k];
14866 var attr = attrs[attrName]; // 非线性映射只用映射第一项就可以了
14867
14868 attrValues[attrName] = attr.mapping(firstChild[attr.field]);
14869 } // 线性属性映射
14870
14871
14872 for (var j = 0, childrenLen = children.length; j < childrenLen; j++) {
14873 var child = children[j];
14874 var normalized = {};
14875
14876 for (var _k = 0; _k < linearAttrs.length; _k++) {
14877 var _attrName = linearAttrs[_k];
14878 var _attr = attrs[_attrName]; // 分类属性的线性映射
14879
14880 if (attrController.isGroupAttr(_attrName)) {
14881 attrValues[_attrName] = _attr.mapping(child[_attr.field], child);
14882 } else {
14883 normalized[_attrName] = _attr.normalize(child[_attr.field]);
14884 }
14885 }
14886
14887 var _coord$convertPoint = coord.convertPoint({
14888 x: normalized.x,
14889 y: normalized.y
14890 }),
14891 x = _coord$convertPoint.x,
14892 y = _coord$convertPoint.y; // 获取 shape 的 style
14893
14894
14895 var shapeName = attrValues.shape;
14896
14897 var shape = this._getShapeStyle(shapeName, child.origin);
14898
14899 var selected = this.isSelected(child);
14900 mix(child, attrValues, {
14901 normalized: normalized,
14902 x: x,
14903 y: y,
14904 shapeName: shapeName,
14905 shape: shape,
14906 selected: selected
14907 });
14908 }
14909 }
14910
14911 return records;
14912 } // 数据映射
14913
14914 }, {
14915 key: "mapping",
14916 value: function mapping() {
14917 var records = this.records; // 数据映射
14918
14919 this._mapping(records);
14920
14921 return records;
14922 }
14923 }, {
14924 key: "getClip",
14925 value: function getClip() {
14926 var _this$props = this.props,
14927 coord = _this$props.coord,
14928 viewClip = _this$props.viewClip;
14929 var contentWidth = coord.width,
14930 contentHeight = coord.height,
14931 left = coord.left,
14932 top = coord.top;
14933
14934 if (viewClip) {
14935 return {
14936 type: 'rect',
14937 attrs: {
14938 x: left,
14939 y: top,
14940 width: contentWidth,
14941 height: contentHeight
14942 }
14943 };
14944 }
14945
14946 return null;
14947 }
14948 }, {
14949 key: "getAttr",
14950 value: function getAttr(attrName) {
14951 return this.attrController.getAttr(attrName);
14952 }
14953 }, {
14954 key: "getXScale",
14955 value: function getXScale() {
14956 return this.getAttr('x').scale;
14957 }
14958 }, {
14959 key: "getYScale",
14960 value: function getYScale() {
14961 return this.getAttr('y').scale;
14962 }
14963 }, {
14964 key: "_getXSnap",
14965 value: function _getXSnap(invertPointX) {
14966 var xScale = this.getXScale();
14967
14968 if (xScale.isCategory) {
14969 return xScale.invert(invertPointX);
14970 } // linear 类型
14971
14972
14973 var invertValue = xScale.invert(invertPointX);
14974 var values = xScale.values;
14975 var len = values.length; // 如果只有1个点直接返回第1个点
14976
14977 if (len === 1) {
14978 return values[0];
14979 } // 第1个点和第2个点之间
14980
14981
14982 if ((values[0] + values[1]) / 2 > invertValue) {
14983 return values[0];
14984 } // 最后2个点
14985
14986
14987 if ((values[len - 2] + values[len - 1]) / 2 <= invertValue) {
14988 return values[len - 1];
14989 }
14990
14991 for (var i = 1; i < len; i++) {
14992 // 中间的点
14993 if ((values[i - 1] + values[i]) / 2 <= invertValue && (values[i + 1] + values[i]) / 2 > invertValue) {
14994 return values[i];
14995 }
14996 }
14997
14998 return null;
14999 }
15000 }, {
15001 key: "_getYSnapRecords",
15002 value: function _getYSnapRecords(invertPointY, records) {
15003 var yScale = this.getYScale();
15004 var yField = yScale.field;
15005 var yValue = yScale.invert(invertPointY); // category
15006
15007 if (yScale.isCategory) {
15008 return records.filter(function (record) {
15009 return record[FIELD_ORIGIN][yField] === yValue;
15010 });
15011 } // linear
15012
15013
15014 return records.filter(function (record) {
15015 var rangeY = record[yField];
15016
15017 if (rangeY[0] <= yValue && rangeY[1] >= yValue) {
15018 return true;
15019 }
15020
15021 return false;
15022 });
15023 } // 把 records 拍平
15024
15025 }, {
15026 key: "flatRecords",
15027 value: function flatRecords() {
15028 var records = this.records;
15029 return records.reduce(function (prevRecords, record) {
15030 return prevRecords.concat(record.children);
15031 }, []);
15032 }
15033 }, {
15034 key: "getSnapRecords",
15035 value: function getSnapRecords(point, inCoordRange) {
15036 var props = this.props;
15037 var coord = props.coord,
15038 adjust = props.adjust;
15039 var invertPoint = coord.invertPoint(point);
15040 var xScale = this.getXScale();
15041 var yScale = this.getYScale(); // 如果不在coord坐标范围内,直接返回空
15042 // if (invertPoint.x < 0 || invertPoint.y < 0) {
15043 // return [];
15044 // }
15045 // 是否调整 point,默认为不调整
15046
15047 if (inCoordRange) {
15048 var xRange = xScale.range;
15049 var yRange = yScale.range; // 如果 inCoordRange=true,当 point 不在 coord 坐标范围内时,调整到 range 内
15050
15051 invertPoint.x = Math.min(Math.max(invertPoint.x, xRange[0]), xRange[1]);
15052 invertPoint.y = Math.min(Math.max(invertPoint.y, yRange[0]), yRange[1]);
15053 }
15054
15055 var records = this.flatRecords(); // 处理饼图
15056
15057 if (adjust === 'stack' && coord.isPolar && coord.transposed) {
15058 // 弧度在半径范围内
15059 if (invertPoint.x >= 0 && invertPoint.x <= 1) {
15060 var snapRecords = this._getYSnapRecords(invertPoint.y, records);
15061
15062 return snapRecords;
15063 }
15064 }
15065
15066 var rst = [];
15067
15068 var value = this._getXSnap(invertPoint.x);
15069
15070 if (!value) {
15071 return rst;
15072 }
15073
15074 var xField = xScale.field;
15075 var yField = yScale.field;
15076
15077 for (var i = 0, len = records.length; i < len; i++) {
15078 var record = _objectSpread(_objectSpread({}, records[i]), {}, {
15079 xField: xField,
15080 yField: yField
15081 });
15082
15083 var originValue = record[FIELD_ORIGIN][xField];
15084
15085 if (xScale.type === 'timeCat' && toTimeStamp(originValue) === value) {
15086 rst.push(record);
15087 } else if (originValue === value) {
15088 rst.push(record);
15089 }
15090 }
15091
15092 return rst;
15093 }
15094 }, {
15095 key: "getLegendItems",
15096 value: function getLegendItems() {
15097 var attrController = this.attrController;
15098 var colorAttr = attrController.getAttr('color');
15099 if (!colorAttr) return null;
15100 var scale = colorAttr.scale;
15101 if (!scale.isCategory) return null;
15102 var ticks = scale.getTicks();
15103 var items = ticks.map(function (tick) {
15104 var text = tick.text,
15105 tickValue = tick.tickValue;
15106 var color = colorAttr.mapping(tickValue);
15107 return {
15108 field: scale.field,
15109 color: color,
15110 name: text,
15111 tickValue: tickValue
15112 };
15113 });
15114 return items;
15115 }
15116 }]);
15117
15118 return Geometry;
15119 }(Selection);
15120
15121 var arrayWithoutHoles = createCommonjsModule(function (module) {
15122 function _arrayWithoutHoles(arr) {
15123 if (Array.isArray(arr)) return arrayLikeToArray(arr);
15124 }
15125
15126 module.exports = _arrayWithoutHoles, module.exports.__esModule = true, module.exports["default"] = module.exports;
15127 });
15128
15129 var iterableToArray = createCommonjsModule(function (module) {
15130 function _iterableToArray(iter) {
15131 if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
15132 }
15133
15134 module.exports = _iterableToArray, module.exports.__esModule = true, module.exports["default"] = module.exports;
15135 });
15136
15137 var nonIterableSpread = createCommonjsModule(function (module) {
15138 function _nonIterableSpread() {
15139 throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
15140 }
15141
15142 module.exports = _nonIterableSpread, module.exports.__esModule = true, module.exports["default"] = module.exports;
15143 });
15144
15145 var toConsumableArray = createCommonjsModule(function (module) {
15146 function _toConsumableArray(arr) {
15147 return arrayWithoutHoles(arr) || iterableToArray(arr) || unsupportedIterableToArray(arr) || nonIterableSpread();
15148 }
15149
15150 module.exports = _toConsumableArray, module.exports.__esModule = true, module.exports["default"] = module.exports;
15151 });
15152
15153 var _toConsumableArray = /*@__PURE__*/getDefaultExportFromCjs(toConsumableArray);
15154
15155 var withLine = (function (View) {
15156 return /*#__PURE__*/function (_Geometry) {
15157 _inherits(Line, _Geometry);
15158
15159 var _super = _createSuper(Line);
15160
15161 function Line() {
15162 _classCallCheck(this, Line);
15163
15164 return _super.apply(this, arguments);
15165 }
15166
15167 _createClass(Line, [{
15168 key: "getDefaultCfg",
15169 value: function getDefaultCfg() {
15170 return {
15171 geomType: 'line',
15172 sortable: true
15173 };
15174 }
15175 }, {
15176 key: "splitPoints",
15177 value: function splitPoints(points) {
15178 var topPoints = [];
15179 var bottomPoints = [];
15180
15181 for (var i = 0, len = points.length; i < len; i++) {
15182 var point = points[i];
15183 var x = point.x,
15184 y = point.y;
15185 topPoints.push(_objectSpread(_objectSpread({}, point), {}, {
15186 x: x,
15187 y: y[1]
15188 }));
15189 bottomPoints.push(_objectSpread(_objectSpread({}, point), {}, {
15190 x: x,
15191 y: y[0]
15192 }));
15193 }
15194
15195 return [topPoints, bottomPoints];
15196 }
15197 }, {
15198 key: "splitNulls",
15199 value: function splitNulls(points, connectNulls) {
15200 if (connectNulls) {
15201 var _tmpPoints = [];
15202
15203 for (var i = 0, len = points.length; i < len; i++) {
15204 var point = points[i];
15205 var y = point.y;
15206
15207 if (isArray(y)) {
15208 if (isNaN(y[0])) {
15209 continue;
15210 }
15211
15212 _tmpPoints.push(point);
15213
15214 continue;
15215 }
15216
15217 if (isNaN(y)) {
15218 continue;
15219 }
15220
15221 _tmpPoints.push(point);
15222 }
15223
15224 if (_tmpPoints.length) {
15225 return [_tmpPoints];
15226 }
15227
15228 return [];
15229 }
15230
15231 var result = [];
15232 var tmpPoints = [];
15233
15234 for (var _i = 0, _len = points.length; _i < _len; _i++) {
15235 var _point = points[_i];
15236 var _y = _point.y;
15237
15238 if (isArray(_y)) {
15239 if (isNaN(_y[0])) {
15240 if (tmpPoints.length) {
15241 result.push(tmpPoints);
15242 tmpPoints = [];
15243 }
15244
15245 continue;
15246 }
15247
15248 tmpPoints.push(_point);
15249 continue;
15250 }
15251
15252 if (isNaN(_y)) {
15253 if (tmpPoints.length) {
15254 result.push(tmpPoints);
15255 tmpPoints = [];
15256 }
15257
15258 continue;
15259 }
15260
15261 tmpPoints.push(_point);
15262 }
15263
15264 if (tmpPoints.length) {
15265 result.push(tmpPoints);
15266 }
15267
15268 return result;
15269 }
15270 }, {
15271 key: "mapping",
15272 value: function mapping() {
15273 var _this = this;
15274
15275 var records = _get$1(_getPrototypeOf(Line.prototype), "mapping", this).call(this);
15276
15277 var props = this.props,
15278 defaultConnectNulls = this.connectNulls;
15279 var coord = props.coord,
15280 _props$connectNulls = props.connectNulls,
15281 connectNulls = _props$connectNulls === void 0 ? defaultConnectNulls : _props$connectNulls;
15282 return records.map(function (record) {
15283 var children = record.children; // children 有可能为空
15284
15285 var _ref = children[0] || {},
15286 size = _ref.size,
15287 color = _ref.color,
15288 shape = _ref.shape,
15289 y = _ref.y; // 极坐标时,需加入起点,从而闭合所绘图形
15290
15291
15292 var points = coord.isPolar ? [].concat(_toConsumableArray(children), [children[0]]) : children;
15293
15294 var splitPoints = _this.splitNulls(points, connectNulls);
15295
15296 var newChildren = splitPoints.map(function (points) {
15297 var _ref2 = isArray(y) ? _this.splitPoints(points) : [points, undefined],
15298 _ref3 = _slicedToArray(_ref2, 2),
15299 topPoints = _ref3[0],
15300 bottomPoints = _ref3[1];
15301
15302 return {
15303 size: size,
15304 color: color,
15305 shape: shape,
15306 points: topPoints,
15307 bottomPoints: bottomPoints
15308 };
15309 });
15310 return _objectSpread(_objectSpread({}, record), {}, {
15311 children: newChildren
15312 });
15313 });
15314 }
15315 }, {
15316 key: "render",
15317 value: function render() {
15318 var props = this.props;
15319 var coord = props.coord;
15320 var records = this.mapping();
15321 var clip = this.getClip();
15322 return jsx(View, _objectSpread(_objectSpread({}, props), {}, {
15323 coord: coord,
15324 records: records,
15325 clip: clip
15326 }));
15327 }
15328 }]);
15329
15330 return Line;
15331 }(Geometry);
15332 });
15333
15334 function concatPoints(children) {
15335 var result = [];
15336
15337 for (var i = 0; i < children.length; i++) {
15338 var child = children[i];
15339 result = result.concat(child.points);
15340 }
15341
15342 return result;
15343 }
15344
15345 function formatPoint(point) {
15346 var y = point.y;
15347 return {
15348 x: point.x,
15349 y: isArray(y) ? y[1] : y
15350 };
15351 }
15352
15353 function getPoint$1(points, t) {
15354 var formatedPoints = points.map(function (p) {
15355 return formatPoint(p);
15356 });
15357 var firstPoint = formatedPoints[0];
15358 var lastPoint = formatedPoints[formatedPoints.length - 1];
15359 var xOffset = lastPoint.x - firstPoint.x;
15360 var x = firstPoint.x + xOffset * t;
15361
15362 for (var i = 1; i < formatedPoints.length; i++) {
15363 var point = formatedPoints[i];
15364 var prevPoint = formatedPoints[i - 1];
15365
15366 if (x >= prevPoint.x && x <= point.x) {
15367 // x 在 2 点之间的比例,根据比例再算出 y 的值
15368 var ratio = (x - prevPoint.x) / (point.x - prevPoint.x);
15369 return {
15370 x: x,
15371 y: prevPoint.y + (point.y - prevPoint.y) * ratio
15372 };
15373 }
15374 }
15375 }
15376
15377 function AnimationEndView(props) {
15378 var record = props.record,
15379 appear = props.appear,
15380 EndView = props.EndView;
15381 var children = record.children;
15382 var points = concatPoints(children);
15383 var origin = points[0].origin;
15384 return jsx("group", {
15385 animation: {
15386 appear: {
15387 easing: appear.easing,
15388 duration: appear.duration,
15389 onFrame: function onFrame(t) {
15390 // 这段逻辑有点恶心。。
15391 var element = this.element;
15392 var children = element.get('children');
15393 var point = getPoint$1(points, t);
15394 children.forEach(function (child) {
15395 child.moveTo(point.x, point.y);
15396 });
15397 }
15398 }
15399 }
15400 }, jsx(EndView, {
15401 origin: origin
15402 }));
15403 }
15404
15405 var LineView = (function (props) {
15406 var records = props.records,
15407 coord = props.coord,
15408 animation = props.animation,
15409 EndView = props.endView,
15410 clip = props.clip;
15411 var left = coord.left,
15412 top = coord.top,
15413 width = coord.width,
15414 height = coord.height,
15415 center = coord.center,
15416 startAngle = coord.startAngle,
15417 endAngle = coord.endAngle,
15418 radius = coord.radius;
15419 var appear = coord.isPolar ? {
15420 easing: 'quadraticOut',
15421 duration: 450,
15422 clip: {
15423 type: 'sector',
15424 property: ['endAngle'],
15425 attrs: {
15426 x: center.x,
15427 y: center.y,
15428 startAngle: startAngle,
15429 r: radius
15430 },
15431 start: {
15432 endAngle: startAngle
15433 },
15434 end: {
15435 endAngle: endAngle
15436 }
15437 }
15438 } : {
15439 easing: 'quadraticOut',
15440 duration: 450,
15441 clip: {
15442 type: 'rect',
15443 property: ['width'],
15444 attrs: {
15445 x: left,
15446 y: top,
15447 height: height
15448 },
15449 start: {
15450 width: 0
15451 },
15452 end: {
15453 width: width
15454 }
15455 }
15456 };
15457 return jsx("group", {
15458 attrs: {
15459 clip: clip
15460 }
15461 }, records.map(function (record) {
15462 var key = record.key,
15463 children = record.children;
15464 return jsx("group", {
15465 key: key
15466 }, children.map(function (child) {
15467 var points = child.points,
15468 color = child.color,
15469 size = child.size,
15470 shape = child.shape;
15471 return jsx("polyline", {
15472 attrs: _objectSpread(_objectSpread({
15473 points: points.map(function (point) {
15474 return {
15475 x: point.x,
15476 y: point.y
15477 };
15478 }),
15479 stroke: color
15480 }, shape), {}, {
15481 lineWidth: size || shape.lineWidth
15482 }),
15483 animation: deepMix({
15484 update: {
15485 easing: 'linear',
15486 duration: 450,
15487 property: ['points']
15488 },
15489 appear: appear
15490 }, animation)
15491 });
15492 }), EndView ? jsx(AnimationEndView, {
15493 record: record,
15494 EndView: EndView,
15495 appear: appear
15496 }) : null);
15497 }));
15498 });
15499
15500 var index = withLine(LineView);
15501
15502 var withArea = (function (View) {
15503 return /*#__PURE__*/function (_withLine) {
15504 _inherits(Area, _withLine);
15505
15506 var _super = _createSuper(Area);
15507
15508 function Area() {
15509 _classCallCheck(this, Area);
15510
15511 return _super.apply(this, arguments);
15512 }
15513
15514 _createClass(Area, [{
15515 key: "getDefaultCfg",
15516 value: function getDefaultCfg() {
15517 return {
15518 geomType: 'area',
15519 // 面积图默认设为从0开始
15520 startOnZero: true,
15521 // 点需要排序
15522 sortable: true
15523 };
15524 }
15525 }, {
15526 key: "mapping",
15527 value: function mapping() {
15528 var records = _get$1(_getPrototypeOf(Area.prototype), "mapping", this).call(this); // 坐标轴 y0
15529
15530
15531 var y0 = this.getY0Value();
15532 var props = this.props,
15533 defaultStartOnZero = this.startOnZero;
15534 var coord = props.coord,
15535 _props$startOnZero = props.startOnZero,
15536 startOnZero = _props$startOnZero === void 0 ? defaultStartOnZero : _props$startOnZero;
15537 var baseY = coord.y[0];
15538
15539 if (startOnZero) {
15540 // 零点映射到绝对坐标
15541 var originCoord = coord.convertPoint({
15542 x: 0,
15543 y: y0
15544 });
15545 baseY = originCoord.y;
15546 }
15547
15548 for (var i = 0, len = records.length; i < len; i++) {
15549 var record = records[i];
15550 var children = record.children;
15551
15552 for (var j = 0, _len = children.length; j < _len; j++) {
15553 var child = children[j];
15554 var points = child.points,
15555 bottomPoints = child.bottomPoints;
15556
15557 if (bottomPoints && bottomPoints.length) {
15558 bottomPoints.reverse();
15559 child.points = points.concat(bottomPoints);
15560 } else {
15561 points.push({
15562 x: points[points.length - 1].x,
15563 y: baseY
15564 });
15565 points.push({
15566 x: points[0].x,
15567 y: baseY
15568 });
15569 }
15570 }
15571 }
15572
15573 return records;
15574 }
15575 }]);
15576
15577 return Area;
15578 }(withLine(View));
15579 });
15580
15581 var AreaView = (function (props) {
15582 var coord = props.coord,
15583 records = props.records,
15584 shape = props.shape,
15585 animation = props.animation;
15586 var isSmooth = shape === 'smooth';
15587 var left = coord.left,
15588 top = coord.top,
15589 width = coord.width,
15590 height = coord.height,
15591 center = coord.center,
15592 startAngle = coord.startAngle,
15593 endAngle = coord.endAngle,
15594 radius = coord.radius;
15595 var appear = coord.isPolar ? {
15596 easing: 'quadraticOut',
15597 duration: 450,
15598 clip: {
15599 type: 'sector',
15600 property: ['endAngle'],
15601 attrs: {
15602 x: center.x,
15603 y: center.y,
15604 startAngle: startAngle,
15605 r: radius
15606 },
15607 start: {
15608 endAngle: startAngle
15609 },
15610 end: {
15611 endAngle: endAngle
15612 }
15613 }
15614 } : {
15615 easing: 'quadraticOut',
15616 duration: 450,
15617 clip: {
15618 type: 'rect',
15619 property: ['width'],
15620 attrs: {
15621 x: left,
15622 y: top,
15623 height: height
15624 },
15625 start: {
15626 width: 0
15627 },
15628 end: {
15629 width: width
15630 }
15631 }
15632 };
15633 return jsx("group", null, records.map(function (record) {
15634 var key = record.key,
15635 children = record.children;
15636 return jsx("group", {
15637 key: key
15638 }, children.map(function (child) {
15639 var points = child.points,
15640 bottomPoints = child.bottomPoints,
15641 color = child.color,
15642 shape = child.shape;
15643
15644 if (isSmooth) {
15645 return jsx("custom", {
15646 attrs: _objectSpread({
15647 points: points,
15648 lineWidth: '2px',
15649 fill: color
15650 }, shape),
15651 createPath: function createPath(context) {
15652 var constaint = [[0, 0], [1, 1]];
15653 var bottomPointsLen = (bottomPoints === null || bottomPoints === void 0 ? void 0 : bottomPoints.length) || 0;
15654 var topPoints = points.slice(0, points.length - bottomPointsLen);
15655 var topSps = catmullRom2bezier(topPoints, false, constaint);
15656 context.beginPath();
15657 context.moveTo(topPoints[0].x, topPoints[0].y);
15658
15659 for (var i = 0, n = topSps.length; i < n; i++) {
15660 var sp = topSps[i];
15661 context.bezierCurveTo(sp[1], sp[2], sp[3], sp[4], sp[5], sp[6]);
15662 }
15663
15664 if (bottomPointsLen) {
15665 var bottomSps = catmullRom2bezier(bottomPoints, false, constaint);
15666 context.lineTo(bottomPoints[0].x, bottomPoints[0].y);
15667
15668 for (var _i = 0, _n = bottomSps.length; _i < _n; _i++) {
15669 var _sp = bottomSps[_i];
15670 context.bezierCurveTo(_sp[1], _sp[2], _sp[3], _sp[4], _sp[5], _sp[6]);
15671 }
15672 }
15673
15674 context.closePath();
15675 },
15676 calculateBox: function calculateBox() {
15677 return getBBoxFromPoints(points);
15678 }
15679 });
15680 }
15681
15682 return jsx("polygon", {
15683 attrs: _objectSpread({
15684 points: points,
15685 lineWidth: '2px',
15686 fill: color
15687 }, shape),
15688 animation: deepMix({
15689 appear: appear,
15690 update: {
15691 easing: 'linear',
15692 duration: 450,
15693 property: ['points']
15694 }
15695 }, animation)
15696 });
15697 }));
15698 }));
15699 });
15700
15701 var index$1 = withArea(AreaView);
15702
15703 /**
15704 * 计算两个坐标的中点坐标
15705 * @param start 起始点{x:number, y:number}
15706 * @param end 结束点{x:number, y:number}
15707 * @returns 中点坐标{x:number, y:number}
15708 */
15709 function getMiddlePoint(start, end) {
15710 var x = (end.x - start.x) / 2 + start.x;
15711 var y = (end.y - start.y) / 2 + start.y;
15712 return {
15713 x: x,
15714 y: y
15715 };
15716 }
15717
15718 var DEFAULT_LABEL_CFG = {
15719 textBaseline: 'middle',
15720 fill: '#808080'
15721 };
15722 function LabelView(props) {
15723 var record = props.record,
15724 offsetX = props.offsetX,
15725 offsetY = props.offsetY,
15726 points = props.points,
15727 label = props.label,
15728 guide = props.guide;
15729 var origin = record.origin,
15730 color = record.color;
15731 var labelAttrs, guideAttrs;
15732
15733 if (isFunction(label)) {
15734 var point = points.length === 4 // 如果是金字塔图,顶部只有 3 个点
15735 ? getMiddlePoint(points[1], points[2]) : getMiddlePoint(points[0], points[1]);
15736 labelAttrs = mix({
15737 x: point.x + offsetX,
15738 y: point.y + offsetY
15739 }, DEFAULT_LABEL_CFG, label(origin, color));
15740 }
15741
15742 if (isFunction(guide)) {
15743 var _points$;
15744
15745 var _point = getMiddlePoint(points.length === 4 ? getMiddlePoint(points[0], points[1]) : points[0], getMiddlePoint(points[2], (_points$ = points[3]) !== null && _points$ !== void 0 ? _points$ : points[1]));
15746
15747 guideAttrs = mix({
15748 x: _point.x,
15749 y: _point.y,
15750 textBaseline: 'middle',
15751 textAlign: 'center'
15752 }, DEFAULT_LABEL_CFG, guide(origin, color));
15753 }
15754
15755 return jsx("group", null, labelAttrs && jsx("text", {
15756 attrs: labelAttrs
15757 }), guideAttrs && jsx("text", {
15758 attrs: guideAttrs
15759 }));
15760 }
15761
15762 var LabelViews = /*#__PURE__*/Object.freeze({
15763 __proto__: null,
15764 pyramid: LabelView,
15765 funnel: LabelView
15766 });
15767
15768 var withInterval = (function (Views) {
15769 return /*#__PURE__*/function (_Geometry) {
15770 _inherits(Interval, _Geometry);
15771
15772 var _super = _createSuper(Interval);
15773
15774 function Interval() {
15775 _classCallCheck(this, Interval);
15776
15777 return _super.apply(this, arguments);
15778 }
15779
15780 _createClass(Interval, [{
15781 key: "getDefaultCfg",
15782 value: function getDefaultCfg() {
15783 return {
15784 geomType: 'interval',
15785 justifyContent: true,
15786 startOnZero: true
15787 };
15788 }
15789 }, {
15790 key: "getDefaultSize",
15791 value: function getDefaultSize() {
15792 var attrs = this.attrs,
15793 props = this.props,
15794 adjust = this.adjust,
15795 records = this.records;
15796 var coord = props.coord,
15797 sizeRatio = props.sizeRatio;
15798 var x = attrs.x;
15799 var scale = x.scale;
15800 var values = scale.values;
15801
15802 if (sizeRatio) {
15803 return 1 / values.length * sizeRatio;
15804 }
15805
15806 var defaultWithRatio = {
15807 column: 1 / 2,
15808 rose: 0.999999,
15809 multiplePie: 3 / 4 // 多饼图
15810
15811 };
15812 var count = values.length;
15813 var ratio;
15814
15815 if (coord.isPolar) {
15816 if (coord.transposed && count > 1) {
15817 ratio = defaultWithRatio.multiplePie;
15818 } else {
15819 ratio = defaultWithRatio.rose;
15820 }
15821 } else {
15822 ratio = defaultWithRatio.column;
15823 }
15824
15825 var size = 1 / values.length * ratio; // 分组时size要除以类别个数
15826
15827 if (adjust && adjust.type === 'dodge') {
15828 return size / records.length;
15829 }
15830
15831 return size;
15832 }
15833 }, {
15834 key: "mapping",
15835 value: function mapping() {
15836 var records = _get$1(_getPrototypeOf(Interval.prototype), "mapping", this).call(this);
15837
15838 var props = this.props;
15839 var coord = props.coord;
15840 var y0 = this.getY0Value();
15841 var defaultSize = this.getDefaultSize();
15842
15843 for (var i = 0, len = records.length; i < len; i++) {
15844 var record = records[i];
15845 var children = record.children;
15846
15847 for (var j = 0, _len = children.length; j < _len; j++) {
15848 var child = children[j];
15849 var normalized = child.normalized,
15850 mappedSize = child.size; // 没有指定size,则根据数据来计算默认size
15851
15852 if (isNil(mappedSize)) {
15853 var x = normalized.x,
15854 y = normalized.y,
15855 _normalized$size = normalized.size,
15856 size = _normalized$size === void 0 ? defaultSize : _normalized$size;
15857 mix(child, coord.convertRect({
15858 x: x,
15859 y: y,
15860 y0: y0,
15861 size: size
15862 }));
15863 } else {
15864 var _x = child.x,
15865 _y = child.y;
15866 var rect = {
15867 size: mappedSize,
15868 x: _x,
15869 y: _y,
15870 y0: y0
15871 };
15872 mix(child, coord.transformToRect(rect));
15873 }
15874
15875 mix(child.shape, this.getSelectionStyle(child));
15876 }
15877 }
15878
15879 return records;
15880 } // 获取Y轴坐标零点的画布位置
15881
15882 }, {
15883 key: "getPointY0",
15884 value: function getPointY0() {
15885 var props = this.props;
15886 var coord = props.coord;
15887 var y0 = this.getY0Value();
15888 var y0Point = coord.convertPoint({
15889 y: y0,
15890 x: 0
15891 });
15892 return y0Point === null || y0Point === void 0 ? void 0 : y0Point.y;
15893 }
15894 }, {
15895 key: "render",
15896 value: function render() {
15897 var props = this.props,
15898 state = this.state,
15899 container = this.container;
15900 var coord = props.coord,
15901 _props$shape = props.shape,
15902 shape = _props$shape === void 0 ? 'rect' : _props$shape,
15903 animation = props.animation,
15904 showLabel = props.showLabel,
15905 customLabelCfg = props.labelCfg;
15906 var View = isFunction(Views) ? Views : Views[shape];
15907 var LabelView = LabelViews[shape];
15908 var labelCfg = deepMix({
15909 label: null,
15910 offsetX: 0,
15911 offsetY: 0
15912 }, customLabelCfg);
15913 if (!View) return null;
15914 var selected = state.selected;
15915 var records = this.mapping();
15916 var pointY0 = this.getPointY0();
15917 var clip = this.getClip();
15918 return jsx(View, {
15919 coord: coord,
15920 records: records,
15921 selected: selected,
15922 shape: shape,
15923 animation: animation,
15924 showLabel: showLabel,
15925 labelCfg: labelCfg,
15926 LabelView: LabelView,
15927 y0: pointY0,
15928 clip: clip
15929 });
15930 }
15931 }]);
15932
15933 return Interval;
15934 }(Geometry);
15935 });
15936
15937 var Rect$3 = (function (props) {
15938 var records = props.records,
15939 animation = props.animation,
15940 y0 = props.y0,
15941 clip = props.clip;
15942 return jsx("group", {
15943 attrs: {
15944 clip: clip
15945 }
15946 }, records.map(function (record) {
15947 var key = record.key,
15948 children = record.children;
15949 return jsx("group", {
15950 key: key
15951 }, children.map(function (item) {
15952 var key = item.key,
15953 xMin = item.xMin,
15954 xMax = item.xMax,
15955 yMin = item.yMin,
15956 yMax = item.yMax,
15957 color = item.color,
15958 shape = item.shape;
15959
15960 if (isNaN(xMin) || isNaN(xMax) || isNaN(yMin) || isNaN(yMax)) {
15961 return null;
15962 }
15963
15964 return jsx("rect", {
15965 key: key,
15966 attrs: _objectSpread({
15967 x: xMin,
15968 y: yMin,
15969 width: xMax - xMin,
15970 height: yMax - yMin,
15971 fill: color
15972 }, shape),
15973 animation: deepMix({
15974 appear: {
15975 easing: 'linear',
15976 duration: 450,
15977 property: ['y', 'height'],
15978 start: {
15979 y: y0,
15980 height: 0
15981 }
15982 },
15983 update: {
15984 easing: 'linear',
15985 duration: 450,
15986 property: ['x', 'y', 'width', 'height']
15987 }
15988 }, animation)
15989 });
15990 }));
15991 }));
15992 });
15993
15994 var Polar$1 = (function (props) {
15995 var coord = props.coord,
15996 records = props.records,
15997 animation = props.animation;
15998 var center = coord.center,
15999 startAngle = coord.startAngle,
16000 endAngle = coord.endAngle,
16001 radius = coord.radius;
16002 return jsx("group", {
16003 animation: {
16004 appear: _objectSpread(_objectSpread({
16005 easing: 'quadraticOut',
16006 duration: 450
16007 }, animation && animation.appear), {}, {
16008 clip: {
16009 type: 'sector',
16010 property: ['endAngle'],
16011 attrs: {
16012 x: center.x,
16013 y: center.y,
16014 startAngle: startAngle,
16015 r: radius
16016 },
16017 start: {
16018 endAngle: startAngle
16019 },
16020 end: {
16021 endAngle: endAngle
16022 }
16023 }
16024 })
16025 }
16026 }, records.map(function (record) {
16027 var key = record.key,
16028 children = record.children;
16029 return jsx("group", {
16030 key: key
16031 }, children.map(function (item) {
16032 var key = item.key,
16033 xMin = item.xMin,
16034 xMax = item.xMax,
16035 yMin = item.yMin,
16036 yMax = item.yMax,
16037 color = item.color,
16038 shape = item.shape;
16039 return jsx("sector", {
16040 key: key,
16041 attrs: _objectSpread({
16042 x: center.x,
16043 y: center.y,
16044 fill: color,
16045 startAngle: xMin,
16046 endAngle: xMax,
16047 r0: yMin,
16048 r: yMax
16049 }, shape),
16050 animation: deepMix({
16051 update: {
16052 easing: 'linear',
16053 duration: 450,
16054 property: ['x', 'y', 'startAngle', 'endAngle', 'r0', 'r']
16055 }
16056 }, animation)
16057 });
16058 }));
16059 }));
16060 });
16061
16062 var intervalView = (function (props) {
16063 var coord = props.coord;
16064 var coordType = coord.type; // 直角坐标系
16065
16066 if (coordType === 'rect') {
16067 return jsx(Rect$3, _objectSpread({}, props));
16068 } // 极坐标系
16069
16070
16071 return jsx(Polar$1, _objectSpread({}, props));
16072 });
16073
16074 function convertToPoints(_ref) {
16075 var xMin = _ref.xMin,
16076 xMax = _ref.xMax,
16077 yMin = _ref.yMin,
16078 yMax = _ref.yMax;
16079 return [{
16080 x: xMin,
16081 y: yMin
16082 }, {
16083 x: xMax,
16084 y: yMin
16085 }, {
16086 x: xMax,
16087 y: yMax
16088 }, {
16089 x: xMin,
16090 y: yMax
16091 } // bl
16092 ];
16093 }
16094
16095 var polygonView = (function (props) {
16096 var records = props.records,
16097 shape = props.shape,
16098 showLabel = props.showLabel,
16099 labelCfg = props.labelCfg,
16100 LabelView = props.LabelView; // 是否倒置
16101
16102 var overturn = false;
16103 return jsx("group", null, records.map(function (record, index) {
16104 var key = record.key,
16105 children = record.children;
16106 var isLastRecord = index === records.length - 1;
16107 var nextRecord = isLastRecord ? record : records[index + 1];
16108 var nextChildren = nextRecord.children;
16109 var nextFirstPoint = convertToPoints(nextChildren[0]);
16110 var nextLastPoints = convertToPoints(nextChildren[nextChildren.length - 1]);
16111
16112 if (!overturn) {
16113 overturn = nextChildren[0].yMax > children[0].yMax;
16114 }
16115
16116 if (overturn) {
16117 nextFirstPoint.reverse();
16118 nextLastPoints.reverse();
16119 }
16120
16121 var polygonPoints = children.map(function (child, childIndex) {
16122 var points = convertToPoints(child);
16123
16124 if (overturn) {
16125 points.reverse();
16126 }
16127
16128 if (isLastRecord) {
16129 if (shape === 'pyramid') {
16130 points = [getMiddlePoint(points[0], points[1]), points[2], points[3]];
16131 }
16132 } else {
16133 if (childIndex === 0) {
16134 points[0] = nextFirstPoint[3];
16135 }
16136
16137 if (childIndex === children.length - 1) {
16138 points[1] = nextLastPoints[2];
16139 }
16140 }
16141
16142 return _objectSpread(_objectSpread({}, child), {}, {
16143 points: points
16144 });
16145 });
16146 return jsx("group", {
16147 key: key
16148 }, polygonPoints.map(function (child) {
16149 var points = child.points,
16150 color = child.color,
16151 shape = child.shape;
16152 return jsx("group", null, jsx("polygon", {
16153 attrs: _objectSpread({
16154 points: points,
16155 fill: color
16156 }, shape)
16157 }), showLabel && LabelView ? jsx(LabelView, _objectSpread({
16158 record: child,
16159 points: points
16160 }, labelCfg)) : null);
16161 }));
16162 }));
16163 });
16164
16165 // 柱图/条图
16166
16167 var Views = /*#__PURE__*/Object.freeze({
16168 __proto__: null,
16169 rect: intervalView,
16170 pyramid: polygonView,
16171 funnel: polygonView
16172 });
16173
16174 var index$2 = withInterval(Views);
16175
16176 var withPoint = (function (View) {
16177 return /*#__PURE__*/function (_Geometry) {
16178 _inherits(Point, _Geometry);
16179
16180 var _super = _createSuper(Point);
16181
16182 function Point() {
16183 _classCallCheck(this, Point);
16184
16185 return _super.apply(this, arguments);
16186 }
16187
16188 _createClass(Point, [{
16189 key: "getDefaultCfg",
16190 value: function getDefaultCfg() {
16191 return {
16192 geomType: 'point'
16193 };
16194 }
16195 }, {
16196 key: "render",
16197 value: function render() {
16198 var props = this.props,
16199 container = this.container;
16200 var coord = props.coord;
16201 var records = this.mapping();
16202 var clip = this.getClip();
16203 return jsx(View, _objectSpread(_objectSpread({}, props), {}, {
16204 coord: coord,
16205 records: records,
16206 clip: clip
16207 }));
16208 }
16209 }]);
16210
16211 return Point;
16212 }(Geometry);
16213 });
16214
16215 var PointView = (function (props) {
16216 var records = props.records,
16217 animation = props.animation,
16218 clip = props.clip;
16219 return jsx("group", {
16220 attrs: {
16221 clip: clip
16222 }
16223 }, records.map(function (record) {
16224 var key = record.key,
16225 children = record.children;
16226 return jsx("group", {
16227 key: key
16228 }, children.map(function (item) {
16229 var x = item.x,
16230 y = item.y,
16231 size = item.size,
16232 color = item.color,
16233 shapeName = item.shapeName,
16234 shape = item.shape;
16235
16236 if (isNaN(x) || isNaN(y)) {
16237 return null;
16238 }
16239
16240 if (shapeName === 'rect') {
16241 var rectSize = isNil(size) ? shape.size : size;
16242 return jsx("rect", {
16243 attrs: _objectSpread(_objectSpread({
16244 x: x - rectSize,
16245 y: y - rectSize,
16246 fill: color,
16247 stroke: color
16248 }, shape), {}, {
16249 width: rectSize * 2,
16250 height: rectSize * 2
16251 }),
16252 animation: deepMix({
16253 appear: {
16254 easing: 'linear',
16255 duration: 450
16256 },
16257 update: {
16258 easing: 'linear',
16259 duration: 450,
16260 property: ['x', 'y', 'width', 'height', 'fill']
16261 }
16262 }, animation)
16263 });
16264 }
16265
16266 return jsx("circle", {
16267 attrs: _objectSpread(_objectSpread({
16268 x: x,
16269 y: y,
16270 fill: shapeName === 'circle' ? color : null,
16271 stroke: shapeName === 'hollowCircle' ? color : null
16272 }, shape), {}, {
16273 r: isNil(size) ? shape.size : size
16274 }),
16275 animation: deepMix({
16276 appear: {
16277 easing: 'linear',
16278 duration: 450
16279 },
16280 update: {
16281 easing: 'linear',
16282 duration: 450,
16283 property: ['x', 'y', 'r', 'fill']
16284 }
16285 }, animation)
16286 });
16287 }));
16288 }));
16289 });
16290
16291 var index$3 = withPoint(PointView);
16292
16293 var withAxis = (function (View) {
16294 return /*#__PURE__*/function (_Component) {
16295 _inherits(Axis, _Component);
16296
16297 var _super = _createSuper(Axis);
16298
16299 function Axis(props) {
16300 var _this;
16301
16302 _classCallCheck(this, Axis);
16303
16304 _this = _super.call(this, props);
16305 _this.style = {};
16306 var _this$props = _this.props,
16307 chart = _this$props.chart,
16308 field = _this$props.field;
16309
16310 var scaleOption = _this.getScaleOption(props);
16311
16312 chart.setScale(field, scaleOption);
16313 return _this;
16314 }
16315
16316 _createClass(Axis, [{
16317 key: "willReceiveProps",
16318 value: function willReceiveProps(nextProps) {
16319 var lastProps = this.props;
16320 var chart = nextProps.chart,
16321 field = nextProps.field;
16322 var nextScaleOption = this.getScaleOption(nextProps);
16323 var lastScaleOption = this.getScaleOption(lastProps);
16324
16325 if (!equal(nextScaleOption, lastScaleOption)) {
16326 chart.setScale(field, nextScaleOption);
16327 }
16328 }
16329 }, {
16330 key: "willMount",
16331 value: function willMount() {
16332 this.updateCoord();
16333 }
16334 }, {
16335 key: "willUpdate",
16336 value: function willUpdate() {
16337 this.updateCoord();
16338 }
16339 }, {
16340 key: "getScaleOption",
16341 value: function getScaleOption(props) {
16342 var type = props.type,
16343 tickCount = props.tickCount,
16344 range = props.range,
16345 mask = props.mask,
16346 formatter = props.formatter,
16347 min = props.min,
16348 max = props.max,
16349 nice = props.nice;
16350 return {
16351 type: type,
16352 tickCount: tickCount,
16353 range: range,
16354 mask: mask,
16355 formatter: formatter,
16356 min: min,
16357 max: max,
16358 nice: nice
16359 };
16360 }
16361 }, {
16362 key: "_getDimType",
16363 value: function _getDimType() {
16364 var props = this.props;
16365 var field = props.field,
16366 chart = props.chart;
16367 var xScales = chart.getXScales();
16368 var scales = xScales.filter(function (scale) {
16369 return scale.field === field;
16370 });
16371 return scales.length > 0 ? 'x' : 'y';
16372 } // 获取ticks最大的宽高
16373
16374 }, {
16375 key: "getMaxBBox",
16376 value: function getMaxBBox(ticks, style) {
16377 var context = this.context;
16378 var measureText = context.measureText;
16379 var label = style.label,
16380 labelOffset = style.labelOffset;
16381 var width = 0;
16382 var height = 0;
16383 ticks.forEach(function (tick) {
16384 if (!label) return;
16385 var _tick$labelStyle = tick.labelStyle,
16386 labelStyle = _tick$labelStyle === void 0 ? {} : _tick$labelStyle,
16387 text = tick.text;
16388 var bbox = measureText(labelStyle.text || text, _objectSpread(_objectSpread({}, label), labelStyle));
16389 width = Math.max(width, bbox.width);
16390 height = Math.max(height, bbox.height);
16391 });
16392
16393 if (!width && !height) {
16394 return {
16395 width: width,
16396 height: height
16397 };
16398 }
16399
16400 var bbox = {
16401 width: width + labelOffset,
16402 height: height + labelOffset
16403 };
16404 return bbox;
16405 }
16406 }, {
16407 key: "_getPosition",
16408 value: function _getPosition() {
16409 var props = this.props;
16410 var position = props.position,
16411 coord = props.coord;
16412
16413 if (position) {
16414 return position;
16415 }
16416
16417 var dimType = this._getDimType();
16418
16419 if (coord.transposed) {
16420 return dimType === 'x' ? 'left' : 'bottom';
16421 }
16422
16423 return dimType === 'x' ? 'bottom' : 'left';
16424 }
16425 }, {
16426 key: "getTicks",
16427 value: function getTicks() {
16428 var props = this.props;
16429 var field = props.field,
16430 chart = props.chart;
16431 var scale = chart.getScale(field);
16432 var ticks = scale.getTicks(); // 设置tick的样式
16433
16434 ticks = this._setTicksStyle(ticks);
16435 ticks = this._generateGridPoints(ticks);
16436 return ticks;
16437 }
16438 /**
16439 * 生成极坐标下网格线的交叉点
16440 * @param ticks
16441 * @returns
16442 */
16443
16444 }, {
16445 key: "_generateGridPoints",
16446 value: function _generateGridPoints(ticks) {
16447 var props = this.props;
16448 var chart = props.chart,
16449 coord = props.coord;
16450
16451 if (!coord.isPolar) {
16452 return ticks;
16453 }
16454
16455 var dimType = this._getDimType(); // 只需要在 y 的时候生成
16456
16457
16458 if (dimType !== 'y') {
16459 return ticks;
16460 }
16461
16462 var xScale = chart.getXScales()[0];
16463 var xTicks = xScale.getTicks();
16464 ticks.forEach(function (tick) {
16465 var gridPoints = xTicks.map(function (xTick) {
16466 return coord.convertPoint({
16467 x: xTick.value,
16468 y: tick.value
16469 });
16470 }); // 添加第 1 个点,形成环状
16471
16472 gridPoints.push(gridPoints[0]);
16473 tick.gridPoints = gridPoints;
16474 });
16475 return ticks;
16476 }
16477 }, {
16478 key: "_setTicksStyle",
16479 value: function _setTicksStyle(ticks) {
16480 var _this2 = this;
16481
16482 var props = this.props,
16483 context = this.context;
16484 var theme = context.theme,
16485 px2hd = context.px2hd;
16486 var _props$style = props.style,
16487 style = _props$style === void 0 ? {} : _props$style;
16488 var themeAxis = theme.axis;
16489 each(themeAxis, function (value, key) {
16490 // 关闭tick的样式
16491 if (style[key] === null) {
16492 return;
16493 }
16494
16495 var styleValue = isFunction(style[key]) ? undefined : style[key];
16496
16497 if (isString(value) || isNumber(value)) {
16498 _this2.style[key] = px2hd(styleValue) || value;
16499 } else {
16500 _this2.style[key] = px2hd(deepMix(clone(value), styleValue));
16501 }
16502 });
16503 return ticks.map(function (tick, index) {
16504 var label = style.label,
16505 grid = style.grid;
16506 var defaultLabelStyle = themeAxis.label,
16507 defaultGridStyle = themeAxis.grid;
16508
16509 if (isFunction(label)) {
16510 tick.labelStyle = px2hd(mix({}, defaultLabelStyle, label(tick.text, index, ticks)));
16511 }
16512
16513 if (isFunction(grid)) {
16514 tick.gridStyle = px2hd(mix({}, defaultGridStyle, grid(tick.text, index, ticks.length)));
16515 }
16516
16517 return tick;
16518 });
16519 }
16520 }, {
16521 key: "convertTicks",
16522 value: function convertTicks(ticks) {
16523 var props = this.props;
16524 var coord = props.coord;
16525
16526 var dimType = this._getDimType();
16527
16528 var otherDim = dimType === 'x' ? 'y' : 'x';
16529 return ticks.map(function (tick) {
16530 var _coord$convertPoint, _coord$convertPoint2;
16531
16532 var start = coord.convertPoint((_coord$convertPoint = {}, _defineProperty(_coord$convertPoint, dimType, tick.value), _defineProperty(_coord$convertPoint, otherDim, 0), _coord$convertPoint));
16533 var end = coord.convertPoint((_coord$convertPoint2 = {}, _defineProperty(_coord$convertPoint2, dimType, tick.value), _defineProperty(_coord$convertPoint2, otherDim, 1), _coord$convertPoint2));
16534 return _objectSpread(_objectSpread({}, tick), {}, {
16535 points: [start, end]
16536 });
16537 });
16538 }
16539 }, {
16540 key: "measureLayout",
16541 value: function measureLayout() {
16542 var props = this.props;
16543 var visible = props.visible,
16544 coord = props.coord;
16545
16546 if (visible === false) {
16547 return null;
16548 }
16549
16550 var ticks = this.getTicks();
16551 var bbox = this.getMaxBBox(ticks, this.style);
16552 var isPolar = coord.isPolar;
16553
16554 var dimType = this._getDimType();
16555
16556 var width = bbox.width,
16557 height = bbox.height;
16558
16559 if (isPolar) {
16560 // 机坐标系的 y 不占位置
16561 if (dimType === 'y') {
16562 return null;
16563 } // 4 个方向都需要留空
16564
16565
16566 return ['top', 'right', 'bottom', 'left'].map(function (position) {
16567 return {
16568 position: position,
16569 width: width,
16570 height: height
16571 };
16572 });
16573 } // 直角坐标系下
16574
16575
16576 var position = this._getPosition();
16577
16578 return {
16579 position: position,
16580 width: width,
16581 height: height
16582 };
16583 } // 主要是计算coord的布局
16584
16585 }, {
16586 key: "updateCoord",
16587 value: function updateCoord() {
16588 var props = this.props;
16589 var chart = props.chart;
16590 var layout = this.measureLayout();
16591 chart.updateCoordFor(this, layout);
16592 }
16593 }, {
16594 key: "render",
16595 value: function render() {
16596 var props = this.props,
16597 style = this.style;
16598 var visible = props.visible,
16599 coord = props.coord;
16600
16601 if (visible === false) {
16602 return null;
16603 }
16604
16605 var ticks = this.getTicks();
16606
16607 var position = this._getPosition();
16608
16609 var dimType = this._getDimType();
16610
16611 return jsx(View, _objectSpread(_objectSpread({}, props), {}, {
16612 style: style,
16613 ticks: this.convertTicks(ticks),
16614 coord: coord,
16615 position: position,
16616 dimType: dimType
16617 }));
16618 }
16619 }]);
16620
16621 return Axis;
16622 }(Component);
16623 });
16624
16625 // 相对圆心偏移量的点
16626
16627 function getOffsetPoint(center, point, offset) {
16628 var vectorX = point.x - center.x;
16629 var vectorY = point.y - center.y;
16630 var vector = [vectorX, vectorY];
16631 var vectorLength = Vector2.length(vector);
16632 var offsetLength = vectorLength + offset;
16633 var x = vectorX / vectorLength * offsetLength;
16634 var y = vectorY / vectorLength * offsetLength;
16635 return {
16636 x: center.x + x,
16637 y: center.y + y
16638 };
16639 } // 获取文本的对齐方式
16640
16641
16642 function getTextAlignInfo(center, point) {
16643 // 文本点向量
16644 var vector = [point.x - center.x, point.y - center.y];
16645 var align;
16646 var baseLine; // 水平对齐
16647
16648 if (vector[0] > 0) {
16649 align = 'left';
16650 } else if (vector[0] < 0) {
16651 align = 'right';
16652 } else {
16653 align = 'center';
16654 } // 垂直对齐
16655
16656
16657 if (vector[1] > 0) {
16658 baseLine = 'top';
16659 } else if (vector[1] < 0) {
16660 baseLine = 'bottom';
16661 } else {
16662 baseLine = 'middle';
16663 }
16664
16665 return {
16666 textAlign: align,
16667 textBaseline: baseLine
16668 };
16669 }
16670
16671 var Line$1 = function Line(props) {
16672 var line = props.line,
16673 gridType = props.gridType,
16674 center = props.center,
16675 radius = props.radius,
16676 ticks = props.ticks;
16677 if (!line) return null;
16678
16679 if (gridType !== 'line') {
16680 return jsx("arc", {
16681 attrs: _objectSpread({
16682 x: center.x,
16683 y: center.y,
16684 r: radius
16685 }, line)
16686 });
16687 }
16688
16689 var points = ticks.map(function (tick) {
16690 var points = tick.points;
16691 return points[points.length - 1];
16692 }); // 头尾相连
16693
16694 points.push(points[0]);
16695 return jsx("polyline", {
16696 attrs: _objectSpread({
16697 points: points
16698 }, line)
16699 });
16700 };
16701
16702 var PolarX = (function (props) {
16703 var ticks = props.ticks,
16704 coord = props.coord,
16705 style = props.style,
16706 gridType = props.grid;
16707 var center = coord.center;
16708 var grid = style.grid,
16709 tickLine = style.tickLine,
16710 line = style.line,
16711 labelOffset = style.labelOffset,
16712 label = style.label;
16713 var firstTicks = ticks[0];
16714 var points = firstTicks.points;
16715 var end = points[points.length - 1];
16716 var radius = Vector2.length([end.x - center.x, end.y - center.y]);
16717 return jsx("group", null, grid ? ticks.map(function (tick) {
16718 var points = tick.points,
16719 gridStyle = tick.gridStyle;
16720 var end = points[points.length - 1];
16721 return jsx("line", {
16722 attrs: _objectSpread(_objectSpread({
16723 x1: center.x,
16724 y1: center.y,
16725 x2: end.x,
16726 y2: end.y
16727 }, grid), gridStyle)
16728 });
16729 }) : null, tickLine && tickLine.length ? ticks.map(function (tick) {
16730 var points = tick.points;
16731 var end = points[points.length - 1];
16732 var offsetPoint = getOffsetPoint(center, end, tickLine.length);
16733 return jsx("line", {
16734 attrs: _objectSpread({
16735 x1: end.x,
16736 y1: end.y,
16737 x2: offsetPoint.x,
16738 y2: offsetPoint.y
16739 }, tickLine)
16740 });
16741 }) : null, jsx(Line$1, {
16742 line: line,
16743 gridType: gridType,
16744 center: center,
16745 radius: radius,
16746 ticks: ticks
16747 }), label ? ticks.map(function (tick) {
16748 var points = tick.points,
16749 text = tick.text,
16750 labelStyle = tick.labelStyle;
16751 var end = points[points.length - 1];
16752 var offsetPoint = getOffsetPoint(center, end, labelOffset);
16753 return jsx("text", {
16754 attrs: _objectSpread(_objectSpread(_objectSpread({
16755 x: offsetPoint.x,
16756 y: offsetPoint.y,
16757 text: text
16758 }, getTextAlignInfo(center, end)), label), labelStyle)
16759 });
16760 }) : null);
16761 });
16762
16763 var PolarY = (function (props) {
16764 var ticks = props.ticks,
16765 coord = props.coord,
16766 style = props.style,
16767 gridType = props.grid;
16768 var center = coord.center;
16769 var grid = style.grid,
16770 tickLine = style.tickLine,
16771 line = style.line,
16772 labelOffset = style.labelOffset,
16773 label = style.label;
16774 return jsx("group", null, grid ? ticks.map(function (tick) {
16775 var points = tick.points,
16776 gridStyle = tick.gridStyle,
16777 gridPoints = tick.gridPoints;
16778 var end = points[points.length - 1];
16779
16780 if (gridType !== 'line') {
16781 return jsx("arc", {
16782 attrs: _objectSpread(_objectSpread({
16783 x: center.x,
16784 y: center.y,
16785 r: Vector2.length([end.x - center.x, end.y - center.y])
16786 }, grid), gridStyle)
16787 });
16788 }
16789
16790 return jsx("polyline", {
16791 attrs: _objectSpread(_objectSpread({
16792 points: gridPoints
16793 }, grid), gridStyle)
16794 });
16795 }) : null, tickLine && tickLine.length ? ticks.map(function (tick) {
16796 var points = tick.points;
16797 var end = points[points.length - 1];
16798 return jsx("line", {
16799 attrs: _objectSpread({
16800 x1: end.x,
16801 y1: end.y,
16802 x2: end.x - tickLine.length,
16803 y2: end.y
16804 }, tickLine)
16805 });
16806 }) : null, line ? jsx("line", {
16807 attrs: _objectSpread({
16808 x1: ticks[0].points[0].x,
16809 y1: ticks[0].points[0].y,
16810 x2: ticks[ticks.length - 1].points[0].x,
16811 y2: ticks[ticks.length - 1].points[0].y
16812 }, line)
16813 }) : null, label ? ticks.map(function (tick) {
16814 var points = tick.points,
16815 text = tick.text,
16816 labelStyle = tick.labelStyle;
16817 var end = points[points.length - 1];
16818 return jsx("text", {
16819 attrs: _objectSpread(_objectSpread({
16820 x: end.x - labelOffset,
16821 y: end.y,
16822 text: text,
16823 textAlign: 'right',
16824 textBaseline: 'middle'
16825 }, label), labelStyle)
16826 });
16827 }) : null);
16828 });
16829
16830 var Top = (function (props) {
16831 var ticks = props.ticks,
16832 coord = props.coord,
16833 style = props.style;
16834 var left = coord.left,
16835 top = coord.top,
16836 right = coord.right;
16837 var grid = style.grid,
16838 tickLine = style.tickLine,
16839 line = style.line,
16840 labelOffset = style.labelOffset,
16841 label = style.label;
16842 return jsx("group", null, grid ? ticks.map(function (tick) {
16843 var points = tick.points,
16844 gridStyle = tick.gridStyle;
16845 var start = points[0];
16846 var end = points[points.length - 1];
16847 return jsx("line", {
16848 attrs: _objectSpread(_objectSpread({
16849 x1: start.x,
16850 y1: start.y,
16851 x2: end.x,
16852 y2: end.y
16853 }, grid), gridStyle)
16854 });
16855 }) : null, tickLine && tickLine.length ? ticks.map(function (tick) {
16856 var points = tick.points;
16857 var end = points[points.length - 1];
16858 return jsx("line", {
16859 attrs: _objectSpread({
16860 x1: end.x,
16861 y1: end.y,
16862 x2: end.x,
16863 y2: end.y - tickLine.length
16864 }, tickLine)
16865 });
16866 }) : null, line ? jsx("line", {
16867 attrs: _objectSpread({
16868 x1: left,
16869 y1: top,
16870 x2: right,
16871 y2: top
16872 }, line)
16873 }) : null, label ? ticks.map(function (tick, _index) {
16874 var points = tick.points,
16875 text = tick.text,
16876 labelStyle = tick.labelStyle;
16877 var end = points[points.length - 1];
16878 return jsx("text", {
16879 attrs: _objectSpread(_objectSpread({
16880 x: end.x,
16881 y: end.y - labelOffset,
16882 textAlign: 'center',
16883 textBaseline: 'bottom',
16884 text: text
16885 }, label), labelStyle)
16886 });
16887 }) : null);
16888 });
16889
16890 var Bottom = (function (props, context) {
16891 var ticks = props.ticks,
16892 coord = props.coord,
16893 style = props.style,
16894 animation = props.animation;
16895 var px2hd = context.px2hd;
16896 var left = coord.left,
16897 right = coord.right,
16898 bottom = coord.bottom;
16899 var grid = style.grid,
16900 tickLine = style.tickLine,
16901 line = style.line,
16902 labelOffset = style.labelOffset,
16903 label = style.label;
16904 return jsx("group", null, grid ? ticks.map(function (tick) {
16905 var points = tick.points,
16906 tickValue = tick.tickValue,
16907 gridStyle = tick.gridStyle;
16908 var start = points[0];
16909 var end = points[points.length - 1];
16910 return jsx("line", {
16911 key: tickValue,
16912 attrs: _objectSpread(_objectSpread({
16913 x1: start.x,
16914 y1: start.y,
16915 x2: end.x,
16916 y2: end.y
16917 }, grid), gridStyle)
16918 });
16919 }) : null, tickLine && tickLine.length ? ticks.map(function (tick) {
16920 var points = tick.points,
16921 tickValue = tick.tickValue;
16922 var start = points[0];
16923 return jsx("line", {
16924 key: tickValue,
16925 attrs: _objectSpread({
16926 x1: start.x,
16927 y1: start.y,
16928 x2: start.x,
16929 y2: start.y + px2hd(tickLine.length)
16930 }, tickLine)
16931 });
16932 }) : null, line ? jsx("line", {
16933 attrs: _objectSpread({
16934 x1: left,
16935 y1: bottom,
16936 x2: right,
16937 y2: bottom
16938 }, line)
16939 }) : null, label ? ticks.map(function (tick, index) {
16940 var points = tick.points,
16941 text = tick.text,
16942 tickValue = tick.tickValue,
16943 labelStyle = tick.labelStyle;
16944 var start = points[0];
16945
16946 var _ref = labelStyle || label || {},
16947 _ref$align = _ref.align,
16948 align = _ref$align === void 0 ? 'center' : _ref$align;
16949
16950 var textAttrs = _objectSpread(_objectSpread({
16951 x: start.x,
16952 y: start.y + labelOffset,
16953 textBaseline: 'top',
16954 text: text
16955 }, label), labelStyle);
16956
16957 if (align === 'between') {
16958 if (index === 0) {
16959 textAttrs.textAlign = 'start';
16960 } else if (index === ticks.length - 1) {
16961 textAttrs.textAlign = 'end';
16962 } else {
16963 textAttrs.textAlign = 'center';
16964 }
16965 } else {
16966 textAttrs.textAlign = align;
16967 }
16968
16969 return jsx("text", {
16970 key: tickValue,
16971 attrs: textAttrs,
16972 animation: animation || {
16973 appear: {
16974 easing: 'linear',
16975 duration: 300,
16976 delay: 0,
16977 property: ['fillOpacity'],
16978 start: {
16979 fillOpacity: 0
16980 },
16981 end: {
16982 fillOpacity: 1
16983 }
16984 },
16985 update: {
16986 easing: 'linear',
16987 duration: 450,
16988 delay: 0,
16989 property: ['x', 'y']
16990 },
16991 leave: {
16992 easing: 'linear',
16993 duration: 450,
16994 delay: 0,
16995 property: ['fillOpacity'],
16996 start: {
16997 fillOpacity: 1
16998 },
16999 end: {
17000 fillOpacity: 0
17001 }
17002 }
17003 }
17004 });
17005 }) : null);
17006 });
17007
17008 var Right = (function (props) {
17009 var ticks = props.ticks,
17010 coord = props.coord,
17011 style = props.style;
17012 var top = coord.top,
17013 right = coord.right,
17014 bottom = coord.bottom;
17015 var grid = style.grid,
17016 tickLine = style.tickLine,
17017 line = style.line,
17018 labelOffset = style.labelOffset,
17019 label = style.label;
17020 return jsx("group", null, grid ? ticks.map(function (tick) {
17021 var points = tick.points,
17022 gridStyle = tick.gridStyle;
17023 var start = points[0];
17024 var end = points[points.length - 1];
17025 return jsx("line", {
17026 attrs: _objectSpread(_objectSpread({
17027 x1: start.x,
17028 y1: start.y,
17029 x2: end.x,
17030 y2: end.y
17031 }, grid), gridStyle)
17032 });
17033 }) : null, tickLine && tickLine.length ? ticks.map(function (tick) {
17034 var points = tick.points;
17035 var end = points[points.length - 1];
17036 return jsx("line", {
17037 attrs: _objectSpread({
17038 x1: end.x,
17039 y1: end.y,
17040 x2: end.x + tickLine.length,
17041 y2: end.y
17042 }, tickLine)
17043 });
17044 }) : null, line ? jsx("line", {
17045 attrs: _objectSpread({
17046 x1: right,
17047 y1: top,
17048 x2: right,
17049 y2: bottom
17050 }, line)
17051 }) : null, label ? ticks.map(function (tick, _index) {
17052 var points = tick.points,
17053 text = tick.text,
17054 labelStyle = tick.labelStyle;
17055 var end = points[points.length - 1];
17056 return jsx("text", {
17057 attrs: _objectSpread(_objectSpread({
17058 x: end.x + labelOffset,
17059 y: end.y,
17060 textAlign: 'left',
17061 textBaseline: 'middle',
17062 text: text
17063 }, label), labelStyle)
17064 });
17065 }) : null);
17066 });
17067
17068 var Left = (function (props) {
17069 var ticks = props.ticks,
17070 coord = props.coord,
17071 style = props.style,
17072 animation = props.animation;
17073 var left = coord.left,
17074 top = coord.top,
17075 bottom = coord.bottom;
17076 var grid = style.grid,
17077 tickLine = style.tickLine,
17078 line = style.line,
17079 labelOffset = style.labelOffset,
17080 label = style.label;
17081 return jsx("group", null, grid ? ticks.map(function (tick) {
17082 var points = tick.points,
17083 tickValue = tick.tickValue,
17084 gridStyle = tick.gridStyle;
17085 var start = points[0];
17086 var end = points[points.length - 1];
17087 return jsx("line", {
17088 key: tickValue,
17089 attrs: _objectSpread(_objectSpread({
17090 x1: start.x,
17091 y1: start.y,
17092 x2: end.x,
17093 y2: end.y
17094 }, grid), gridStyle)
17095 });
17096 }) : null, tickLine && tickLine.length ? ticks.map(function (tick) {
17097 var points = tick.points,
17098 tickValue = tick.tickValue;
17099 var start = points[0];
17100 return jsx("line", {
17101 key: tickValue,
17102 attrs: _objectSpread({
17103 x1: start.x,
17104 y1: start.y,
17105 x2: start.x - tickLine.length,
17106 y2: start.y
17107 }, tickLine)
17108 });
17109 }) : null, line ? jsx("line", {
17110 attrs: _objectSpread({
17111 x1: left,
17112 y1: top,
17113 x2: left,
17114 y2: bottom
17115 }, line)
17116 }) : null, label ? ticks.map(function (tick, _index) {
17117 var tickValue = tick.tickValue,
17118 points = tick.points,
17119 text = tick.text,
17120 labelStyle = tick.labelStyle;
17121 var start = points[0];
17122 return jsx("text", {
17123 key: tickValue,
17124 attrs: _objectSpread(_objectSpread({
17125 x: start.x - labelOffset,
17126 y: start.y,
17127 textAlign: 'right',
17128 textBaseline: 'middle',
17129 text: text
17130 }, label), labelStyle),
17131 animation: animation || {
17132 appear: {
17133 easing: 'linear',
17134 duration: 300,
17135 delay: 0,
17136 property: ['fillOpacity'],
17137 start: {
17138 fillOpacity: 0
17139 },
17140 end: {
17141 fillOpacity: 1
17142 }
17143 },
17144 update: {
17145 easing: 'linear',
17146 duration: 450,
17147 delay: 0,
17148 property: ['x', 'y']
17149 },
17150 leave: {
17151 easing: 'linear',
17152 duration: 450,
17153 delay: 0,
17154 property: ['fillOpacity'],
17155 start: {
17156 fillOpacity: 1
17157 },
17158 end: {
17159 fillOpacity: 0
17160 }
17161 }
17162 }
17163 });
17164 }) : null);
17165 });
17166
17167 function isPolar(props) {
17168 return props.coord.isPolar;
17169 }
17170
17171 var AxisView = (function (props) {
17172 // 极坐标
17173 if (isPolar(props)) {
17174 var dimType = props.dimType;
17175
17176 if (dimType === 'x') {
17177 return jsx(PolarX, _objectSpread({}, props));
17178 }
17179
17180 return jsx(PolarY, _objectSpread({}, props));
17181 }
17182
17183 var position = props.position; // 直角坐标
17184
17185 if (position === 'right') {
17186 return jsx(Right, _objectSpread({}, props));
17187 }
17188
17189 if (position === 'left') {
17190 return jsx(Left, _objectSpread({}, props));
17191 }
17192
17193 if (position === 'top') {
17194 return jsx(Top, _objectSpread({}, props));
17195 }
17196
17197 return jsx(Bottom, _objectSpread({}, props));
17198 });
17199
17200 var index$4 = withAxis(AxisView);
17201
17202 var withLegend = (function (View) {
17203 return /*#__PURE__*/function (_Component) {
17204 _inherits(Legend, _Component);
17205
17206 var _super = _createSuper(Legend);
17207
17208 function Legend(props) {
17209 var _this;
17210
17211 _classCallCheck(this, Legend);
17212
17213 _this = _super.call(this, props);
17214 _this.state = {
17215 filtered: {},
17216 items: []
17217 };
17218 return _this;
17219 }
17220
17221 _createClass(Legend, [{
17222 key: "getOriginItems",
17223 value: function getOriginItems() {
17224 var chart = this.props.chart;
17225 return chart.getLegendItems();
17226 }
17227 }, {
17228 key: "getItems",
17229 value: function getItems() {
17230 var _props$items;
17231
17232 var props = this.props,
17233 state = this.state;
17234 var filtered = state.filtered;
17235 var renderItems = ((_props$items = props.items) === null || _props$items === void 0 ? void 0 : _props$items.length) ? props.items : this.getOriginItems();
17236 if (!renderItems) return null;
17237 return renderItems.map(function (item) {
17238 var tickValue = item.tickValue;
17239 return _objectSpread(_objectSpread({}, item), {}, {
17240 filtered: filtered[tickValue]
17241 });
17242 });
17243 }
17244 }, {
17245 key: "setItems",
17246 value: function setItems(items) {
17247 this.setState({
17248 items: items
17249 });
17250 }
17251 }, {
17252 key: "getMaxItemBox",
17253 value: function getMaxItemBox(legendShape) {
17254 var maxItemWidth = 0;
17255 var maxItemHeight = 0;
17256 (legendShape.get('children') || []).forEach(function (child) {
17257 var _child$get = child.get('attrs'),
17258 width = _child$get.width,
17259 height = _child$get.height;
17260
17261 maxItemWidth = Math.max(maxItemWidth, width);
17262 maxItemHeight = Math.max(maxItemHeight, height);
17263 });
17264 return {
17265 width: maxItemWidth,
17266 height: maxItemHeight
17267 };
17268 } // 计算 legend 的位置
17269
17270 }, {
17271 key: "_init",
17272 value: function _init() {
17273 var props = this.props,
17274 context = this.context;
17275 var parentLayout = props.layout,
17276 customWidth = props.width,
17277 customHeight = props.height,
17278 _props$position = props.position,
17279 position = _props$position === void 0 ? 'top' : _props$position;
17280 var items = this.getItems();
17281 if (!items || !items.length) return;
17282 var left = parentLayout.left,
17283 top = parentLayout.top,
17284 right = parentLayout.right,
17285 bottom = parentLayout.bottom,
17286 layoutWidth = parentLayout.width,
17287 layoutHeight = parentLayout.height;
17288 var width = context.px2hd(customWidth) || layoutWidth;
17289 var shape = renderShape(this, this.render(), false);
17290
17291 var _this$getMaxItemBox = this.getMaxItemBox(shape),
17292 itemMaxWidth = _this$getMaxItemBox.width,
17293 itemMaxHeight = _this$getMaxItemBox.height; // 每行最多的个数
17294
17295
17296 var lineMaxCount = Math.floor(width / itemMaxWidth);
17297 var itemCount = items.length; // legend item 的行数
17298
17299 var lineCount = Math.ceil(itemCount / lineMaxCount);
17300 var itemWidth = width / lineMaxCount;
17301 var autoHeight = itemMaxHeight * lineCount;
17302 var style = {
17303 left: left,
17304 top: top,
17305 width: width,
17306 // height 默认自适应
17307 height: undefined,
17308 flexDirection: 'row',
17309 flexWrap: 'wrap',
17310 alignItems: 'center',
17311 justifyContent: 'flex-start'
17312 }; // 如果只有一行,2端对齐
17313
17314 if (lineCount === 1) {
17315 style.justifyContent = 'space-between';
17316 }
17317
17318 if (position === 'top') {
17319 style.height = customHeight ? customHeight : autoHeight;
17320 }
17321
17322 if (position === 'left') {
17323 style.flexDirection = 'column';
17324 style.justifyContent = 'center';
17325 style.width = itemMaxWidth;
17326 style.height = customHeight ? customHeight : layoutHeight;
17327 }
17328
17329 if (position === 'right') {
17330 style.flexDirection = 'column';
17331 style.alignItems = 'flex-start';
17332 style.justifyContent = 'center';
17333 style.width = itemMaxWidth;
17334 style.height = customHeight ? customHeight : layoutHeight;
17335 style.left = right - itemMaxWidth;
17336 }
17337
17338 if (position === 'bottom') {
17339 style.top = bottom - autoHeight;
17340 style.height = customHeight ? customHeight : autoHeight;
17341 }
17342
17343 this.itemWidth = itemWidth;
17344 this.style = style;
17345 shape.remove();
17346 }
17347 }, {
17348 key: "updateCoord",
17349 value: function updateCoord() {
17350 var context = this.context,
17351 props = this.props,
17352 style = this.style;
17353 var _props$position2 = props.position,
17354 position = _props$position2 === void 0 ? 'top' : _props$position2,
17355 _props$margin = props.margin,
17356 margin = _props$margin === void 0 ? '30px' : _props$margin,
17357 chart = props.chart;
17358 var width = style.width,
17359 height = style.height;
17360 var marginNumber = context.px2hd(margin);
17361 chart.updateCoordFor(this, {
17362 position: position,
17363 width: width + marginNumber,
17364 height: height + marginNumber
17365 });
17366 }
17367 }, {
17368 key: "willMount",
17369 value: function willMount() {
17370 var items = this.getItems();
17371 if (!items || !items.length) return;
17372
17373 this._init();
17374
17375 this.updateCoord();
17376 }
17377 }, {
17378 key: "didMount",
17379 value: function didMount() {
17380 this._initEvent();
17381 }
17382 }, {
17383 key: "willUpdate",
17384 value: function willUpdate() {
17385 var items = this.getItems();
17386 if (!items || !items.length) return;
17387 this.updateCoord();
17388 }
17389 }, {
17390 key: "_initEvent",
17391 value: function _initEvent() {
17392 var _this2 = this;
17393
17394 var context = this.context,
17395 props = this.props,
17396 container = this.container;
17397 var canvas = context.canvas;
17398 var chart = props.chart,
17399 _props$clickable = props.clickable,
17400 clickable = _props$clickable === void 0 ? true : _props$clickable,
17401 onClick = props.onClick;
17402 if (!clickable) return; // item 点击事件
17403
17404 canvas.on('click', function (ev) {
17405 var points = ev.points;
17406 var point = points[0];
17407 var bbox = container.getBBox();
17408
17409 if (!isInBBox(bbox, point)) {
17410 return;
17411 }
17412
17413 var legendItems = getElementsByClassName('legend-item', container);
17414
17415 if (!legendItems.length) {
17416 return;
17417 }
17418
17419 var clickItem = find(legendItems, function (item) {
17420 var itemBBox = item.getBBox();
17421 return isInBBox(itemBBox, point);
17422 });
17423
17424 if (!clickItem) {
17425 return;
17426 }
17427
17428 var dataItem = clickItem.get('data-item');
17429
17430 if (!dataItem) {
17431 return;
17432 }
17433
17434 if (isFunction(onClick)) {
17435 onClick(dataItem);
17436 }
17437
17438 var field = dataItem.field,
17439 tickValue = dataItem.tickValue;
17440 var prevFiltered = _this2.state.filtered;
17441
17442 var filtered = _objectSpread(_objectSpread({}, prevFiltered), {}, _defineProperty({}, tickValue, !prevFiltered[tickValue]));
17443
17444 _this2.setState({
17445 filtered: filtered
17446 });
17447
17448 chart.filter(field, function (value) {
17449 return !filtered[value];
17450 });
17451 });
17452 }
17453 }, {
17454 key: "render",
17455 value: function render() {
17456 var props = this.props,
17457 itemWidth = this.itemWidth,
17458 style = this.style;
17459 var items = this.getItems();
17460
17461 if (!items || !items.length) {
17462 return null;
17463 }
17464
17465 return jsx(View, _objectSpread(_objectSpread({}, props), {}, {
17466 items: items,
17467 itemWidth: itemWidth,
17468 style: _objectSpread(_objectSpread({}, style), props.style)
17469 }));
17470 }
17471 }]);
17472
17473 return Legend;
17474 }(Component);
17475 });
17476
17477 var Marker$1 = function Marker(_ref) {
17478 var type = _ref.type,
17479 color = _ref.color;
17480
17481 if (type === 'square') {
17482 return jsx("rect", {
17483 style: {
17484 width: '12px',
17485 height: '12px',
17486 marginRight: '10px'
17487 },
17488 attrs: {
17489 fill: color
17490 }
17491 });
17492 }
17493
17494 return jsx("circle", {
17495 style: {
17496 width: '12px',
17497 height: '12px',
17498 marginRight: '10px'
17499 },
17500 attrs: {
17501 fill: color
17502 }
17503 });
17504 };
17505
17506 var LegendView = (function (props) {
17507 var items = props.items,
17508 itemWidth = props.itemWidth,
17509 itemFormatter = props.itemFormatter,
17510 style = props.style,
17511 _props$marker = props.marker,
17512 marker = _props$marker === void 0 ? 'circle' : _props$marker,
17513 nameStyle = props.nameStyle,
17514 valueStyle = props.valueStyle,
17515 valuePrefix = props.valuePrefix;
17516
17517 var formatValue = function formatValue(value) {
17518 var valuePrefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ": ";
17519 return "".concat(valuePrefix).concat(value);
17520 };
17521
17522 return jsx("group", {
17523 style: style
17524 }, items.map(function (item) {
17525 var color = item.color,
17526 name = item.name,
17527 value = item.value,
17528 filtered = item.filtered,
17529 tickValue = item.tickValue;
17530 var valueText = isFunction(itemFormatter) ? itemFormatter(value, tickValue) : value;
17531 return jsx("group", {
17532 className: "legend-item",
17533 style: {
17534 width: itemWidth,
17535 display: 'flex',
17536 flexDirection: 'row',
17537 alignItems: 'center',
17538 justifyContent: 'flex-start',
17539 padding: ['6px', '6px', '6px', 0]
17540 },
17541 "data-item": item
17542 }, jsx(Marker$1, {
17543 color: filtered ? '#bfbfbf' : color,
17544 type: marker
17545 }), jsx("text", {
17546 attrs: _objectSpread({
17547 fill: filtered ? '#bfbfbf' : '#808080',
17548 text: name
17549 }, nameStyle)
17550 }), valueText ? jsx("text", {
17551 attrs: _objectSpread({
17552 fill: '#808080',
17553 text: formatValue(valueText, valuePrefix)
17554 }, valueStyle)
17555 }) : null);
17556 }));
17557 });
17558
17559 var index$5 = withLegend(LegendView);
17560
17561 function isInBBox$1(bbox, point) {
17562 var minX = bbox.minX,
17563 maxX = bbox.maxX,
17564 minY = bbox.minY,
17565 maxY = bbox.maxY;
17566 var x = point.x,
17567 y = point.y;
17568 return minX <= x && maxX >= x && minY <= y && maxY >= y;
17569 }
17570
17571 var withGuide = (function (View) {
17572 return /*#__PURE__*/function (_Component) {
17573 _inherits(Guide, _Component);
17574
17575 var _super = _createSuper(Guide);
17576
17577 function Guide(props) {
17578 var _this;
17579
17580 _classCallCheck(this, Guide);
17581
17582 _this = _super.call(this, props); // 创建ref
17583
17584 _this.triggerRef = {};
17585 _this.state = {};
17586 return _this;
17587 }
17588
17589 _createClass(Guide, [{
17590 key: "willMount",
17591 value: function willMount() {
17592 _get$1(_getPrototypeOf(Guide.prototype), "willMount", this).call(this);
17593
17594 this.getGuideBBox();
17595 }
17596 }, {
17597 key: "didMount",
17598 value: function didMount() {
17599 var _this2 = this;
17600
17601 var context = this.context,
17602 props = this.props;
17603 var canvas = context.canvas;
17604 var onClick = props.onClick;
17605 canvas.on('click', function (ev) {
17606 var points = ev.points;
17607 var shape = _this2.triggerRef.current;
17608 if (!shape || shape.isDestroyed()) return;
17609 var bbox = shape.getBBox();
17610
17611 if (isInBBox$1(bbox, points[0])) {
17612 ev.shape = shape;
17613 onClick && onClick(ev);
17614 }
17615 });
17616 }
17617 }, {
17618 key: "didUpdate",
17619 value: function didUpdate() {
17620 _get$1(_getPrototypeOf(Guide.prototype), "didUpdate", this).call(this);
17621
17622 var shape = this.triggerRef.current;
17623 if (!shape || shape.isDestroyed()) return;
17624
17625 var _shape$get = shape.get('attrs'),
17626 x = _shape$get.x,
17627 y = _shape$get.y,
17628 width = _shape$get.width,
17629 height = _shape$get.height;
17630
17631 var bbox = {
17632 minX: x,
17633 minY: y,
17634 maxX: x + width,
17635 maxY: y + height,
17636 width: width,
17637 height: height
17638 };
17639 this.setState({
17640 guideBBox: bbox
17641 });
17642 }
17643 }, {
17644 key: "getGuideBBox",
17645 value: function getGuideBBox() {
17646 var shape = renderShape(this, this.render(), false);
17647
17648 var _shape$get2 = shape.get('attrs'),
17649 x = _shape$get2.x,
17650 y = _shape$get2.y,
17651 width = _shape$get2.width,
17652 height = _shape$get2.height; // getBBox 没有包含 padding 所以这里手动计算 bbox
17653
17654
17655 var bbox = {
17656 minX: x,
17657 minY: y,
17658 maxX: x + width,
17659 maxY: y + height,
17660 width: width,
17661 height: height
17662 };
17663 this.setState({
17664 guideBBox: bbox
17665 });
17666 shape.destroy();
17667 } // 解析record里的模板字符串,如min、max、50%...
17668
17669 }, {
17670 key: "parseReplaceStr",
17671 value: function parseReplaceStr(value, scale) {
17672 var replaceMap = {
17673 min: 0,
17674 max: 1,
17675 median: 0.5
17676 }; // 传入的是 min、max、median 的
17677
17678 if (!isNil(replaceMap[value])) {
17679 return replaceMap[value];
17680 } // 传入的是 xx%
17681
17682
17683 if (isString(value) && value.indexOf('%') != -1 && !isNaN(Number(value.slice(0, -1)))) {
17684 var rateValue = Number(value.slice(0, -1));
17685 var percent = rateValue / 100;
17686 return percent;
17687 }
17688
17689 return scale.scale(value);
17690 }
17691 }, {
17692 key: "parsePoint",
17693 value: function parsePoint(record) {
17694 var props = this.props;
17695 var chart = props.chart,
17696 coord = props.coord;
17697 var xScale = chart.getXScales()[0]; // 只取第一个yScale
17698
17699 var yScale = chart.getYScales()[0]; // 解析 record 为归一化后的坐标
17700
17701 var x = this.parseReplaceStr(record[xScale.field], xScale);
17702 var y = this.parseReplaceStr(record[yScale.field], yScale);
17703 return coord.convertPoint({
17704 x: x,
17705 y: y
17706 });
17707 }
17708 }, {
17709 key: "convertPoints",
17710 value: function convertPoints(records) {
17711 var _this3 = this;
17712
17713 return records.map(function (record) {
17714 return _this3.parsePoint(record);
17715 });
17716 }
17717 }, {
17718 key: "getGuideTheme",
17719 value: function getGuideTheme() {
17720 var context = this.context;
17721 var theme = context.theme;
17722 return theme.guide;
17723 }
17724 }, {
17725 key: "render",
17726 value: function render() {
17727 var props = this.props,
17728 context = this.context;
17729 var coord = props.coord,
17730 _props$records = props.records,
17731 records = _props$records === void 0 ? [] : _props$records,
17732 animation = props.animation,
17733 chart = props.chart;
17734 var width = context.width,
17735 height = context.height;
17736 var points = this.convertPoints(records);
17737 var theme = this.getGuideTheme();
17738 var guideBBox = this.state.guideBBox;
17739 var animationCfg = animation;
17740
17741 if (isFunction(animation)) {
17742 // 透传绘制关键点和chart实例
17743 animationCfg = animation(points, chart);
17744 }
17745
17746 return jsx(View, _objectSpread(_objectSpread({
17747 triggerRef: this.triggerRef,
17748 points: points,
17749 theme: theme,
17750 coord: coord
17751 }, props), {}, {
17752 canvasWidth: width,
17753 canvasHeight: height,
17754 guideBBox: guideBBox,
17755 animation: animationCfg
17756 }));
17757 }
17758 }]);
17759
17760 return Guide;
17761 }(Component);
17762 });
17763
17764 var TextGuideView = (function (props, context) {
17765 var _props$theme = props.theme,
17766 theme = _props$theme === void 0 ? {} : _props$theme;
17767
17768 var _deepMix = deepMix(_objectSpread({}, theme.text), props),
17769 points = _deepMix.points,
17770 style = _deepMix.style,
17771 offsetX = _deepMix.offsetX,
17772 offsetY = _deepMix.offsetY,
17773 content = _deepMix.content,
17774 animation = _deepMix.animation;
17775
17776 var _ref = points[0] || {},
17777 x = _ref.x,
17778 y = _ref.y;
17779
17780 var offsetXNum = context.px2hd(offsetX);
17781 var offsetYNum = context.px2hd(offsetY);
17782 var posX = x + (offsetXNum || 0);
17783 var posY = y + (offsetYNum || 0);
17784 return jsx("text", {
17785 attrs: _objectSpread({
17786 text: content,
17787 x: posX,
17788 y: posY
17789 }, style),
17790 animation: deepMix({
17791 update: {
17792 easing: 'linear',
17793 duration: 450,
17794 property: ['x', 'y']
17795 }
17796 }, animation)
17797 });
17798 });
17799
17800 var PointGuideView = (function (props, context) {
17801 var theme = props.theme;
17802
17803 var _deepMix = deepMix(_objectSpread({}, theme.point), props),
17804 points = _deepMix.points,
17805 style = _deepMix.style,
17806 offsetX = _deepMix.offsetX,
17807 offsetY = _deepMix.offsetY,
17808 animation = _deepMix.animation;
17809
17810 var _ref = points[0] || {},
17811 x = _ref.x,
17812 y = _ref.y;
17813
17814 var offsetXNum = context.px2hd(offsetX);
17815 var offsetYNum = context.px2hd(offsetY);
17816 var posX = x + (offsetXNum || 0);
17817 var posY = y + (offsetYNum || 0);
17818 return jsx("group", null, jsx("circle", {
17819 attrs: _objectSpread({
17820 x: posX,
17821 y: posY
17822 }, style),
17823 animation: animation
17824 }));
17825 });
17826
17827 var LineGuideView = (function (props, context) {
17828 var _props$theme = props.theme,
17829 theme = _props$theme === void 0 ? {} : _props$theme;
17830
17831 var _deepMix = deepMix(_objectSpread({}, theme.line), props),
17832 points = _deepMix.points,
17833 style = _deepMix.style,
17834 offsetX = _deepMix.offsetX,
17835 offsetY = _deepMix.offsetY,
17836 animation = _deepMix.animation;
17837
17838 var _ref = points[0] || {},
17839 x1 = _ref.x,
17840 y1 = _ref.y;
17841
17842 var _ref2 = points[1] || {},
17843 x2 = _ref2.x,
17844 y2 = _ref2.y;
17845
17846 var offsetXNum = context.px2hd(offsetX);
17847 var offsetYNum = context.px2hd(offsetY);
17848 var posX1 = x1 + (isArray(offsetXNum) ? offsetXNum[0] || 0 : offsetXNum || 0);
17849 var posY1 = y1 + (isArray(offsetYNum) ? offsetYNum[0] || 0 : offsetYNum || 0);
17850 var posX2 = x2 + (isArray(offsetXNum) ? offsetXNum[1] || 0 : offsetXNum || 0);
17851 var posY2 = y2 + (isArray(offsetYNum) ? offsetYNum[1] || 0 : offsetYNum || 0);
17852 return jsx("group", null, jsx("line", {
17853 attrs: _objectSpread({
17854 x1: posX1,
17855 y1: posY1,
17856 x2: posX2,
17857 y2: posY2
17858 }, style),
17859 animation: animation
17860 }));
17861 });
17862
17863 var ArcGuideView = (function (props) {
17864 var _props$theme = props.theme,
17865 theme = _props$theme === void 0 ? {} : _props$theme;
17866
17867 var _deepMix = deepMix(_objectSpread({}, theme.line), props),
17868 coord = _deepMix.coord,
17869 points = _deepMix.points,
17870 style = _deepMix.style,
17871 animation = _deepMix.animation;
17872
17873 var start = points[0] || {};
17874 var end = points[1] || {};
17875 var coordCenter = coord.center;
17876 var radius = Math.sqrt((start.x - coordCenter.x) * (start.x - coordCenter.x) + (start.y - coordCenter.y) * (start.y - coordCenter.y));
17877 var startAngle = Math.atan2(start.y - coordCenter.y, start.x - coordCenter.x);
17878 var endAngle = Math.atan2(end.y - coordCenter.y, end.x - coordCenter.x);
17879 return jsx("group", null, jsx("arc", {
17880 attrs: _objectSpread({
17881 x: coordCenter.x,
17882 y: coordCenter.y,
17883 r: radius,
17884 startAngle: startAngle,
17885 endAngle: endAngle
17886 }, style),
17887 animation: animation
17888 }));
17889 });
17890
17891 var RectGuideView = (function (props) {
17892 var _props$theme = props.theme,
17893 theme = _props$theme === void 0 ? {} : _props$theme;
17894
17895 var _deepMix = deepMix(_objectSpread({}, theme.rect), props),
17896 points = _deepMix.points,
17897 style = _deepMix.style,
17898 animation = _deepMix.animation;
17899
17900 var start = points[0] || {};
17901 var end = points[1] || {};
17902 return jsx("group", null, jsx("rect", {
17903 attrs: _objectSpread({
17904 x: Math.min(start.x, end.x),
17905 y: Math.min(start.y, end.y),
17906 width: Math.abs(end.x - start.x),
17907 height: Math.abs(start.y - end.y)
17908 }, style),
17909 animation: animation
17910 }));
17911 });
17912
17913 var defaultProps = {
17914 offsetX: 0,
17915 offsetY: 0,
17916 points: [],
17917 src: ''
17918 };
17919 var baseAttrs = {
17920 height: '20px',
17921 width: '20px'
17922 };
17923 var ImageGuideView = (function (props, context) {
17924 var cfg = deepMix({}, defaultProps, props);
17925 var points = cfg.points,
17926 style = cfg.style,
17927 attrs = cfg.attrs,
17928 offsetX = cfg.offsetX,
17929 offsetY = cfg.offsetY,
17930 src = cfg.src,
17931 animation = cfg.animation;
17932
17933 var _ref = points[0] || {},
17934 x = _ref.x,
17935 y = _ref.y;
17936
17937 var _attrs$height = attrs.height,
17938 height = _attrs$height === void 0 ? 0 : _attrs$height,
17939 _attrs$width = attrs.width,
17940 width = _attrs$width === void 0 ? 0 : _attrs$width;
17941 var heightNum = context.px2hd(height + 'px');
17942 var widthNum = context.px2hd(width + 'px');
17943 var offsetXNum = context.px2hd(offsetX);
17944 var offsetYNum = context.px2hd(offsetY);
17945 var posX = x + (offsetXNum || 0) - heightNum / 2;
17946 var posY = y + (offsetYNum || 0) - widthNum / 2;
17947 return jsx("group", {
17948 style: style
17949 }, jsx("image", {
17950 attrs: _objectSpread(_objectSpread(_objectSpread({}, baseAttrs), attrs), {}, {
17951 height: heightNum,
17952 width: widthNum,
17953 x: posX,
17954 y: posY,
17955 src: src
17956 }),
17957 animation: deepMix({
17958 update: {
17959 easing: 'linear',
17960 duration: 450,
17961 property: ['x', 'y']
17962 }
17963 }, animation)
17964 }));
17965 });
17966
17967 var defaultProps$1 = {
17968 offsetX: 0,
17969 offsetY: 0,
17970 points: [],
17971 direct: 'tl',
17972 side: 6,
17973 autoAdjust: true
17974 };
17975 var defaultStyle = {
17976 container: {
17977 fill: '#1677FF',
17978 radius: 2,
17979 padding: [3, 5]
17980 },
17981 text: {
17982 fontSize: '22px',
17983 fill: '#fff'
17984 },
17985 arrow: {
17986 fill: '#1677FF'
17987 }
17988 };
17989 var TagGuideView = (function (props, context) {
17990 var cfg = _objectSpread(_objectSpread({}, defaultProps$1), props);
17991
17992 var points = cfg.points,
17993 content = cfg.content,
17994 offsetX = cfg.offsetX,
17995 offsetY = cfg.offsetY,
17996 direct = cfg.direct,
17997 side = cfg.side,
17998 autoAdjust = cfg.autoAdjust,
17999 canvasWidth = cfg.canvasWidth,
18000 canvasHeight = cfg.canvasHeight,
18001 guideBBox = cfg.guideBBox,
18002 background = cfg.background,
18003 textStyle = cfg.textStyle,
18004 triggerRef = cfg.triggerRef;
18005
18006 var _ref = points[0] || {},
18007 x = _ref.x,
18008 y = _ref.y;
18009
18010 var _ref2 = guideBBox || {},
18011 guideWidth = _ref2.width,
18012 guideHeight = _ref2.height;
18013
18014 var offsetXNum = context.px2hd(offsetX);
18015 var offsetYNum = context.px2hd(offsetY);
18016 var posX = x + (offsetXNum || 0);
18017 var posY = y + (offsetYNum || 0);
18018
18019 var _getDirect = function _getDirect(point) {
18020 var newDirect = direct;
18021 var x = point.x,
18022 y = point.y;
18023 var vertical = newDirect[0];
18024 var horizontal = newDirect[1]; // adjust for vertical direction
18025
18026 if (vertical === 't' && y - side - guideHeight < 0) {
18027 vertical = 'b';
18028 } else if (vertical === 'b' && y + side + guideHeight > canvasHeight) {
18029 vertical = 't';
18030 } // adjust for horizontal direction
18031
18032
18033 var diff = vertical === 'c' ? side : 0;
18034
18035 if (horizontal === 'l' && x - diff - guideWidth < 0) {
18036 horizontal = 'r';
18037 } else if (horizontal === 'r' && x + diff + guideWidth > canvasWidth) {
18038 horizontal = 'l';
18039 } else if (horizontal === 'c') {
18040 if (guideWidth / 2 + x + diff > canvasWidth) {
18041 horizontal = 'l';
18042 } else if (x - guideWidth / 2 - diff < 0) {
18043 horizontal = 'r';
18044 }
18045 }
18046
18047 newDirect = vertical + horizontal;
18048 return newDirect;
18049 };
18050
18051 var _getArrowPoints = function _getArrowPoints(direct) {
18052 var arrowPoints = []; // const { minX, minY } = guideBBox || {};
18053
18054 if (direct === 'tl') {
18055 arrowPoints = [{
18056 x: posX,
18057 y: posY - side - 1
18058 }, {
18059 x: posX,
18060 y: posY
18061 }, {
18062 x: posX - side,
18063 y: posY - side - 1
18064 }];
18065 posX -= guideWidth || 0;
18066 posY = posY - (guideHeight || 0) - side;
18067 } else if (direct === 'cl') {
18068 arrowPoints = [{
18069 x: posX - side - 1,
18070 y: posY - side
18071 }, {
18072 x: posX - side - 1,
18073 y: posY + side
18074 }, {
18075 x: posX,
18076 y: posY
18077 }];
18078 posX = posX - (guideWidth || 0) - side;
18079 posY -= guideHeight / 2 || 0;
18080 } else if (direct === 'bl') {
18081 arrowPoints = [{
18082 x: posX,
18083 y: posY
18084 }, {
18085 x: posX,
18086 y: posY + side + 1
18087 }, {
18088 x: posX - side,
18089 y: posY + side + 1
18090 }];
18091 posX = posX - (guideWidth || 0);
18092 posY += side;
18093 } else if (direct === 'bc') {
18094 // 有问题
18095 arrowPoints = [{
18096 x: posX,
18097 y: posY
18098 }, {
18099 x: posX - side,
18100 y: posY + side + 1
18101 }, {
18102 x: posX + side,
18103 y: posY + side + 1
18104 }];
18105 posX = posX - (guideWidth / 2 || 0);
18106 posY = posY + side;
18107 } else if (direct === 'br') {
18108 arrowPoints = [{
18109 x: posX,
18110 y: posY
18111 }, {
18112 x: posX,
18113 y: posY + side + 1
18114 }, {
18115 x: posX + side,
18116 y: posY + side + 1
18117 }];
18118 posY += side;
18119 } else if (direct === 'cr') {
18120 arrowPoints = [{
18121 x: posX,
18122 y: posY
18123 }, {
18124 x: posX + side,
18125 y: posY - side
18126 }, {
18127 x: posX + side,
18128 y: posY + side
18129 }];
18130 posX += side;
18131 posY -= guideHeight / 2 || 0;
18132 } else if (direct === 'tr') {
18133 arrowPoints = [{
18134 x: posX,
18135 y: posY
18136 }, {
18137 x: posX,
18138 y: posY - side - 1
18139 }, {
18140 x: posX + side,
18141 y: posY - side - 1
18142 }];
18143 posY = posY - (guideHeight || 0) - side;
18144 } else if (direct === 'tc') {
18145 arrowPoints = [{
18146 x: posX,
18147 y: posY
18148 }, {
18149 x: posX - side,
18150 y: posY - side - 1
18151 }, {
18152 x: posX + side,
18153 y: posY - side - 1
18154 }];
18155 posX -= guideWidth / 2 || 0;
18156 posY = posY - (guideHeight || 0) - side;
18157 }
18158
18159 return arrowPoints;
18160 };
18161
18162 var dr = autoAdjust ? _getDirect(points[0]) : direct;
18163
18164 var arrowPoints = _getArrowPoints(dr);
18165
18166 return jsx("group", {
18167 attrs: _objectSpread({
18168 fill: defaultStyle.container.fill,
18169 radius: defaultStyle.container.radius
18170 }, background),
18171 style: _objectSpread({
18172 left: posX,
18173 top: posY,
18174 padding: defaultStyle.container.padding
18175 }, background),
18176 ref: triggerRef
18177 }, jsx("text", {
18178 attrs: _objectSpread({
18179 text: content,
18180 fontSize: defaultStyle.text.fontSize,
18181 fill: defaultStyle.text.fill
18182 }, textStyle)
18183 }), guideBBox && jsx("polygon", {
18184 attrs: {
18185 points: arrowPoints,
18186 fill: (background === null || background === void 0 ? void 0 : background.fill) || defaultStyle.arrow.fill
18187 }
18188 }));
18189 });
18190
18191 var DefaultGuideView = function DefaultGuideView() {
18192 return null;
18193 };
18194
18195 var TextGuide = withGuide(TextGuideView);
18196 var PointGuide = withGuide(PointGuideView);
18197 var LineGuide = withGuide(LineGuideView);
18198 var ArcGuide = withGuide(ArcGuideView);
18199 var RectGuide = withGuide(RectGuideView);
18200 var ImageGuide = withGuide(ImageGuideView);
18201 var TagGuide = withGuide(TagGuideView);
18202 var index$6 = withGuide(DefaultGuideView);
18203
18204 var withTooltip = (function (View) {
18205 return /*#__PURE__*/function (_Component) {
18206 _inherits(Tooltip, _Component);
18207
18208 var _super = _createSuper(Tooltip);
18209
18210 function Tooltip(props) {
18211 var _this;
18212
18213 _classCallCheck(this, Tooltip);
18214
18215 _this = _super.call(this, props);
18216
18217 _this._triggerOn = function (ev) {
18218 var points = ev.points;
18219
18220 _this.show(points[0], ev);
18221 };
18222
18223 _this._triggerOff = function () {
18224 var _assertThisInitialize = _assertThisInitialized(_this),
18225 _assertThisInitialize2 = _assertThisInitialize.props.alwaysShow,
18226 alwaysShow = _assertThisInitialize2 === void 0 ? false : _assertThisInitialize2;
18227
18228 if (!alwaysShow) {
18229 _this.hide();
18230 }
18231 };
18232
18233 _this.state = {
18234 records: null
18235 };
18236 return _this;
18237 }
18238
18239 _createClass(Tooltip, [{
18240 key: "updateCoord",
18241 value: function updateCoord() {
18242 var props = this.props,
18243 context = this.context;
18244 var _props$padding = props.padding,
18245 padding = _props$padding === void 0 ? '10px' : _props$padding,
18246 chart = props.chart;
18247 chart.updateCoordFor(this, {
18248 position: 'top',
18249 width: 0,
18250 height: context.px2hd(padding)
18251 });
18252 }
18253 }, {
18254 key: "willMount",
18255 value: function willMount() {
18256 this.updateCoord();
18257 }
18258 }, {
18259 key: "didMount",
18260 value: function didMount() {
18261 this._initShow();
18262
18263 this._initEvent();
18264 }
18265 }, {
18266 key: "willReceiveProps",
18267 value: function willReceiveProps(nextProps) {
18268 var nextDefaultItem = nextProps.defaultItem,
18269 nextCoord = nextProps.coord;
18270 var _this$props = this.props,
18271 lastDefaultItem = _this$props.defaultItem,
18272 lastCoord = _this$props.coord; // 默认元素或坐标有变动,均需重新渲染
18273
18274 if (!equal(nextDefaultItem, lastDefaultItem) || !equal(nextCoord, lastCoord)) {
18275 this._showByData(nextDefaultItem);
18276 }
18277 }
18278 }, {
18279 key: "_initShow",
18280 value: function _initShow() {
18281 var props = this.props;
18282 var defaultItem = props.defaultItem;
18283
18284 this._showByData(defaultItem);
18285 }
18286 }, {
18287 key: "_showByData",
18288 value: function _showByData(dataItem) {
18289 var _this2 = this;
18290
18291 if (!dataItem) return;
18292 var props = this.props;
18293 var chart = props.chart; // 因为 tooltip 有可能在 geometry 之前,所以需要等 geometry render 完后再执行
18294
18295 setTimeout(function () {
18296 var point = chart.getPosition(dataItem);
18297
18298 _this2.show(point);
18299 }, 0);
18300 }
18301 }, {
18302 key: "_initEvent",
18303 value: function _initEvent() {
18304 var context = this.context,
18305 props = this.props;
18306 var canvas = context.canvas;
18307 var _props$triggerOn = props.triggerOn,
18308 triggerOn = _props$triggerOn === void 0 ? 'press' : _props$triggerOn,
18309 _props$triggerOff = props.triggerOff,
18310 triggerOff = _props$triggerOff === void 0 ? 'pressend' : _props$triggerOff;
18311 canvas.on(triggerOn, this._triggerOn);
18312 canvas.on(triggerOff, this._triggerOff);
18313 }
18314 }, {
18315 key: "didUnmount",
18316 value: function didUnmount() {
18317 this._clearEvents();
18318 }
18319 }, {
18320 key: "_clearEvents",
18321 value: function _clearEvents() {
18322 var context = this.context,
18323 props = this.props;
18324 var canvas = context.canvas;
18325 var _props$triggerOn2 = props.triggerOn,
18326 triggerOn = _props$triggerOn2 === void 0 ? 'press' : _props$triggerOn2,
18327 _props$triggerOff2 = props.triggerOff,
18328 triggerOff = _props$triggerOff2 === void 0 ? 'pressend' : _props$triggerOff2; // 解绑事件
18329
18330 canvas.off(triggerOn, this._triggerOn);
18331 canvas.off(triggerOff, this._triggerOff);
18332 }
18333 }, {
18334 key: "show",
18335 value: function show(point, _ev) {
18336 var props = this.props;
18337 var chart = props.chart,
18338 onChange = props.onChange;
18339 var snapRecords = chart.getSnapRecords(point, true); // 超出边界会自动调整
18340
18341 if (!snapRecords || !snapRecords.length) return;
18342 var legendItems = chart.getLegendItems();
18343 var _snapRecords$ = snapRecords[0],
18344 xField = _snapRecords$.xField,
18345 yField = _snapRecords$.yField;
18346 var xScale = chart.getScale(xField);
18347 var yScale = chart.getScale(yField);
18348 var records = snapRecords.map(function (record) {
18349 var origin = record.origin,
18350 xField = record.xField,
18351 yField = record.yField;
18352 var value = yScale.getText(origin[yField]); // 默认取 alias 的配置
18353
18354 var name = yScale.alias;
18355
18356 if (!name) {
18357 name = xScale.getText(origin[xField]);
18358
18359 if (legendItems && legendItems.length) {
18360 var item = find(legendItems, function (item) {
18361 var field = item.field,
18362 tickValue = item.tickValue;
18363 return origin[field] === tickValue;
18364 });
18365
18366 if (item && item.name) {
18367 name = item.name;
18368 }
18369 }
18370 }
18371
18372 return _objectSpread(_objectSpread({}, record), {}, {
18373 name: name,
18374 value: value
18375 });
18376 });
18377
18378 if (!isArray(records) || !records.length) {
18379 return;
18380 }
18381
18382 this.setState({
18383 records: records
18384 });
18385
18386 if (isFunction(onChange)) {
18387 onChange(records);
18388 }
18389 }
18390 }, {
18391 key: "hide",
18392 value: function hide() {
18393 this.setState({
18394 records: null
18395 });
18396 }
18397 }, {
18398 key: "render",
18399 value: function render() {
18400 var props = this.props,
18401 state = this.state;
18402 var visible = props.visible;
18403
18404 if (visible === false) {
18405 return null;
18406 }
18407
18408 var records = state.records;
18409 if (!records || !records.length) return null;
18410 return jsx(View, _objectSpread(_objectSpread({}, props), {}, {
18411 records: records
18412 }));
18413 }
18414 }]);
18415
18416 return Tooltip;
18417 }(Component);
18418 });
18419
18420 function createRef() {
18421 var ref = {
18422 current: null
18423 };
18424 return ref;
18425 }
18426
18427 var defaultStyle$1 = {
18428 showTitle: false,
18429 showCrosshairs: false,
18430 crosshairsType: 'y',
18431 crosshairsStyle: {
18432 stroke: 'rgba(0, 0, 0, 0.25)',
18433 lineWidth: '2px'
18434 },
18435 showTooltipMarker: false,
18436 markerBackgroundStyle: {
18437 fill: '#CCD6EC',
18438 opacity: 0.3,
18439 padding: '6px'
18440 },
18441 tooltipMarkerStyle: {
18442 fill: '#fff',
18443 lineWidth: '3px'
18444 },
18445 background: {
18446 radius: '4px',
18447 fill: 'rgba(0, 0, 0, 0.65)',
18448 padding: ['6px', '10px']
18449 },
18450 titleStyle: {
18451 fontSize: '24px',
18452 fill: '#fff',
18453 textAlign: 'start',
18454 textBaseline: 'top'
18455 },
18456 nameStyle: {
18457 fontSize: '24px',
18458 fill: 'rgba(255, 255, 255, 0.65)',
18459 textAlign: 'start',
18460 textBaseline: 'middle'
18461 },
18462 valueStyle: {
18463 fontSize: '24px',
18464 fill: '#fff',
18465 textAlign: 'start',
18466 textBaseline: 'middle'
18467 },
18468 joinString: ': ',
18469 showItemMarker: true,
18470 itemMarkerStyle: {
18471 width: '12px',
18472 radius: '6px',
18473 symbol: 'circle',
18474 lineWidth: '2px',
18475 stroke: '#fff'
18476 },
18477 layout: 'horizontal',
18478 snap: false,
18479 xTipTextStyle: {
18480 fontSize: '24px',
18481 fill: '#fff'
18482 },
18483 yTipTextStyle: {
18484 fontSize: '24px',
18485 fill: '#fff'
18486 },
18487 xTipBackground: {
18488 radius: '4px',
18489 fill: 'rgba(0, 0, 0, 0.65)',
18490 padding: ['6px', '10px'],
18491 marginLeft: '-50%',
18492 marginTop: '6px'
18493 },
18494 yTipBackground: {
18495 radius: '4px',
18496 fill: 'rgba(0, 0, 0, 0.65)',
18497 padding: ['6px', '10px'],
18498 marginLeft: '-100%',
18499 marginTop: '-50%'
18500 }
18501 };
18502
18503 function directionEnabled(mode, dir) {
18504 if (mode === undefined) {
18505 return true;
18506 } else if (typeof mode === 'string') {
18507 return mode.indexOf(dir) !== -1;
18508 }
18509
18510 return false;
18511 }
18512
18513 var RenderItemMarker = function RenderItemMarker(props) {
18514 var records = props.records,
18515 coord = props.coord,
18516 context = props.context,
18517 markerBackgroundStyle = props.markerBackgroundStyle;
18518 var point = coord.convertPoint({
18519 x: 1,
18520 y: 1
18521 });
18522 var padding = context.px2hd(markerBackgroundStyle.padding || '6px');
18523 var xPoints = [].concat(_toConsumableArray(records.map(function (record) {
18524 return record.xMin;
18525 })), _toConsumableArray(records.map(function (record) {
18526 return record.xMax;
18527 })));
18528 var yPoints = [].concat(_toConsumableArray(records.map(function (record) {
18529 return record.yMin;
18530 })), _toConsumableArray(records.map(function (record) {
18531 return record.yMax;
18532 })));
18533
18534 if (coord.transposed) {
18535 xPoints.push(point.x);
18536 } else {
18537 yPoints.push(point.y);
18538 }
18539
18540 var xMin = Math.min.apply(null, xPoints);
18541 var xMax = Math.max.apply(null, xPoints);
18542 var yMin = Math.min.apply(null, yPoints);
18543 var yMax = Math.max.apply(null, yPoints);
18544 var x = coord.transposed ? xMin : xMin - padding;
18545 var y = coord.transposed ? yMin - padding : yMin;
18546 var width = coord.transposed ? xMax - xMin : xMax - xMin + 2 * padding;
18547 var height = coord.transposed ? yMax - yMin + 2 * padding : yMax - yMin;
18548 return jsx("rect", {
18549 attrs: _objectSpread({
18550 x: x,
18551 y: y,
18552 width: width,
18553 height: height
18554 }, markerBackgroundStyle)
18555 });
18556 };
18557
18558 var RenderCrosshairs = function RenderCrosshairs(props) {
18559 var records = props.records,
18560 coord = props.coord,
18561 chart = props.chart,
18562 crosshairsType = props.crosshairsType,
18563 crosshairsStyle = props.crosshairsStyle;
18564 var coordLeft = coord.left,
18565 coordTop = coord.top,
18566 coordRight = coord.right,
18567 coordBottom = coord.bottom,
18568 center = coord.center;
18569 var firstRecord = records[0];
18570 var x = firstRecord.x,
18571 y = firstRecord.y,
18572 origin = firstRecord.origin,
18573 xField = firstRecord.xField;
18574
18575 if (coord.isPolar) {
18576 // 极坐标下的辅助线
18577 var xScale = chart.getScale(xField);
18578 var ticks = xScale.getTicks();
18579 var tick = find(ticks, function (tick) {
18580 return origin[xField] === tick.tickValue;
18581 });
18582 var end = coord.convertPoint({
18583 x: tick.value,
18584 y: 1
18585 });
18586 return jsx("line", {
18587 attrs: _objectSpread({
18588 x1: center.x,
18589 y1: center.y,
18590 x2: end.x,
18591 y2: end.y
18592 }, crosshairsStyle)
18593 });
18594 }
18595
18596 return jsx("group", null, directionEnabled(crosshairsType, 'x') ? jsx("line", {
18597 attrs: _objectSpread({
18598 x1: coordLeft,
18599 y1: y,
18600 x2: coordRight,
18601 y2: y
18602 }, crosshairsStyle)
18603 }) : null, directionEnabled(crosshairsType, 'y') ? jsx("line", {
18604 attrs: _objectSpread({
18605 x1: x,
18606 y1: coordTop,
18607 x2: x,
18608 y2: coordBottom
18609 }, crosshairsStyle)
18610 }) : null);
18611 };
18612
18613 var TooltipView = /*#__PURE__*/function (_Component) {
18614 _inherits(TooltipView, _Component);
18615
18616 var _super = _createSuper(TooltipView);
18617
18618 function TooltipView(props) {
18619 var _this;
18620
18621 _classCallCheck(this, TooltipView);
18622
18623 _this = _super.call(this, props);
18624 _this.rootRef = createRef();
18625 _this.arrowRef = createRef();
18626 return _this;
18627 } // 调整 显示的位置
18628
18629
18630 _createClass(TooltipView, [{
18631 key: "_position",
18632 value: function _position() {
18633 var props = this.props,
18634 context = this.context,
18635 rootRef = this.rootRef,
18636 arrowRef = this.arrowRef;
18637 var group = rootRef.current;
18638
18639 if (!group) {
18640 return;
18641 }
18642
18643 var records = props.records,
18644 coord = props.coord;
18645 var arrowWidth = context.px2hd('6px');
18646 var record = records[0]; // 中心点
18647
18648 var x = record.x;
18649 var coordLeft = coord.left,
18650 coordWidth = coord.width;
18651
18652 var _group$get = group.get('attrs'),
18653 y = _group$get.y,
18654 width = _group$get.width,
18655 height = _group$get.height,
18656 radius = _group$get.radius;
18657
18658 var halfWidth = width / 2; // 让 tooltip 限制在 coord 的显示范围内
18659
18660 var offsetX = Math.min(Math.max(x - coordLeft - halfWidth, -arrowWidth - radius), coordWidth - width + arrowWidth + radius); // 因为默认是从 coord 的范围内显示的,所以要往上移,移出 coord,避免挡住 geometry
18661
18662 var offset = Math.min(y, height + arrowWidth); // 因为不能超出 canvas 画布区域,所以最大只能是 y
18663
18664 group.moveTo(offsetX, -offset);
18665 arrowRef.current.moveTo(0, height - offset);
18666 }
18667 }, {
18668 key: "didMount",
18669 value: function didMount() {
18670 this._position();
18671 }
18672 }, {
18673 key: "didUpdate",
18674 value: function didUpdate() {
18675 this._position();
18676 }
18677 }, {
18678 key: "render",
18679 value: function render() {
18680 var props = this.props,
18681 context = this.context;
18682 var records = props.records,
18683 coord = props.coord;
18684 var coordLeft = coord.left,
18685 coordTop = coord.top,
18686 coordBottom = coord.bottom;
18687 var firstRecord = records[0];
18688 var x = firstRecord.x,
18689 y = firstRecord.y;
18690 var xFirstText = firstRecord.name,
18691 yFirstText = firstRecord.value;
18692 var chart = props.chart,
18693 customBackground = props.background,
18694 _props$showTooltipMar = props.showTooltipMarker,
18695 showTooltipMarker = _props$showTooltipMar === void 0 ? defaultStyle$1.showTooltipMarker : _props$showTooltipMar,
18696 _props$markerBackgrou = props.markerBackgroundStyle,
18697 markerBackgroundStyle = _props$markerBackgrou === void 0 ? defaultStyle$1.markerBackgroundStyle : _props$markerBackgrou,
18698 _props$showItemMarker = props.showItemMarker,
18699 showItemMarker = _props$showItemMarker === void 0 ? defaultStyle$1.showItemMarker : _props$showItemMarker,
18700 customItemMarkerStyle = props.itemMarkerStyle,
18701 nameStyle = props.nameStyle,
18702 valueStyle = props.valueStyle,
18703 _props$joinString = props.joinString,
18704 joinString = _props$joinString === void 0 ? defaultStyle$1.joinString : _props$joinString,
18705 _props$showCrosshairs = props.showCrosshairs,
18706 showCrosshairs = _props$showCrosshairs === void 0 ? defaultStyle$1.showCrosshairs : _props$showCrosshairs,
18707 crosshairsStyle = props.crosshairsStyle,
18708 _props$crosshairsType = props.crosshairsType,
18709 crosshairsType = _props$crosshairsType === void 0 ? defaultStyle$1.crosshairsType : _props$crosshairsType,
18710 _props$snap = props.snap,
18711 snap = _props$snap === void 0 ? defaultStyle$1.snap : _props$snap,
18712 _props$tooltipMarkerS = props.tooltipMarkerStyle,
18713 tooltipMarkerStyle = _props$tooltipMarkerS === void 0 ? defaultStyle$1.tooltipMarkerStyle : _props$tooltipMarkerS,
18714 showXTip = props.showXTip,
18715 showYTip = props.showYTip,
18716 xTip = props.xTip,
18717 yTip = props.yTip,
18718 _props$xTipTextStyle = props.xTipTextStyle,
18719 xTipTextStyle = _props$xTipTextStyle === void 0 ? defaultStyle$1.xTipTextStyle : _props$xTipTextStyle,
18720 _props$yTipTextStyle = props.yTipTextStyle,
18721 yTipTextStyle = _props$yTipTextStyle === void 0 ? defaultStyle$1.yTipTextStyle : _props$yTipTextStyle,
18722 _props$xTipBackground = props.xTipBackground,
18723 xTipBackground = _props$xTipBackground === void 0 ? defaultStyle$1.xTipBackground : _props$xTipBackground,
18724 _props$yTipBackground = props.yTipBackground,
18725 yTipBackground = _props$yTipBackground === void 0 ? defaultStyle$1.yTipBackground : _props$yTipBackground,
18726 _props$custom = props.custom,
18727 custom = _props$custom === void 0 ? false : _props$custom,
18728 customText = props.customText;
18729
18730 var itemMarkerStyle = _objectSpread(_objectSpread({}, customItemMarkerStyle), defaultStyle$1.itemMarkerStyle);
18731
18732 var background = _objectSpread(_objectSpread({}, defaultStyle$1.background), customBackground);
18733
18734 var arrowWidth = context.px2hd('6px');
18735 return jsx("group", null, jsx("group", {
18736 style: {
18737 left: coordLeft,
18738 top: coordTop
18739 }
18740 }, !custom && jsx("group", null, jsx("group", {
18741 ref: this.rootRef,
18742 style: background,
18743 attrs: background
18744 }, jsx("group", {
18745 style: {
18746 display: 'flex',
18747 flexDirection: 'row',
18748 flexWrap: 'wrap',
18749 padding: [0, 0, 0, '6px']
18750 }
18751 }, records.map(function (record) {
18752 var name = record.name,
18753 value = record.value;
18754 return jsx("group", {
18755 style: {
18756 display: 'flex',
18757 flexDirection: 'row',
18758 alignItems: 'center',
18759 padding: [0, '6px', 0, 0]
18760 }
18761 }, showItemMarker ? jsx("marker", {
18762 style: {
18763 width: itemMarkerStyle.width,
18764 marginRight: '6px'
18765 },
18766 attrs: _objectSpread(_objectSpread({}, itemMarkerStyle), {}, {
18767 fill: record.color
18768 })
18769 }) : null, customText && isFunction(customText) ? customText(record) : jsx("group", {
18770 style: {
18771 display: 'flex',
18772 flexDirection: 'row'
18773 }
18774 }, jsx("text", {
18775 attrs: _objectSpread(_objectSpread(_objectSpread({}, defaultStyle$1.nameStyle), nameStyle), {}, {
18776 text: value ? "".concat(name).concat(joinString) : name
18777 })
18778 }), jsx("text", {
18779 attrs: _objectSpread(_objectSpread(_objectSpread({}, defaultStyle$1.valueStyle), valueStyle), {}, {
18780 text: value
18781 })
18782 })));
18783 }))), jsx("polygon", {
18784 ref: this.arrowRef,
18785 attrs: {
18786 points: [{
18787 x: x - arrowWidth,
18788 y: coordTop
18789 }, {
18790 x: x + arrowWidth,
18791 y: coordTop
18792 }, {
18793 x: x,
18794 y: coordTop + arrowWidth
18795 }],
18796 fill: background.fill
18797 }
18798 })), showTooltipMarker ? jsx(RenderItemMarker, {
18799 coord: coord,
18800 context: context,
18801 records: records,
18802 markerBackgroundStyle: markerBackgroundStyle
18803 }) : null, showCrosshairs ? jsx(RenderCrosshairs, {
18804 chart: chart,
18805 coord: coord,
18806 records: records,
18807 crosshairsType: crosshairsType,
18808 crosshairsStyle: _objectSpread(_objectSpread({}, defaultStyle$1.crosshairsStyle), crosshairsStyle)
18809 }) : null, snap ? records.map(function (item) {
18810 var x = item.x,
18811 y = item.y,
18812 color = item.color,
18813 shape = item.shape;
18814 return jsx("circle", {
18815 attrs: _objectSpread(_objectSpread({
18816 x: x,
18817 y: y,
18818 r: '6px',
18819 stroke: color,
18820 fill: color
18821 }, shape), tooltipMarkerStyle)
18822 });
18823 }) : null), showXTip && jsx("group", {
18824 style: _objectSpread(_objectSpread({
18825 left: x,
18826 top: coordBottom
18827 }, defaultStyle$1.xTipBackground), xTipBackground),
18828 attrs: _objectSpread(_objectSpread({}, defaultStyle$1.xTipBackground), xTipBackground)
18829 }, jsx("text", {
18830 attrs: _objectSpread(_objectSpread(_objectSpread({}, defaultStyle$1.xTipTextStyle), xTipTextStyle), {}, {
18831 text: isFunction(xTip) ? xTip(xFirstText) : xFirstText
18832 })
18833 })), showYTip && jsx("group", {
18834 style: _objectSpread(_objectSpread({
18835 left: coordLeft,
18836 top: y
18837 }, defaultStyle$1.yTipBackground), yTipBackground),
18838 attrs: _objectSpread(_objectSpread({}, defaultStyle$1.yTipBackground), yTipBackground)
18839 }, jsx("text", {
18840 attrs: _objectSpread(_objectSpread(_objectSpread({}, defaultStyle$1.yTipTextStyle), yTipTextStyle), {}, {
18841 text: isFunction(yTip) ? yTip(yFirstText) : yFirstText
18842 })
18843 })));
18844 }
18845 }]);
18846
18847 return TooltipView;
18848 }(Component);
18849
18850 var index$7 = withTooltip(TooltipView);
18851
18852 function count(node) {
18853 var sum = 0,
18854 children = node.children,
18855 i = children && children.length;
18856 if (!i) sum = 1;else while (--i >= 0) {
18857 sum += children[i].value;
18858 }
18859 node.value = sum;
18860 }
18861
18862 function node_count () {
18863 return this.eachAfter(count);
18864 }
18865
18866 var createForOfIteratorHelper = createCommonjsModule(function (module) {
18867 function _createForOfIteratorHelper(o, allowArrayLike) {
18868 var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"];
18869
18870 if (!it) {
18871 if (Array.isArray(o) || (it = unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") {
18872 if (it) o = it;
18873 var i = 0;
18874
18875 var F = function F() {};
18876
18877 return {
18878 s: F,
18879 n: function n() {
18880 if (i >= o.length) return {
18881 done: true
18882 };
18883 return {
18884 done: false,
18885 value: o[i++]
18886 };
18887 },
18888 e: function e(_e) {
18889 throw _e;
18890 },
18891 f: F
18892 };
18893 }
18894
18895 throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
18896 }
18897
18898 var normalCompletion = true,
18899 didErr = false,
18900 err;
18901 return {
18902 s: function s() {
18903 it = it.call(o);
18904 },
18905 n: function n() {
18906 var step = it.next();
18907 normalCompletion = step.done;
18908 return step;
18909 },
18910 e: function e(_e2) {
18911 didErr = true;
18912 err = _e2;
18913 },
18914 f: function f() {
18915 try {
18916 if (!normalCompletion && it["return"] != null) it["return"]();
18917 } finally {
18918 if (didErr) throw err;
18919 }
18920 }
18921 };
18922 }
18923
18924 module.exports = _createForOfIteratorHelper, module.exports.__esModule = true, module.exports["default"] = module.exports;
18925 });
18926
18927 var _createForOfIteratorHelper = /*@__PURE__*/getDefaultExportFromCjs(createForOfIteratorHelper);
18928
18929 function node_each (callback, that) {
18930 var index = -1;
18931
18932 var _iterator = _createForOfIteratorHelper(this),
18933 _step;
18934
18935 try {
18936 for (_iterator.s(); !(_step = _iterator.n()).done;) {
18937 var node = _step.value;
18938 callback.call(that, node, ++index, this);
18939 }
18940 } catch (err) {
18941 _iterator.e(err);
18942 } finally {
18943 _iterator.f();
18944 }
18945
18946 return this;
18947 }
18948
18949 function node_eachBefore (callback, that) {
18950 var node = this,
18951 nodes = [node],
18952 children,
18953 i,
18954 index = -1;
18955
18956 while (node = nodes.pop()) {
18957 callback.call(that, node, ++index, this);
18958
18959 if (children = node.children) {
18960 for (i = children.length - 1; i >= 0; --i) {
18961 nodes.push(children[i]);
18962 }
18963 }
18964 }
18965
18966 return this;
18967 }
18968
18969 function node_eachAfter (callback, that) {
18970 var node = this,
18971 nodes = [node],
18972 next = [],
18973 children,
18974 i,
18975 n,
18976 index = -1;
18977
18978 while (node = nodes.pop()) {
18979 next.push(node);
18980
18981 if (children = node.children) {
18982 for (i = 0, n = children.length; i < n; ++i) {
18983 nodes.push(children[i]);
18984 }
18985 }
18986 }
18987
18988 while (node = next.pop()) {
18989 callback.call(that, node, ++index, this);
18990 }
18991
18992 return this;
18993 }
18994
18995 function node_find (callback, that) {
18996 var index = -1;
18997
18998 var _iterator = _createForOfIteratorHelper(this),
18999 _step;
19000
19001 try {
19002 for (_iterator.s(); !(_step = _iterator.n()).done;) {
19003 var node = _step.value;
19004
19005 if (callback.call(that, node, ++index, this)) {
19006 return node;
19007 }
19008 }
19009 } catch (err) {
19010 _iterator.e(err);
19011 } finally {
19012 _iterator.f();
19013 }
19014 }
19015
19016 function node_sum (value) {
19017 return this.eachAfter(function (node) {
19018 var sum = +value(node.data) || 0,
19019 children = node.children,
19020 i = children && children.length;
19021
19022 while (--i >= 0) {
19023 sum += children[i].value;
19024 }
19025
19026 node.value = sum;
19027 });
19028 }
19029
19030 function node_sort (compare) {
19031 return this.eachBefore(function (node) {
19032 if (node.children) {
19033 node.children.sort(compare);
19034 }
19035 });
19036 }
19037
19038 function node_path (end) {
19039 var start = this,
19040 ancestor = leastCommonAncestor(start, end),
19041 nodes = [start];
19042
19043 while (start !== ancestor) {
19044 start = start.parent;
19045 nodes.push(start);
19046 }
19047
19048 var k = nodes.length;
19049
19050 while (end !== ancestor) {
19051 nodes.splice(k, 0, end);
19052 end = end.parent;
19053 }
19054
19055 return nodes;
19056 }
19057
19058 function leastCommonAncestor(a, b) {
19059 if (a === b) return a;
19060 var aNodes = a.ancestors(),
19061 bNodes = b.ancestors(),
19062 c = null;
19063 a = aNodes.pop();
19064 b = bNodes.pop();
19065
19066 while (a === b) {
19067 c = a;
19068 a = aNodes.pop();
19069 b = bNodes.pop();
19070 }
19071
19072 return c;
19073 }
19074
19075 function node_ancestors () {
19076 var node = this,
19077 nodes = [node];
19078
19079 while (node = node.parent) {
19080 nodes.push(node);
19081 }
19082
19083 return nodes;
19084 }
19085
19086 function node_descendants () {
19087 return Array.from(this);
19088 }
19089
19090 function node_leaves () {
19091 var leaves = [];
19092 this.eachBefore(function (node) {
19093 if (!node.children) {
19094 leaves.push(node);
19095 }
19096 });
19097 return leaves;
19098 }
19099
19100 function node_links () {
19101 var root = this,
19102 links = [];
19103 root.each(function (node) {
19104 if (node !== root) {
19105 // Don’t include the root’s parent, if any.
19106 links.push({
19107 source: node.parent,
19108 target: node
19109 });
19110 }
19111 });
19112 return links;
19113 }
19114
19115 var regeneratorRuntime$1 = createCommonjsModule(function (module) {
19116 var _typeof = _typeof_1["default"];
19117
19118 function _regeneratorRuntime() {
19119 /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */
19120
19121 module.exports = _regeneratorRuntime = function _regeneratorRuntime() {
19122 return exports;
19123 }, module.exports.__esModule = true, module.exports["default"] = module.exports;
19124 var exports = {},
19125 Op = Object.prototype,
19126 hasOwn = Op.hasOwnProperty,
19127 $Symbol = "function" == typeof Symbol ? Symbol : {},
19128 iteratorSymbol = $Symbol.iterator || "@@iterator",
19129 asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator",
19130 toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag";
19131
19132 function define(obj, key, value) {
19133 return Object.defineProperty(obj, key, {
19134 value: value,
19135 enumerable: !0,
19136 configurable: !0,
19137 writable: !0
19138 }), obj[key];
19139 }
19140
19141 try {
19142 define({}, "");
19143 } catch (err) {
19144 define = function define(obj, key, value) {
19145 return obj[key] = value;
19146 };
19147 }
19148
19149 function wrap(innerFn, outerFn, self, tryLocsList) {
19150 var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator,
19151 generator = Object.create(protoGenerator.prototype),
19152 context = new Context(tryLocsList || []);
19153 return generator._invoke = function (innerFn, self, context) {
19154 var state = "suspendedStart";
19155 return function (method, arg) {
19156 if ("executing" === state) throw new Error("Generator is already running");
19157
19158 if ("completed" === state) {
19159 if ("throw" === method) throw arg;
19160 return doneResult();
19161 }
19162
19163 for (context.method = method, context.arg = arg;;) {
19164 var delegate = context.delegate;
19165
19166 if (delegate) {
19167 var delegateResult = maybeInvokeDelegate(delegate, context);
19168
19169 if (delegateResult) {
19170 if (delegateResult === ContinueSentinel) continue;
19171 return delegateResult;
19172 }
19173 }
19174
19175 if ("next" === context.method) context.sent = context._sent = context.arg;else if ("throw" === context.method) {
19176 if ("suspendedStart" === state) throw state = "completed", context.arg;
19177 context.dispatchException(context.arg);
19178 } else "return" === context.method && context.abrupt("return", context.arg);
19179 state = "executing";
19180 var record = tryCatch(innerFn, self, context);
19181
19182 if ("normal" === record.type) {
19183 if (state = context.done ? "completed" : "suspendedYield", record.arg === ContinueSentinel) continue;
19184 return {
19185 value: record.arg,
19186 done: context.done
19187 };
19188 }
19189
19190 "throw" === record.type && (state = "completed", context.method = "throw", context.arg = record.arg);
19191 }
19192 };
19193 }(innerFn, self, context), generator;
19194 }
19195
19196 function tryCatch(fn, obj, arg) {
19197 try {
19198 return {
19199 type: "normal",
19200 arg: fn.call(obj, arg)
19201 };
19202 } catch (err) {
19203 return {
19204 type: "throw",
19205 arg: err
19206 };
19207 }
19208 }
19209
19210 exports.wrap = wrap;
19211 var ContinueSentinel = {};
19212
19213 function Generator() {}
19214
19215 function GeneratorFunction() {}
19216
19217 function GeneratorFunctionPrototype() {}
19218
19219 var IteratorPrototype = {};
19220 define(IteratorPrototype, iteratorSymbol, function () {
19221 return this;
19222 });
19223 var getProto = Object.getPrototypeOf,
19224 NativeIteratorPrototype = getProto && getProto(getProto(values([])));
19225 NativeIteratorPrototype && NativeIteratorPrototype !== Op && hasOwn.call(NativeIteratorPrototype, iteratorSymbol) && (IteratorPrototype = NativeIteratorPrototype);
19226 var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(IteratorPrototype);
19227
19228 function defineIteratorMethods(prototype) {
19229 ["next", "throw", "return"].forEach(function (method) {
19230 define(prototype, method, function (arg) {
19231 return this._invoke(method, arg);
19232 });
19233 });
19234 }
19235
19236 function AsyncIterator(generator, PromiseImpl) {
19237 function invoke(method, arg, resolve, reject) {
19238 var record = tryCatch(generator[method], generator, arg);
19239
19240 if ("throw" !== record.type) {
19241 var result = record.arg,
19242 value = result.value;
19243 return value && "object" == _typeof(value) && hasOwn.call(value, "__await") ? PromiseImpl.resolve(value.__await).then(function (value) {
19244 invoke("next", value, resolve, reject);
19245 }, function (err) {
19246 invoke("throw", err, resolve, reject);
19247 }) : PromiseImpl.resolve(value).then(function (unwrapped) {
19248 result.value = unwrapped, resolve(result);
19249 }, function (error) {
19250 return invoke("throw", error, resolve, reject);
19251 });
19252 }
19253
19254 reject(record.arg);
19255 }
19256
19257 var previousPromise;
19258
19259 this._invoke = function (method, arg) {
19260 function callInvokeWithMethodAndArg() {
19261 return new PromiseImpl(function (resolve, reject) {
19262 invoke(method, arg, resolve, reject);
19263 });
19264 }
19265
19266 return previousPromise = previousPromise ? previousPromise.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg();
19267 };
19268 }
19269
19270 function maybeInvokeDelegate(delegate, context) {
19271 var method = delegate.iterator[context.method];
19272
19273 if (undefined === method) {
19274 if (context.delegate = null, "throw" === context.method) {
19275 if (delegate.iterator["return"] && (context.method = "return", context.arg = undefined, maybeInvokeDelegate(delegate, context), "throw" === context.method)) return ContinueSentinel;
19276 context.method = "throw", context.arg = new TypeError("The iterator does not provide a 'throw' method");
19277 }
19278
19279 return ContinueSentinel;
19280 }
19281
19282 var record = tryCatch(method, delegate.iterator, context.arg);
19283 if ("throw" === record.type) return context.method = "throw", context.arg = record.arg, context.delegate = null, ContinueSentinel;
19284 var info = record.arg;
19285 return info ? info.done ? (context[delegate.resultName] = info.value, context.next = delegate.nextLoc, "return" !== context.method && (context.method = "next", context.arg = undefined), context.delegate = null, ContinueSentinel) : info : (context.method = "throw", context.arg = new TypeError("iterator result is not an object"), context.delegate = null, ContinueSentinel);
19286 }
19287
19288 function pushTryEntry(locs) {
19289 var entry = {
19290 tryLoc: locs[0]
19291 };
19292 1 in locs && (entry.catchLoc = locs[1]), 2 in locs && (entry.finallyLoc = locs[2], entry.afterLoc = locs[3]), this.tryEntries.push(entry);
19293 }
19294
19295 function resetTryEntry(entry) {
19296 var record = entry.completion || {};
19297 record.type = "normal", delete record.arg, entry.completion = record;
19298 }
19299
19300 function Context(tryLocsList) {
19301 this.tryEntries = [{
19302 tryLoc: "root"
19303 }], tryLocsList.forEach(pushTryEntry, this), this.reset(!0);
19304 }
19305
19306 function values(iterable) {
19307 if (iterable) {
19308 var iteratorMethod = iterable[iteratorSymbol];
19309 if (iteratorMethod) return iteratorMethod.call(iterable);
19310 if ("function" == typeof iterable.next) return iterable;
19311
19312 if (!isNaN(iterable.length)) {
19313 var i = -1,
19314 next = function next() {
19315 for (; ++i < iterable.length;) {
19316 if (hasOwn.call(iterable, i)) return next.value = iterable[i], next.done = !1, next;
19317 }
19318
19319 return next.value = undefined, next.done = !0, next;
19320 };
19321
19322 return next.next = next;
19323 }
19324 }
19325
19326 return {
19327 next: doneResult
19328 };
19329 }
19330
19331 function doneResult() {
19332 return {
19333 value: undefined,
19334 done: !0
19335 };
19336 }
19337
19338 return GeneratorFunction.prototype = GeneratorFunctionPrototype, define(Gp, "constructor", GeneratorFunctionPrototype), define(GeneratorFunctionPrototype, "constructor", GeneratorFunction), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, toStringTagSymbol, "GeneratorFunction"), exports.isGeneratorFunction = function (genFun) {
19339 var ctor = "function" == typeof genFun && genFun.constructor;
19340 return !!ctor && (ctor === GeneratorFunction || "GeneratorFunction" === (ctor.displayName || ctor.name));
19341 }, exports.mark = function (genFun) {
19342 return Object.setPrototypeOf ? Object.setPrototypeOf(genFun, GeneratorFunctionPrototype) : (genFun.__proto__ = GeneratorFunctionPrototype, define(genFun, toStringTagSymbol, "GeneratorFunction")), genFun.prototype = Object.create(Gp), genFun;
19343 }, exports.awrap = function (arg) {
19344 return {
19345 __await: arg
19346 };
19347 }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, asyncIteratorSymbol, function () {
19348 return this;
19349 }), exports.AsyncIterator = AsyncIterator, exports.async = function (innerFn, outerFn, self, tryLocsList, PromiseImpl) {
19350 void 0 === PromiseImpl && (PromiseImpl = Promise);
19351 var iter = new AsyncIterator(wrap(innerFn, outerFn, self, tryLocsList), PromiseImpl);
19352 return exports.isGeneratorFunction(outerFn) ? iter : iter.next().then(function (result) {
19353 return result.done ? result.value : iter.next();
19354 });
19355 }, defineIteratorMethods(Gp), define(Gp, toStringTagSymbol, "Generator"), define(Gp, iteratorSymbol, function () {
19356 return this;
19357 }), define(Gp, "toString", function () {
19358 return "[object Generator]";
19359 }), exports.keys = function (object) {
19360 var keys = [];
19361
19362 for (var key in object) {
19363 keys.push(key);
19364 }
19365
19366 return keys.reverse(), function next() {
19367 for (; keys.length;) {
19368 var key = keys.pop();
19369 if (key in object) return next.value = key, next.done = !1, next;
19370 }
19371
19372 return next.done = !0, next;
19373 };
19374 }, exports.values = values, Context.prototype = {
19375 constructor: Context,
19376 reset: function reset(skipTempReset) {
19377 if (this.prev = 0, this.next = 0, this.sent = this._sent = undefined, this.done = !1, this.delegate = null, this.method = "next", this.arg = undefined, this.tryEntries.forEach(resetTryEntry), !skipTempReset) for (var name in this) {
19378 "t" === name.charAt(0) && hasOwn.call(this, name) && !isNaN(+name.slice(1)) && (this[name] = undefined);
19379 }
19380 },
19381 stop: function stop() {
19382 this.done = !0;
19383 var rootRecord = this.tryEntries[0].completion;
19384 if ("throw" === rootRecord.type) throw rootRecord.arg;
19385 return this.rval;
19386 },
19387 dispatchException: function dispatchException(exception) {
19388 if (this.done) throw exception;
19389 var context = this;
19390
19391 function handle(loc, caught) {
19392 return record.type = "throw", record.arg = exception, context.next = loc, caught && (context.method = "next", context.arg = undefined), !!caught;
19393 }
19394
19395 for (var i = this.tryEntries.length - 1; i >= 0; --i) {
19396 var entry = this.tryEntries[i],
19397 record = entry.completion;
19398 if ("root" === entry.tryLoc) return handle("end");
19399
19400 if (entry.tryLoc <= this.prev) {
19401 var hasCatch = hasOwn.call(entry, "catchLoc"),
19402 hasFinally = hasOwn.call(entry, "finallyLoc");
19403
19404 if (hasCatch && hasFinally) {
19405 if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0);
19406 if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc);
19407 } else if (hasCatch) {
19408 if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0);
19409 } else {
19410 if (!hasFinally) throw new Error("try statement without catch or finally");
19411 if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc);
19412 }
19413 }
19414 }
19415 },
19416 abrupt: function abrupt(type, arg) {
19417 for (var i = this.tryEntries.length - 1; i >= 0; --i) {
19418 var entry = this.tryEntries[i];
19419
19420 if (entry.tryLoc <= this.prev && hasOwn.call(entry, "finallyLoc") && this.prev < entry.finallyLoc) {
19421 var finallyEntry = entry;
19422 break;
19423 }
19424 }
19425
19426 finallyEntry && ("break" === type || "continue" === type) && finallyEntry.tryLoc <= arg && arg <= finallyEntry.finallyLoc && (finallyEntry = null);
19427 var record = finallyEntry ? finallyEntry.completion : {};
19428 return record.type = type, record.arg = arg, finallyEntry ? (this.method = "next", this.next = finallyEntry.finallyLoc, ContinueSentinel) : this.complete(record);
19429 },
19430 complete: function complete(record, afterLoc) {
19431 if ("throw" === record.type) throw record.arg;
19432 return "break" === record.type || "continue" === record.type ? this.next = record.arg : "return" === record.type ? (this.rval = this.arg = record.arg, this.method = "return", this.next = "end") : "normal" === record.type && afterLoc && (this.next = afterLoc), ContinueSentinel;
19433 },
19434 finish: function finish(finallyLoc) {
19435 for (var i = this.tryEntries.length - 1; i >= 0; --i) {
19436 var entry = this.tryEntries[i];
19437 if (entry.finallyLoc === finallyLoc) return this.complete(entry.completion, entry.afterLoc), resetTryEntry(entry), ContinueSentinel;
19438 }
19439 },
19440 "catch": function _catch(tryLoc) {
19441 for (var i = this.tryEntries.length - 1; i >= 0; --i) {
19442 var entry = this.tryEntries[i];
19443
19444 if (entry.tryLoc === tryLoc) {
19445 var record = entry.completion;
19446
19447 if ("throw" === record.type) {
19448 var thrown = record.arg;
19449 resetTryEntry(entry);
19450 }
19451
19452 return thrown;
19453 }
19454 }
19455
19456 throw new Error("illegal catch attempt");
19457 },
19458 delegateYield: function delegateYield(iterable, resultName, nextLoc) {
19459 return this.delegate = {
19460 iterator: values(iterable),
19461 resultName: resultName,
19462 nextLoc: nextLoc
19463 }, "next" === this.method && (this.arg = undefined), ContinueSentinel;
19464 }
19465 }, exports;
19466 }
19467
19468 module.exports = _regeneratorRuntime, module.exports.__esModule = true, module.exports["default"] = module.exports;
19469 });
19470
19471 // TODO(Babel 8): Remove this file.
19472
19473 var runtime = regeneratorRuntime$1();
19474 var regenerator = runtime;
19475
19476 // Copied from https://github.com/facebook/regenerator/blob/main/packages/runtime/runtime.js#L736=
19477 try {
19478 regeneratorRuntime = runtime;
19479 } catch (accidentalStrictMode) {
19480 if (typeof globalThis === "object") {
19481 globalThis.regeneratorRuntime = runtime;
19482 } else {
19483 Function("r", "regeneratorRuntime = r")(runtime);
19484 }
19485 }
19486
19487 var _marked = /*#__PURE__*/regenerator.mark(_callee);
19488
19489 function _callee() {
19490 var node, current, next, children, i, n;
19491 return regenerator.wrap(function _callee$(_context) {
19492 while (1) {
19493 switch (_context.prev = _context.next) {
19494 case 0:
19495 node = this, next = [node];
19496
19497 case 1:
19498 current = next.reverse(), next = [];
19499
19500 case 2:
19501 if (!(node = current.pop())) {
19502 _context.next = 8;
19503 break;
19504 }
19505
19506 _context.next = 5;
19507 return node;
19508
19509 case 5:
19510 if (children = node.children) {
19511 for (i = 0, n = children.length; i < n; ++i) {
19512 next.push(children[i]);
19513 }
19514 }
19515
19516 _context.next = 2;
19517 break;
19518
19519 case 8:
19520 if (next.length) {
19521 _context.next = 1;
19522 break;
19523 }
19524
19525 case 9:
19526 case "end":
19527 return _context.stop();
19528 }
19529 }
19530 }, _marked, this);
19531 }
19532
19533 function hierarchy(data, children) {
19534 if (data instanceof Map) {
19535 data = [undefined, data];
19536 if (children === undefined) children = mapChildren;
19537 } else if (children === undefined) {
19538 children = objectChildren;
19539 }
19540
19541 var root = new Node(data),
19542 node,
19543 nodes = [root],
19544 child,
19545 childs,
19546 i,
19547 n;
19548
19549 while (node = nodes.pop()) {
19550 if ((childs = children(node.data)) && (n = (childs = Array.from(childs)).length)) {
19551 node.children = childs;
19552
19553 for (i = n - 1; i >= 0; --i) {
19554 nodes.push(child = childs[i] = new Node(childs[i]));
19555 child.parent = node;
19556 child.depth = node.depth + 1;
19557 }
19558 }
19559 }
19560
19561 return root.eachBefore(computeHeight);
19562 }
19563
19564 function node_copy() {
19565 return hierarchy(this).eachBefore(copyData);
19566 }
19567
19568 function objectChildren(d) {
19569 return d.children;
19570 }
19571
19572 function mapChildren(d) {
19573 return Array.isArray(d) ? d[1] : null;
19574 }
19575
19576 function copyData(node) {
19577 if (node.data.value !== undefined) node.value = node.data.value;
19578 node.data = node.data.data;
19579 }
19580
19581 function computeHeight(node) {
19582 var height = 0;
19583
19584 do {
19585 node.height = height;
19586 } while ((node = node.parent) && node.height < ++height);
19587 }
19588 function Node(data) {
19589 this.data = data;
19590 this.depth = this.height = 0;
19591 this.parent = null;
19592 }
19593 Node.prototype = hierarchy.prototype = _defineProperty({
19594 constructor: Node,
19595 count: node_count,
19596 each: node_each,
19597 eachAfter: node_eachAfter,
19598 eachBefore: node_eachBefore,
19599 find: node_find,
19600 sum: node_sum,
19601 sort: node_sort,
19602 path: node_path,
19603 ancestors: node_ancestors,
19604 descendants: node_descendants,
19605 leaves: node_leaves,
19606 links: node_links,
19607 copy: node_copy
19608 }, Symbol.iterator, _callee);
19609
19610 function required(f) {
19611 if (typeof f !== "function") throw new Error();
19612 return f;
19613 }
19614
19615 function constantZero() {
19616 return 0;
19617 }
19618 function constant$1 (x) {
19619 return function () {
19620 return x;
19621 };
19622 }
19623
19624 function roundNode (node) {
19625 node.x0 = Math.round(node.x0);
19626 node.y0 = Math.round(node.y0);
19627 node.x1 = Math.round(node.x1);
19628 node.y1 = Math.round(node.y1);
19629 }
19630
19631 function treemapDice (parent, x0, y0, x1, y1) {
19632 var nodes = parent.children,
19633 node,
19634 i = -1,
19635 n = nodes.length,
19636 k = parent.value && (x1 - x0) / parent.value;
19637
19638 while (++i < n) {
19639 node = nodes[i], node.y0 = y0, node.y1 = y1;
19640 node.x0 = x0, node.x1 = x0 += node.value * k;
19641 }
19642 }
19643
19644 function partition () {
19645 var dx = 1,
19646 dy = 1,
19647 padding = 0,
19648 round = false;
19649
19650 function partition(root) {
19651 var n = root.height + 1;
19652 root.x0 = root.y0 = padding;
19653 root.x1 = dx;
19654 root.y1 = dy / n;
19655 root.eachBefore(positionNode(dy, n));
19656 if (round) root.eachBefore(roundNode);
19657 return root;
19658 }
19659
19660 function positionNode(dy, n) {
19661 return function (node) {
19662 if (node.children) {
19663 treemapDice(node, node.x0, dy * (node.depth + 1) / n, node.x1, dy * (node.depth + 2) / n);
19664 }
19665
19666 var x0 = node.x0,
19667 y0 = node.y0,
19668 x1 = node.x1 - padding,
19669 y1 = node.y1 - padding;
19670 if (x1 < x0) x0 = x1 = (x0 + x1) / 2;
19671 if (y1 < y0) y0 = y1 = (y0 + y1) / 2;
19672 node.x0 = x0;
19673 node.y0 = y0;
19674 node.x1 = x1;
19675 node.y1 = y1;
19676 };
19677 }
19678
19679 partition.round = function (x) {
19680 return arguments.length ? (round = !!x, partition) : round;
19681 };
19682
19683 partition.size = function (x) {
19684 return arguments.length ? (dx = +x[0], dy = +x[1], partition) : [dx, dy];
19685 };
19686
19687 partition.padding = function (x) {
19688 return arguments.length ? (padding = +x, partition) : padding;
19689 };
19690
19691 return partition;
19692 }
19693
19694 function treemapSlice (parent, x0, y0, x1, y1) {
19695 var nodes = parent.children,
19696 node,
19697 i = -1,
19698 n = nodes.length,
19699 k = parent.value && (y1 - y0) / parent.value;
19700
19701 while (++i < n) {
19702 node = nodes[i], node.x0 = x0, node.x1 = x1;
19703 node.y0 = y0, node.y1 = y0 += node.value * k;
19704 }
19705 }
19706
19707 var phi = (1 + Math.sqrt(5)) / 2;
19708 function squarifyRatio(ratio, parent, x0, y0, x1, y1) {
19709 var rows = [],
19710 nodes = parent.children,
19711 row,
19712 nodeValue,
19713 i0 = 0,
19714 i1 = 0,
19715 n = nodes.length,
19716 dx,
19717 dy,
19718 value = parent.value,
19719 sumValue,
19720 minValue,
19721 maxValue,
19722 newRatio,
19723 minRatio,
19724 alpha,
19725 beta;
19726
19727 while (i0 < n) {
19728 dx = x1 - x0, dy = y1 - y0; // Find the next non-empty node.
19729
19730 do {
19731 sumValue = nodes[i1++].value;
19732 } while (!sumValue && i1 < n);
19733
19734 minValue = maxValue = sumValue;
19735 alpha = Math.max(dy / dx, dx / dy) / (value * ratio);
19736 beta = sumValue * sumValue * alpha;
19737 minRatio = Math.max(maxValue / beta, beta / minValue); // Keep adding nodes while the aspect ratio maintains or improves.
19738
19739 for (; i1 < n; ++i1) {
19740 sumValue += nodeValue = nodes[i1].value;
19741 if (nodeValue < minValue) minValue = nodeValue;
19742 if (nodeValue > maxValue) maxValue = nodeValue;
19743 beta = sumValue * sumValue * alpha;
19744 newRatio = Math.max(maxValue / beta, beta / minValue);
19745
19746 if (newRatio > minRatio) {
19747 sumValue -= nodeValue;
19748 break;
19749 }
19750
19751 minRatio = newRatio;
19752 } // Position and record the row orientation.
19753
19754
19755 rows.push(row = {
19756 value: sumValue,
19757 dice: dx < dy,
19758 children: nodes.slice(i0, i1)
19759 });
19760 if (row.dice) treemapDice(row, x0, y0, x1, value ? y0 += dy * sumValue / value : y1);else treemapSlice(row, x0, y0, value ? x0 += dx * sumValue / value : x1, y1);
19761 value -= sumValue, i0 = i1;
19762 }
19763
19764 return rows;
19765 }
19766 var squarify = (function custom(ratio) {
19767 function squarify(parent, x0, y0, x1, y1) {
19768 squarifyRatio(ratio, parent, x0, y0, x1, y1);
19769 }
19770
19771 squarify.ratio = function (x) {
19772 return custom((x = +x) > 1 ? x : 1);
19773 };
19774
19775 return squarify;
19776 })(phi);
19777
19778 function treemap () {
19779 var tile = squarify,
19780 round = false,
19781 dx = 1,
19782 dy = 1,
19783 paddingStack = [0],
19784 paddingInner = constantZero,
19785 paddingTop = constantZero,
19786 paddingRight = constantZero,
19787 paddingBottom = constantZero,
19788 paddingLeft = constantZero;
19789
19790 function treemap(root) {
19791 root.x0 = root.y0 = 0;
19792 root.x1 = dx;
19793 root.y1 = dy;
19794 root.eachBefore(positionNode);
19795 paddingStack = [0];
19796 if (round) root.eachBefore(roundNode);
19797 return root;
19798 }
19799
19800 function positionNode(node) {
19801 var p = paddingStack[node.depth],
19802 x0 = node.x0 + p,
19803 y0 = node.y0 + p,
19804 x1 = node.x1 - p,
19805 y1 = node.y1 - p;
19806 if (x1 < x0) x0 = x1 = (x0 + x1) / 2;
19807 if (y1 < y0) y0 = y1 = (y0 + y1) / 2;
19808 node.x0 = x0;
19809 node.y0 = y0;
19810 node.x1 = x1;
19811 node.y1 = y1;
19812
19813 if (node.children) {
19814 p = paddingStack[node.depth + 1] = paddingInner(node) / 2;
19815 x0 += paddingLeft(node) - p;
19816 y0 += paddingTop(node) - p;
19817 x1 -= paddingRight(node) - p;
19818 y1 -= paddingBottom(node) - p;
19819 if (x1 < x0) x0 = x1 = (x0 + x1) / 2;
19820 if (y1 < y0) y0 = y1 = (y0 + y1) / 2;
19821 tile(node, x0, y0, x1, y1);
19822 }
19823 }
19824
19825 treemap.round = function (x) {
19826 return arguments.length ? (round = !!x, treemap) : round;
19827 };
19828
19829 treemap.size = function (x) {
19830 return arguments.length ? (dx = +x[0], dy = +x[1], treemap) : [dx, dy];
19831 };
19832
19833 treemap.tile = function (x) {
19834 return arguments.length ? (tile = required(x), treemap) : tile;
19835 };
19836
19837 treemap.padding = function (x) {
19838 return arguments.length ? treemap.paddingInner(x).paddingOuter(x) : treemap.paddingInner();
19839 };
19840
19841 treemap.paddingInner = function (x) {
19842 return arguments.length ? (paddingInner = typeof x === "function" ? x : constant$1(+x), treemap) : paddingInner;
19843 };
19844
19845 treemap.paddingOuter = function (x) {
19846 return arguments.length ? treemap.paddingTop(x).paddingRight(x).paddingBottom(x).paddingLeft(x) : treemap.paddingTop();
19847 };
19848
19849 treemap.paddingTop = function (x) {
19850 return arguments.length ? (paddingTop = typeof x === "function" ? x : constant$1(+x), treemap) : paddingTop;
19851 };
19852
19853 treemap.paddingRight = function (x) {
19854 return arguments.length ? (paddingRight = typeof x === "function" ? x : constant$1(+x), treemap) : paddingRight;
19855 };
19856
19857 treemap.paddingBottom = function (x) {
19858 return arguments.length ? (paddingBottom = typeof x === "function" ? x : constant$1(+x), treemap) : paddingBottom;
19859 };
19860
19861 treemap.paddingLeft = function (x) {
19862 return arguments.length ? (paddingLeft = typeof x === "function" ? x : constant$1(+x), treemap) : paddingLeft;
19863 };
19864
19865 return treemap;
19866 }
19867
19868 function treemapBinary (parent, x0, y0, x1, y1) {
19869 var nodes = parent.children,
19870 i,
19871 n = nodes.length,
19872 sum,
19873 sums = new Array(n + 1);
19874
19875 for (sums[0] = sum = i = 0; i < n; ++i) {
19876 sums[i + 1] = sum += nodes[i].value;
19877 }
19878
19879 partition(0, n, parent.value, x0, y0, x1, y1);
19880
19881 function partition(i, j, value, x0, y0, x1, y1) {
19882 if (i >= j - 1) {
19883 var node = nodes[i];
19884 node.x0 = x0, node.y0 = y0;
19885 node.x1 = x1, node.y1 = y1;
19886 return;
19887 }
19888
19889 var valueOffset = sums[i],
19890 valueTarget = value / 2 + valueOffset,
19891 k = i + 1,
19892 hi = j - 1;
19893
19894 while (k < hi) {
19895 var mid = k + hi >>> 1;
19896 if (sums[mid] < valueTarget) k = mid + 1;else hi = mid;
19897 }
19898
19899 if (valueTarget - sums[k - 1] < sums[k] - valueTarget && i + 1 < k) --k;
19900 var valueLeft = sums[k] - valueOffset,
19901 valueRight = value - valueLeft;
19902
19903 if (x1 - x0 > y1 - y0) {
19904 var xk = value ? (x0 * valueRight + x1 * valueLeft) / value : x1;
19905 partition(i, k, valueLeft, x0, y0, xk, y1);
19906 partition(k, j, valueRight, xk, y0, x1, y1);
19907 } else {
19908 var yk = value ? (y0 * valueRight + y1 * valueLeft) / value : y1;
19909 partition(i, k, valueLeft, x0, y0, x1, yk);
19910 partition(k, j, valueRight, x0, yk, x1, y1);
19911 }
19912 }
19913 }
19914
19915 var withTreemap = (function (View) {
19916 return /*#__PURE__*/function (_Component) {
19917 _inherits(Treemap, _Component);
19918
19919 var _super = _createSuper(Treemap);
19920
19921 function Treemap(props, context, updater) {
19922 var _this;
19923
19924 _classCallCheck(this, Treemap);
19925
19926 _this = _super.call(this, props, context, updater);
19927 var coord = props.coord,
19928 color = props.color,
19929 data = props.data;
19930 var width = context.width,
19931 height = context.height,
19932 theme = context.theme;
19933 _this.coordController = new coordController();
19934
19935 var _assertThisInitialize = _assertThisInitialized(_this),
19936 coordController$1 = _assertThisInitialize.coordController;
19937
19938 _this.coord = coordController$1.create(coord, {
19939 width: width,
19940 height: height
19941 });
19942 _this.color = new Category$1(_objectSpread(_objectSpread({
19943 range: theme.colors
19944 }, color), {}, {
19945 data: data
19946 }));
19947 return _this;
19948 }
19949
19950 _createClass(Treemap, [{
19951 key: "treemapLayout",
19952 value: function treemapLayout() {
19953 var props = this.props,
19954 coord = this.coord,
19955 colorAttr = this.color;
19956 var data = props.data,
19957 value = props.value;
19958 var root = hierarchy({
19959 children: data
19960 }).sum(function (d) {
19961 return d[value];
19962 }).sort(function (a, b) {
19963 return b[value] - a[value];
19964 });
19965 var treemapLayout = treemap() // 默认treemapSquarify
19966 .tile(treemapBinary) // .size([1, 1])
19967 // @ts-ignore
19968 .round(false); // .padding(space)
19969 // .paddingInner(space);
19970 // .paddingOuter(options.paddingOuter)
19971 // .paddingTop(options.paddingTop)
19972 // .paddingRight(options.paddingRight)
19973 // .paddingBottom(options.paddingBottom)
19974 // .paddingLeft(options.paddingLeft);
19975
19976 var nodes = treemapLayout(root);
19977 return nodes.children.map(function (item) {
19978 var data = item.data,
19979 x0 = item.x0,
19980 y0 = item.y0,
19981 x1 = item.x1,
19982 y1 = item.y1;
19983 var color = colorAttr.mapping(data[colorAttr.field]);
19984 var rect = coord.convertRect({
19985 x: [x0, x1],
19986 y: [y0, y1]
19987 });
19988 return _objectSpread({
19989 key: data.key,
19990 origin: data,
19991 color: color
19992 }, rect);
19993 });
19994 }
19995 }, {
19996 key: "render",
19997 value: function render() {
19998 var nodes = this.treemapLayout();
19999 var props = this.props,
20000 coord = this.coord;
20001 return jsx(View, _objectSpread(_objectSpread({
20002 nodes: nodes
20003 }, props), {}, {
20004 coord: coord
20005 }));
20006 }
20007 }]);
20008
20009 return Treemap;
20010 }(Component);
20011 });
20012
20013 var TreemapView = (function (props) {
20014 var nodes = props.nodes,
20015 coord = props.coord;
20016
20017 if (coord.isPolar) {
20018 var center = coord.center;
20019 var x = center.x,
20020 y = center.y;
20021 return jsx("group", null, nodes.map(function (node) {
20022 var xMin = node.xMin,
20023 xMax = node.xMax,
20024 yMin = node.yMin,
20025 yMax = node.yMax,
20026 color = node.color;
20027 return jsx("sector", {
20028 attrs: {
20029 x: x,
20030 y: y,
20031 lineWidth: '1px',
20032 stroke: '#fff',
20033 startAngle: xMin,
20034 endAngle: xMax,
20035 r0: yMin,
20036 r: yMax,
20037 anticlockwise: false,
20038 fill: color
20039 }
20040 });
20041 }));
20042 }
20043
20044 return jsx("group", null, nodes.map(function (node) {
20045 var key = node.key,
20046 xMin = node.xMin,
20047 xMax = node.xMax,
20048 yMin = node.yMin,
20049 yMax = node.yMax,
20050 color = node.color;
20051 return jsx("rect", {
20052 key: key,
20053 attrs: {
20054 x: xMin,
20055 y: yMin,
20056 width: xMax - xMin,
20057 height: yMax - yMin,
20058 fill: color,
20059 lineWidth: '4px',
20060 stroke: '#fff',
20061 radius: '8px'
20062 },
20063 animation: {
20064 appear: {
20065 easing: 'linear',
20066 duration: 450,
20067 property: ['fillOpacity', 'strokeOpacity'],
20068 start: {
20069 fillOpacity: 0,
20070 strokeOpacity: 0
20071 },
20072 end: {
20073 fillOpacity: 1,
20074 strokeOpacity: 1
20075 }
20076 },
20077 update: {
20078 easing: 'linear',
20079 duration: 450,
20080 property: ['x', 'y', 'width', 'height', 'radius', 'lineWidth']
20081 }
20082 }
20083 });
20084 }));
20085 });
20086
20087 var index$8 = withTreemap(TreemapView);
20088
20089 function rootParent(data) {
20090 var d = data;
20091
20092 while (d.depth > 1) {
20093 d = d.parent;
20094 }
20095
20096 return d;
20097 }
20098
20099 var withSunburst = (function (View) {
20100 return /*#__PURE__*/function (_Component) {
20101 _inherits(Sunburst, _Component);
20102
20103 var _super = _createSuper(Sunburst);
20104
20105 function Sunburst(props, context) {
20106 var _this;
20107
20108 _classCallCheck(this, Sunburst);
20109
20110 _this = _super.call(this, props, context);
20111 var coord = props.coord,
20112 color = props.color,
20113 data = props.data;
20114 var width = context.width,
20115 height = context.height,
20116 theme = context.theme;
20117 _this.coordController = new coordController();
20118
20119 var _assertThisInitialize = _assertThisInitialized(_this),
20120 coordController$1 = _assertThisInitialize.coordController;
20121
20122 _this.coord = coordController$1.create(coord, {
20123 width: width,
20124 height: height
20125 });
20126 _this.color = new Category$1(_objectSpread(_objectSpread({
20127 range: theme.colors
20128 }, color), {}, {
20129 data: data
20130 }));
20131 return _this;
20132 }
20133
20134 _createClass(Sunburst, [{
20135 key: "didMount",
20136 value: function didMount() {
20137 var _this2 = this;
20138
20139 var props = this.props,
20140 container = this.container;
20141 var onClick = props.onClick;
20142 var canvas = container.get('canvas');
20143 this.triggerRef = [];
20144 canvas.on('click', function (ev) {
20145 var points = ev.points;
20146
20147 var shape = _this2.triggerRef.find(function (ref) {
20148 return isInBBox(ref.current.getBBox(), points[0]);
20149 });
20150
20151 if (shape) {
20152 ev.shape = shape; // @ts-ignore
20153
20154 ev.payload = shape.payload;
20155 onClick && onClick(ev);
20156 }
20157 });
20158 }
20159 }, {
20160 key: "_mapping",
20161 value: function _mapping(children) {
20162 var colorAttr = this.color,
20163 coord = this.coord;
20164
20165 for (var i = 0, len = children.length; i < len; i++) {
20166 var node = children[i];
20167 var root = rootParent(node);
20168 var color = colorAttr.mapping(root.data[colorAttr.field]);
20169 node.color = color;
20170 var x0 = node.x0,
20171 x1 = node.x1,
20172 y0 = node.y0,
20173 y1 = node.y1;
20174 var rect = coord.convertRect({
20175 x: [x0, x1],
20176 y: [y0, y1]
20177 });
20178 mix(node, rect); // 递归处理
20179
20180 if (node.children && node.children.length) {
20181 this._mapping(node.children);
20182 }
20183 }
20184 }
20185 }, {
20186 key: "sunburst",
20187 value: function sunburst() {
20188 var props = this.props;
20189 var data = props.data,
20190 value = props.value,
20191 _props$sort = props.sort,
20192 sort = _props$sort === void 0 ? true : _props$sort;
20193 var root = hierarchy({
20194 children: data
20195 }).sum(function (d) {
20196 return d[value];
20197 }); // 内置按value大小顺序排序,支持传入sort函数
20198
20199 if (sort === true || isFunction(sort)) {
20200 var sortFn = isFunction(sort) ? sort : function (a, b) {
20201 return b[value] - a[value];
20202 };
20203 root.sort(sortFn);
20204 }
20205
20206 var nodes = partition()(root);
20207 var children = nodes.children;
20208
20209 this._mapping(children);
20210
20211 return nodes;
20212 }
20213 }, {
20214 key: "render",
20215 value: function render() {
20216 var node = this.sunburst();
20217 var coord = this.coord,
20218 props = this.props;
20219 return jsx(View, _objectSpread(_objectSpread({}, props), {}, {
20220 coord: coord,
20221 node: node,
20222 triggerRef: this.triggerRef
20223 }));
20224 }
20225 }]);
20226
20227 return Sunburst;
20228 }(Component);
20229 });
20230
20231 var SunburstView = (function (props) {
20232 var coord = props.coord,
20233 node = props.node;
20234 var children = node.children;
20235 var _coord$center = coord.center,
20236 x = _coord$center.x,
20237 y = _coord$center.y;
20238
20239 var renderNodes = function renderNodes(nodes) {
20240 return jsx("group", null, nodes.map(function (node) {
20241 var xMin = node.xMin,
20242 xMax = node.xMax,
20243 yMin = node.yMin,
20244 yMax = node.yMax,
20245 color = node.color,
20246 children = node.children;
20247 return jsx("group", null, jsx("sector", {
20248 attrs: {
20249 x: x,
20250 y: y,
20251 lineWidth: '1px',
20252 stroke: '#fff',
20253 startAngle: xMin,
20254 endAngle: xMax,
20255 r0: yMin,
20256 r: yMax,
20257 anticlockwise: false,
20258 fill: color
20259 }
20260 }), children && children.length ? renderNodes(children) : null);
20261 }));
20262 };
20263
20264 return renderNodes(children);
20265 });
20266
20267 var IcicleView = (function (props) {
20268 var node = props.node;
20269 var children = node.children;
20270
20271 var renderNodes = function renderNodes(nodes) {
20272 return jsx("group", null, nodes.map(function (node) {
20273 var xMin = node.xMin,
20274 xMax = node.xMax,
20275 yMin = node.yMin,
20276 yMax = node.yMax,
20277 color = node.color,
20278 children = node.children;
20279 return jsx("group", null, jsx("rect", {
20280 attrs: {
20281 x: xMin,
20282 y: yMin,
20283 width: xMax - xMin,
20284 height: yMax - yMin,
20285 lineWidth: '1px',
20286 stroke: '#fff',
20287 fill: color
20288 }
20289 }), children && children.length ? renderNodes(children) : null);
20290 }));
20291 };
20292
20293 return renderNodes(children);
20294 });
20295
20296 var View = (function (props) {
20297 var coord = props.coord;
20298
20299 if (coord.type === 'polar') {
20300 return jsx(SunburstView, _objectSpread({}, props));
20301 }
20302
20303 return jsx(IcicleView, _objectSpread({}, props));
20304 });
20305
20306 var index$9 = withSunburst(View);
20307
20308 var DEFAULT_CONFIG = {
20309 anchorOffset: '10px',
20310 inflectionOffset: '30px',
20311 sidePadding: '15px',
20312 height: '64px',
20313 adjustOffset: '30',
20314 triggerOn: 'click',
20315 // activeShape: false, // 当有图形被选中的时候,是否激活图形
20316 // activeStyle: {
20317 // offset: '1px',
20318 // appendRadius: '8px',
20319 // fillOpacity: 0.5,
20320 // },
20321 label1OffsetY: '-4px',
20322 label2OffsetY: '4px'
20323 };
20324
20325 function getEndPoint(center, angle, r) {
20326 return {
20327 x: center.x + r * Math.cos(angle),
20328 y: center.y + r * Math.sin(angle)
20329 };
20330 } // 计算中间角度
20331
20332
20333 function getMiddleAngle(startAngle, endAngle) {
20334 if (endAngle < startAngle) {
20335 endAngle += Math.PI * 2;
20336 }
20337
20338 return (endAngle + startAngle) / 2;
20339 }
20340
20341 function move(from, to, count, center) {
20342 var x = center.x;
20343 var sort = from.sort(function (a, b) {
20344 var aDistance = Math.abs(a.x - x);
20345 var bDistance = Math.abs(b.x - x);
20346 return bDistance - aDistance;
20347 });
20348 return [sort.slice(0, sort.length - count), sort.slice(sort.length - count).concat(to)];
20349 } // 第一象限
20350
20351
20352 function isFirstQuadrant(angle) {
20353 return angle >= -Math.PI / 2 && angle < 0;
20354 } // 第二象限
20355
20356
20357 function isSecondQuadrant(angle) {
20358 return angle >= 0 && angle < Math.PI / 2;
20359 }
20360
20361 function isThirdQuadrant(angle) {
20362 return angle >= Math.PI / 2 && angle < Math.PI;
20363 }
20364
20365 function isFourthQuadrant(angle) {
20366 return angle >= Math.PI && angle < Math.PI * 3 / 2;
20367 }
20368
20369 function findShapeByClassName(shape, point, className) {
20370 var targetShapes = getElementsByClassName(className, shape);
20371
20372 for (var i = 0, len = targetShapes.length; i < len; i++) {
20373 var _shape = targetShapes[i];
20374
20375 if (isInBBox(_shape.getBBox(), point)) {
20376 return _shape;
20377 }
20378 }
20379 }
20380
20381 var withPieLabel = (function (View) {
20382 return /*#__PURE__*/function (_Component) {
20383 _inherits(PieLabel, _Component);
20384
20385 var _super = _createSuper(PieLabel);
20386
20387 function PieLabel(props) {
20388 var _this;
20389
20390 _classCallCheck(this, PieLabel);
20391
20392 _this = _super.call(this, props);
20393
20394 _this._handleEvent = function (ev) {
20395 var _this$props = _this.props,
20396 chart = _this$props.chart,
20397 onClick = _this$props.onClick;
20398 var ele = _this.triggerRef.current;
20399 var point = ev.points[0];
20400 var shape = findShapeByClassName(ele, point, 'click');
20401 var pieData = chart.getSnapRecords(point);
20402
20403 if (typeof onClick === 'function') {
20404 // 点击label
20405 if (shape) {
20406 onClick(shape.get('data'));
20407 } // 点击饼图
20408 else if (isArray(pieData) && pieData.length > 0) {
20409 onClick(pieData);
20410 }
20411 }
20412 };
20413
20414 _this.triggerRef = {};
20415 return _this;
20416 }
20417
20418 _createClass(PieLabel, [{
20419 key: "willMount",
20420 value: function willMount() {}
20421 /**
20422 * 绑定事件
20423 */
20424
20425 }, {
20426 key: "didMount",
20427 value: function didMount() {
20428 this._initEvent();
20429 }
20430 }, {
20431 key: "getLabels",
20432 value: function getLabels(props) {
20433 var chart = props.chart,
20434 coord = props.coord,
20435 anchorOffset = props.anchorOffset,
20436 inflectionOffset = props.inflectionOffset,
20437 label1 = props.label1,
20438 label2 = props.label2,
20439 itemHeight = props.height,
20440 sidePadding = props.sidePadding;
20441 var center = coord.center,
20442 radius = coord.radius,
20443 coordWidth = coord.width,
20444 coordHeight = coord.height,
20445 coordLeft = coord.left,
20446 coordRight = coord.right,
20447 coordTop = coord.top;
20448 var maxCountForOneSide = Math.floor(coordHeight / itemHeight);
20449 var maxCount = maxCountForOneSide * 2;
20450 var geometry = chart.getGeometrys()[0];
20451 var records = geometry.flatRecords() // 按角度大到小排序
20452 .sort(function (a, b) {
20453 var angle1 = a.xMax - a.xMin;
20454 var angle2 = b.xMax - b.xMin;
20455 return angle2 - angle1;
20456 }) // 只取前 maxCount 个显示
20457 .slice(0, maxCount); // 存储左右 labels
20458
20459 var halves = [[], [] // right
20460 ];
20461 records.forEach(function (record) {
20462 var xMin = record.xMin,
20463 xMax = record.xMax,
20464 color = record.color,
20465 origin = record.origin; // 锚点角度
20466
20467 var anchorAngle = getMiddleAngle(xMin, xMax); // 锚点坐标
20468
20469 var anchorPoint = getEndPoint(center, anchorAngle, radius + anchorOffset); // 拐点坐标
20470
20471 var inflectionPoint = getEndPoint(center, anchorAngle, radius + inflectionOffset); // 锚点方向
20472
20473 var side = anchorPoint.x < center.x ? 'left' : 'right';
20474 var label = {
20475 origin: origin,
20476 angle: anchorAngle,
20477 anchor: anchorPoint,
20478 inflection: inflectionPoint,
20479 side: side,
20480 x: inflectionPoint.x,
20481 y: inflectionPoint.y,
20482 r: radius + inflectionOffset,
20483 color: color,
20484 label1: isFunction(label1) ? label1(origin, record) : label1,
20485 label2: isFunction(label2) ? label2(origin, record) : label2
20486 }; // 判断文本的方向
20487
20488 if (side === 'left') {
20489 halves[0].push(label);
20490 } else {
20491 halves[1].push(label);
20492 }
20493 }); // 判断是有一边超过了显示的最大
20494
20495 if (halves[0].length > maxCountForOneSide) {
20496 halves = move(halves[0], halves[1], halves[0].length - maxCountForOneSide, center);
20497 } else if (halves[1].length > maxCountForOneSide) {
20498 var _move = move(halves[1], halves[0], halves[1].length - maxCountForOneSide, center),
20499 _move2 = _slicedToArray(_move, 2),
20500 right = _move2[0],
20501 left = _move2[1];
20502
20503 halves = [left, right];
20504 } // label 的最大宽度
20505
20506
20507 var labelWidth = coordWidth / 2 - radius - anchorOffset - inflectionOffset - 2 * sidePadding;
20508 var labels = [];
20509 halves.forEach(function (half, index) {
20510 var showSide = index === 0 ? 'left' : 'right'; // 顺时针方向排序
20511
20512 half.sort(function (a, b) {
20513 var aAngle = a.angle;
20514 var bAngle = b.angle;
20515
20516 if (showSide === 'left') {
20517 // 是否在第一象限
20518 aAngle = isFirstQuadrant(aAngle) ? aAngle + Math.PI * 2 : aAngle;
20519 bAngle = isFirstQuadrant(bAngle) ? bAngle + Math.PI * 2 : bAngle;
20520 return bAngle - aAngle;
20521 } else {
20522 // 是否在第四象限
20523 aAngle = isFourthQuadrant(aAngle) ? aAngle - Math.PI * 2 : aAngle;
20524 bAngle = isFourthQuadrant(bAngle) ? bAngle - Math.PI * 2 : bAngle;
20525 return aAngle - bAngle;
20526 }
20527 });
20528 var pointsY = half.map(function (label) {
20529 return label.y;
20530 });
20531 var maxY = Math.max.apply(null, pointsY);
20532 var minY = Math.min.apply(null, pointsY); // 每个 label 占用的高度
20533
20534 var labelCount = half.length;
20535 var labelHeight = coordHeight / labelCount;
20536 var halfLabelHeight = labelHeight / 2; // 线之间的间隔
20537
20538 var lineInterval = 2;
20539
20540 if (showSide === 'left') {
20541 half.forEach(function (label, index) {
20542 var anchor = label.anchor,
20543 inflection = label.inflection,
20544 angle = label.angle,
20545 x = label.x,
20546 y = label.y;
20547 var points = [anchor, inflection];
20548 var endX = coordLeft + sidePadding;
20549 var endY = coordTop + halfLabelHeight + labelHeight * index; // 文本开始点
20550
20551 var labelStart = {
20552 x: endX + labelWidth + lineInterval * index,
20553 y: endY
20554 }; // 文本结束点
20555
20556 var labelEnd = {
20557 x: endX,
20558 y: endY
20559 }; // 第四象限
20560
20561 if (isFirstQuadrant(angle)) {
20562 var pointY = minY - lineInterval * (labelCount - index);
20563 points.push({
20564 x: x,
20565 y: pointY
20566 });
20567 points.push({
20568 x: labelStart.x,
20569 y: pointY
20570 });
20571 } else if (isThirdQuadrant(angle) || isFourthQuadrant(angle)) {
20572 points.push({
20573 x: labelStart.x,
20574 y: y
20575 });
20576 } else if (isSecondQuadrant(angle)) {
20577 var _pointY = maxY + lineInterval * index;
20578
20579 points.push({
20580 x: x,
20581 y: _pointY
20582 });
20583 points.push({
20584 x: labelStart.x,
20585 y: _pointY
20586 });
20587 }
20588
20589 points.push(labelStart);
20590 points.push(labelEnd);
20591 label.points = points;
20592 label.side = showSide;
20593 labels.push(label);
20594 });
20595 } else {
20596 half.forEach(function (label, index) {
20597 var anchor = label.anchor,
20598 inflection = label.inflection,
20599 angle = label.angle,
20600 x = label.x,
20601 y = label.y; // 折线的点
20602
20603 var points = [anchor, inflection];
20604 var endX = coordRight - sidePadding;
20605 var endY = coordTop + halfLabelHeight + labelHeight * index; // 文本开始点
20606
20607 var labelStart = {
20608 x: endX - labelWidth - lineInterval * index,
20609 y: endY
20610 }; // 文本结束点
20611
20612 var labelEnd = {
20613 x: endX,
20614 y: endY
20615 }; // 第四象限
20616
20617 if (isFourthQuadrant(angle)) {
20618 var pointY = minY - lineInterval * (labelCount - index);
20619 points.push({
20620 x: x,
20621 y: pointY
20622 });
20623 points.push({
20624 x: labelStart.x,
20625 y: pointY
20626 });
20627 } else if (isFirstQuadrant(angle) || isSecondQuadrant(angle)) {
20628 points.push({
20629 x: labelStart.x,
20630 y: y
20631 });
20632 } else if (isThirdQuadrant(angle)) {
20633 var _pointY2 = maxY + lineInterval * index;
20634
20635 points.push({
20636 x: x,
20637 y: _pointY2
20638 });
20639 points.push({
20640 x: labelStart.x,
20641 y: _pointY2
20642 });
20643 }
20644
20645 points.push(labelStart);
20646 points.push(labelEnd);
20647 label.points = points;
20648 label.side = showSide;
20649 labels.push(label);
20650 });
20651 }
20652 });
20653 return labels;
20654 }
20655 }, {
20656 key: "_initEvent",
20657 value: function _initEvent() {
20658 var context = this.context,
20659 props = this.props;
20660 var canvas = context.canvas;
20661 var _props$triggerOn = props.triggerOn,
20662 triggerOn = _props$triggerOn === void 0 ? DEFAULT_CONFIG.triggerOn : _props$triggerOn;
20663 canvas.on(triggerOn, this._handleEvent);
20664 }
20665 }, {
20666 key: "render",
20667 value: function render() {
20668 var context = this.context;
20669 var props = context.px2hd(deepMix({}, DEFAULT_CONFIG, this.props));
20670 var labels = this.getLabels(props);
20671 return jsx(View, _objectSpread(_objectSpread({
20672 labels: labels
20673 }, props), {}, {
20674 triggerRef: this.triggerRef
20675 }));
20676 }
20677 }]);
20678
20679 return PieLabel;
20680 }(Component);
20681 });
20682
20683 var PieLabelView = (function (props) {
20684 var lineStyle = props.lineStyle,
20685 anchorStyle = props.anchorStyle,
20686 labels = props.labels,
20687 label1OffsetY = props.label1OffsetY,
20688 label2OffsetY = props.label2OffsetY,
20689 triggerRef = props.triggerRef;
20690 return jsx("group", {
20691 ref: triggerRef
20692 }, labels.map(function (label) {
20693 var origin = label.origin,
20694 anchor = label.anchor,
20695 side = label.side,
20696 color = label.color,
20697 label1 = label.label1,
20698 label2 = label.label2,
20699 points = label.points;
20700 var end = points[points.length - 1];
20701 return jsx("group", null, jsx("circle", {
20702 attrs: _objectSpread({
20703 r: '4px',
20704 x: anchor.x,
20705 y: anchor.y,
20706 fill: color
20707 }, anchorStyle)
20708 }), jsx("polyline", {
20709 attrs: _objectSpread({
20710 points: points,
20711 lineWidth: '2px',
20712 stroke: color
20713 }, lineStyle)
20714 }), jsx("text", {
20715 className: "click",
20716 attrs: _objectSpread({
20717 x: end.x,
20718 y: end.y + label1OffsetY,
20719 fontSize: '24px',
20720 lineHeight: '24px',
20721 fill: color,
20722 textBaseline: 'bottom',
20723 textAlign: side === 'left' ? 'left' : 'right'
20724 }, label1),
20725 data: origin
20726 }), jsx("text", {
20727 className: "click",
20728 attrs: _objectSpread({
20729 x: end.x,
20730 y: end.y + label2OffsetY,
20731 fontSize: '24px',
20732 lineHeight: '24px',
20733 fill: '#808080',
20734 textBaseline: 'top',
20735 textAlign: side === 'left' ? 'left' : 'right'
20736 }, label2),
20737 data: origin
20738 }));
20739 }));
20740 });
20741
20742 var index$a = withPieLabel(PieLabelView);
20743
20744 var getPoint$2 = function getPoint(cener, angle, r) {
20745 var x = cener.x + Math.cos(angle) * r;
20746 var y = cener.y + Math.sin(angle) * r;
20747 return {
20748 x: x,
20749 y: y
20750 };
20751 };
20752
20753 var getTicks = function getTicks(start, end, tickCount, center, r, tickOffset, tickLength) {
20754 var ticks = [];
20755 var diff = end - start;
20756
20757 for (var i = 0; i <= tickCount; i++) {
20758 var tickValue = start + diff * i / tickCount;
20759 var startPoint = getPoint$2(center, tickValue, r + tickOffset - tickLength);
20760 var endPoint = getPoint$2(center, tickValue, r + tickOffset);
20761 ticks.push({
20762 tickValue: tickValue,
20763 start: startPoint,
20764 end: endPoint
20765 });
20766 }
20767
20768 return ticks;
20769 };
20770
20771 var withGauge = (function (View) {
20772 return /*#__PURE__*/function (_Component) {
20773 _inherits(Guage, _Component);
20774
20775 var _super = _createSuper(Guage);
20776
20777 function Guage() {
20778 _classCallCheck(this, Guage);
20779
20780 return _super.apply(this, arguments);
20781 }
20782
20783 _createClass(Guage, [{
20784 key: "render",
20785 value: function render() {
20786 var props = this.props,
20787 context = this.context;
20788 var startAngle = props.startAngle,
20789 endAngle = props.endAngle,
20790 tickCount = props.tickCount,
20791 center = props.center,
20792 r = props.r,
20793 tickOffset = props.tickOffset,
20794 tickLength = props.tickLength;
20795 var ticks = getTicks(startAngle, endAngle, tickCount, center, context.px2hd(r), context.px2hd(tickOffset), context.px2hd(tickLength));
20796 return jsx(View, _objectSpread(_objectSpread({}, props), {}, {
20797 ticks: ticks
20798 }));
20799 }
20800 }]);
20801
20802 return Guage;
20803 }(Component);
20804 });
20805
20806 var GaugeView = (function (props) {
20807 var center = props.center,
20808 startAngle = props.startAngle,
20809 endAngle = props.endAngle,
20810 r = props.r,
20811 percent = props.percent,
20812 ticks = props.ticks;
20813 var x = center.x,
20814 y = center.y;
20815 var diff = endAngle - startAngle;
20816 return jsx("group", null, jsx("arc", {
20817 attrs: {
20818 x: x,
20819 y: y,
20820 r: r,
20821 startAngle: startAngle,
20822 endAngle: endAngle,
20823 lineWidth: '20px',
20824 lineCap: 'round',
20825 stroke: '#e7e7e7'
20826 }
20827 }), jsx("arc", {
20828 attrs: {
20829 x: x,
20830 y: y,
20831 r: r,
20832 startAngle: startAngle,
20833 endAngle: startAngle,
20834 lineWidth: '40px',
20835 lineCap: 'round',
20836 stroke: '#0075ff'
20837 },
20838 animation: {
20839 appear: {
20840 easing: 'linear',
20841 duration: 500,
20842 property: ['endAngle'],
20843 start: {
20844 endAngle: startAngle
20845 },
20846 end: {
20847 endAngle: startAngle + diff * percent
20848 }
20849 }
20850 }
20851 }), ticks.map(function (tick) {
20852 var start = tick.start,
20853 end = tick.end;
20854 return jsx("line", {
20855 attrs: {
20856 x1: start.x,
20857 y1: start.y,
20858 x2: end.x,
20859 y2: end.y,
20860 lineWidth: '6px',
20861 lineCap: 'round',
20862 stroke: '#e7e7e7'
20863 }
20864 });
20865 }));
20866 });
20867
20868 var index$b = withGauge(GaugeView);
20869
20870 function isValuesEqual(values, newValues) {
20871 if (values.length !== newValues.length) {
20872 return false;
20873 }
20874
20875 var lastIndex = values.length - 1;
20876 return values[0] === newValues[0] && values[lastIndex] === newValues[lastIndex];
20877 }
20878
20879 function updateCategoryRange(scale, originScale, range) {
20880 var currentValues = scale.values,
20881 currentTicks = scale.ticks,
20882 tickMethod = scale.tickMethod,
20883 tickCount = scale.tickCount;
20884 var originValues = originScale.values;
20885
20886 var _range = _slicedToArray(range, 2),
20887 start = _range[0],
20888 end = _range[1];
20889
20890 var len = originValues.length;
20891 var valueStart = start * len;
20892 var valueEnd = end * len; // 保持滑动时个数的稳定
20893
20894 var count = Math.round(valueEnd - valueStart);
20895 var sliceSatrt = Math.round(valueStart); // 从原始数据里截取需要显示的数据
20896
20897 var newValues = originValues.slice(sliceSatrt, sliceSatrt + count); // 根据当前数据的比例,和定义的tickCount计算应该需要多少个ticks
20898
20899 var newTickCount = Math.round(tickCount * originValues.length / newValues.length); // 计算新的ticks
20900
20901 var catTicks = getTickMethod(tickMethod);
20902 var newTicks = catTicks({
20903 tickCount: newTickCount,
20904 values: originValues
20905 }); // 如果新数组和当前显示的数组相同,则不更新
20906
20907 if (isValuesEqual(currentValues, newValues) && isValuesEqual(currentTicks, newTicks)) {
20908 return;
20909 }
20910
20911 scale.change({
20912 values: newValues,
20913 ticks: newTicks
20914 });
20915 return scale;
20916 }
20917
20918 function updateLinearRange(scale, originScale, range) {
20919 var min = originScale.min,
20920 max = originScale.max;
20921
20922 var _range2 = _slicedToArray(range, 2),
20923 start = _range2[0],
20924 end = _range2[1];
20925
20926 var newMin = min + (max - min) * start;
20927 var newMax = min + (max - min) * end;
20928 scale.change({
20929 min: newMin,
20930 max: newMax,
20931 nice: false
20932 });
20933 }
20934
20935 function updateScale(scale, values) {
20936 var isLinear = scale.isLinear;
20937
20938 if (isLinear) {
20939 var _getRange = getRange(values),
20940 min = _getRange.min,
20941 max = _getRange.max;
20942
20943 return scale.change({
20944 min: min,
20945 max: max,
20946 nice: true
20947 });
20948 }
20949 }
20950
20951 function updateRange(scale, originScale, range) {
20952 var isCategory = scale.isCategory,
20953 isLinear = scale.isLinear;
20954
20955 if (isCategory) {
20956 return updateCategoryRange(scale, originScale, range);
20957 }
20958
20959 if (isLinear) {
20960 return updateLinearRange(scale, originScale, range);
20961 }
20962 }
20963
20964 function updateFollow(scales, mainScale, data) {
20965 var mainField = mainScale.field,
20966 mainType = mainScale.type,
20967 mainValues = mainScale.values; // 转成 map 提高查询性能
20968
20969 var mainValuesMap = {};
20970 mainValues.forEach(function (item) {
20971 mainValuesMap[item] = true;
20972 });
20973 return scales.map(function (scale) {
20974 var followField = scale.field;
20975 var values = [];
20976 data.forEach(function (item) {
20977 var value = mainType === 'timeCat' ? toTimeStamp(item[mainField]) : item[mainField];
20978
20979 if (mainValuesMap[value]) {
20980 values.push(item[followField]);
20981 }
20982 });
20983 return updateScale(scale, values);
20984 });
20985 }
20986
20987 function lerp(min, max, fraction) {
20988 return (max - min) * fraction + min;
20989 }
20990
20991 function isEqual$1(aRange, bRange) {
20992 for (var i in aRange) {
20993 if (!isNumberEqual(aRange[i], bRange[i])) return false;
20994 }
20995
20996 return true;
20997 }
20998
20999 function cloneScale$1(scale, scaleConfig) {
21000 // @ts-ignore
21001 return new scale.constructor(_objectSpread(_objectSpread({}, scale.__cfg__), scaleConfig));
21002 } // 缩放
21003
21004
21005 var Zoom = /*#__PURE__*/function (_Component) {
21006 _inherits(Zoom, _Component);
21007
21008 var _super = _createSuper(Zoom);
21009
21010 function Zoom(props) {
21011 var _this;
21012
21013 _classCallCheck(this, Zoom);
21014
21015 var defaultProps = {
21016 onPanStart: function onPanStart() {},
21017 onPinchStart: function onPinchStart() {},
21018 onPan: function onPan() {},
21019 onPinch: function onPinch() {},
21020 onInit: function onInit() {},
21021 onPanEnd: function onPanEnd() {},
21022 onPinchEnd: function onPinchEnd() {},
21023 minCount: 10
21024 };
21025 _this = _super.call(this, _objectSpread(_objectSpread({}, defaultProps), props));
21026 _this.scale = {};
21027 _this.originScale = {}; //swipe end x y
21028
21029 _this.swipeEnd = {
21030 startX: 0,
21031 startY: 0,
21032 endX: 0,
21033 endY: 0
21034 };
21035
21036 _this.onStart = function () {
21037 var _assertThisInitialize = _assertThisInitialized(_this),
21038 state = _assertThisInitialize.state;
21039
21040 var range = state.range;
21041 _this.startRange = range;
21042 _this.loop && cancelAnimationFrame(_this.loop);
21043 };
21044
21045 _this.onPan = function (ev) {
21046 var _assertThisInitialize2 = _assertThisInitialized(_this),
21047 dims = _assertThisInitialize2.dims;
21048
21049 var range = {};
21050 each(dims, function (dim) {
21051 if (dim === 'x') {
21052 range['x'] = _this._doXPan(ev);
21053 return;
21054 }
21055
21056 if (dim === 'y') {
21057 range['y'] = _this._doYPan(ev);
21058 return;
21059 }
21060 });
21061 if (isEqual$1(range, _this.state.range)) return;
21062
21063 _this.setState({
21064 range: range
21065 }); // console.log('pan range', range);
21066
21067 };
21068
21069 _this.onSwipe = function (ev) {
21070 var swipe = _this.props.swipe;
21071 if (_this.props.mode.length < 2 || !swipe) return;
21072 var _ev$velocityX = ev.velocityX,
21073 velocityX = _ev$velocityX === void 0 ? 0 : _ev$velocityX,
21074 _ev$velocityY = ev.velocityY,
21075 velocityY = _ev$velocityY === void 0 ? 0 : _ev$velocityY,
21076 points = ev.points;
21077 var range = _this.state.range;
21078 var _points$ = points[0],
21079 x = _points$.x,
21080 y = _points$.y; // 边界处理
21081
21082 if (Math.abs((range === null || range === void 0 ? void 0 : range.x[0]) - 0) < 0.0005 && velocityX > 0) return;
21083 if (Math.abs((range === null || range === void 0 ? void 0 : range.x[1]) - 1) < 0.0005 && velocityX < 0) return;
21084 if (Math.abs((range === null || range === void 0 ? void 0 : range.y[0]) - 0) < 0.0005 && velocityY < 0) return;
21085 if (Math.abs((range === null || range === void 0 ? void 0 : range.x[1]) - 1) < 0.0005 && velocityY > 0) return;
21086 _this.swipeEnd = {
21087 startX: x,
21088 startY: y,
21089 endX: x + velocityX * 50,
21090 endY: y - velocityY * 50
21091 };
21092
21093 _this.onStart();
21094
21095 _this.update();
21096 };
21097
21098 _this.onPinch = function (ev) {
21099 var _assertThisInitialize3 = _assertThisInitialized(_this),
21100 dims = _assertThisInitialize3.dims;
21101
21102 var range = {};
21103 each(dims, function (dim) {
21104 if (dim === 'x') {
21105 range['x'] = _this._doXPinch(ev);
21106 return;
21107 }
21108
21109 if (dim === 'y') {
21110 range['y'] = _this._doYPinch(ev);
21111 return;
21112 }
21113 });
21114 if (isEqual$1(range, _this.state.range)) return;
21115
21116 _this.setState({
21117 range: range
21118 });
21119 };
21120
21121 _this.onEnd = function () {
21122 _this.startRange = null;
21123 };
21124
21125 var _props$range = props.range,
21126 mode = props.mode;
21127 _this.dims = mode instanceof Array ? mode : [mode];
21128 return _this;
21129 }
21130
21131 _createClass(Zoom, [{
21132 key: "didMount",
21133 value: function didMount() {
21134 this._bindEvents();
21135 }
21136 }, {
21137 key: "willReceiveProps",
21138 value: function willReceiveProps(nextProps) {
21139 var nextRange = nextProps.range;
21140 var lastRange = this.props.range;
21141
21142 if (!equal(nextRange, lastRange)) {
21143 var cacheRange = {};
21144 each(this.dims, function (dim) {
21145 cacheRange[dim] = nextRange;
21146 });
21147 this.state = {
21148 range: cacheRange
21149 };
21150 }
21151 }
21152 }, {
21153 key: "willMount",
21154 value: function willMount() {
21155 var _this2 = this;
21156
21157 var props = this.props,
21158 dims = this.dims,
21159 state = this.state;
21160 var minCount = props.minCount,
21161 range = props.range; // const { range } = state;
21162
21163 var valueLength = Number.MIN_VALUE;
21164 var cacheRange = {};
21165 each(dims, function (dim) {
21166 var scale = _this2._getScale(dim);
21167
21168 var values = scale.values;
21169 valueLength = values.length > valueLength ? values.length : valueLength;
21170 _this2.scale[dim] = scale;
21171 _this2.originScale[dim] = cloneScale$1(scale);
21172
21173 _this2.updateRange(range, dim);
21174
21175 cacheRange[dim] = range;
21176 }); // 图表上最少显示 MIN_COUNT 个数据
21177
21178 this.minScale = minCount / valueLength;
21179 this.state = {
21180 range: cacheRange
21181 };
21182 }
21183 }, {
21184 key: "didUnmount",
21185 value: function didUnmount() {
21186 this._clearEvents();
21187 }
21188 }, {
21189 key: "update",
21190 value: function update() {
21191 var _this3 = this;
21192
21193 var _this$swipeEnd = this.swipeEnd,
21194 startX = _this$swipeEnd.startX,
21195 startY = _this$swipeEnd.startY,
21196 endX = _this$swipeEnd.endX,
21197 endY = _this$swipeEnd.endY;
21198 var x = lerp(startX, endX, 0.05);
21199 var y = lerp(startY, endY, 0.05);
21200 this.swipeEnd = {
21201 startX: x,
21202 startY: y,
21203 endX: endX,
21204 endY: endY
21205 };
21206 var props = this.props;
21207 var coord = props.coord;
21208 var coordWidth = coord.width,
21209 coordHeight = coord.height;
21210 var range = {};
21211 range['x'] = this._doPan((x - startX) / coordWidth, 'x');
21212 range['y'] = this._doPan((y - startY) / coordHeight, 'y');
21213 this.setState({
21214 range: range
21215 });
21216 this.startRange = range;
21217 this.loop = requestAnimationFrame(function () {
21218 return _this3.update();
21219 });
21220
21221 if (Math.abs(x - endX) < 0.0005 && Math.abs(y - endY) < 0.0005) {
21222 this.onEnd();
21223 cancelAnimationFrame(this.loop);
21224 }
21225 }
21226 }, {
21227 key: "_doXPan",
21228 value: function _doXPan(ev) {
21229 var direction = ev.direction,
21230 deltaX = ev.deltaX;
21231
21232 if (this.props.mode.length === 1 && (direction === 'up' || direction === 'down')) {
21233 return this.state.range['x'];
21234 }
21235
21236 ev.preventDefault && ev.preventDefault();
21237 var props = this.props;
21238 var coord = props.coord,
21239 _props$panSensitive = props.panSensitive,
21240 panSensitive = _props$panSensitive === void 0 ? 1 : _props$panSensitive;
21241 var coordWidth = coord.width;
21242 var ratio = deltaX / coordWidth * panSensitive;
21243
21244 var newRange = this._doPan(ratio, 'x');
21245
21246 return newRange;
21247 }
21248 }, {
21249 key: "_doYPan",
21250 value: function _doYPan(ev) {
21251 var direction = ev.direction,
21252 deltaY = ev.deltaY;
21253
21254 if (this.props.mode.length === 1 && (direction === 'left' || direction === 'right')) {
21255 return this.state.range['y'];
21256 }
21257
21258 ev.preventDefault && ev.preventDefault();
21259 var props = this.props;
21260 var coord = props.coord,
21261 _props$panSensitive2 = props.panSensitive,
21262 panSensitive = _props$panSensitive2 === void 0 ? 1 : _props$panSensitive2;
21263 var coordHeight = coord.height;
21264 var ratio = -deltaY / coordHeight * panSensitive;
21265
21266 var newRange = this._doPan(ratio, 'y');
21267
21268 return newRange;
21269 }
21270 }, {
21271 key: "_doPan",
21272 value: function _doPan(ratio, dim) {
21273 var startRange = this.startRange;
21274
21275 var _startRange$dim = _slicedToArray(startRange[dim], 2),
21276 start = _startRange$dim[0],
21277 end = _startRange$dim[1];
21278
21279 var rangeLen = end - start;
21280 var rangeOffset = rangeLen * ratio;
21281 var newStart = start - rangeOffset;
21282 var newEnd = end - rangeOffset;
21283 var newRange = this.updateRange([newStart, newEnd], dim);
21284 return newRange;
21285 }
21286 }, {
21287 key: "_doXPinch",
21288 value: function _doXPinch(ev) {
21289 ev.preventDefault && ev.preventDefault();
21290 var zoom = ev.zoom,
21291 center = ev.center;
21292 var props = this.props;
21293 var coord = props.coord;
21294 var coordWidth = coord.width,
21295 left = coord.left,
21296 right = coord.right;
21297 var leftLen = Math.abs(center.x - left);
21298 var rightLen = Math.abs(right - center.x); // 计算左右缩放的比例
21299
21300 var leftZoom = leftLen / coordWidth;
21301 var rightZoom = rightLen / coordWidth;
21302
21303 var newRange = this._doPinch(leftZoom, rightZoom, zoom, 'x');
21304
21305 return newRange;
21306 }
21307 }, {
21308 key: "_doYPinch",
21309 value: function _doYPinch(ev) {
21310 ev.preventDefault && ev.preventDefault();
21311 var zoom = ev.zoom,
21312 center = ev.center;
21313 var props = this.props;
21314 var coord = props.coord;
21315 var coordHeight = coord.height,
21316 top = coord.top,
21317 bottom = coord.bottom;
21318 var topLen = Math.abs(center.y - top);
21319 var bottomLen = Math.abs(bottom - center.y); // 计算左右缩放的比例
21320
21321 var topZoom = topLen / coordHeight;
21322 var bottomZoom = bottomLen / coordHeight;
21323
21324 var newRange = this._doPinch(topZoom, bottomZoom, zoom, 'y');
21325
21326 return newRange;
21327 }
21328 }, {
21329 key: "_doPinch",
21330 value: function _doPinch(startRatio, endRatio, zoom, dim) {
21331 var startRange = this.startRange,
21332 minScale = this.minScale,
21333 props = this.props;
21334 var _props$pinchSensitive = props.pinchSensitive,
21335 pinchSensitive = _props$pinchSensitive === void 0 ? 1 : _props$pinchSensitive;
21336
21337 var _startRange$dim2 = _slicedToArray(startRange[dim], 2),
21338 start = _startRange$dim2[0],
21339 end = _startRange$dim2[1];
21340
21341 var zoomOffset = zoom < 1 ? (1 / zoom - 1) * pinchSensitive : (1 - zoom) * pinchSensitive;
21342 var rangeLen = end - start;
21343 var rangeOffset = rangeLen * zoomOffset;
21344 var startOffset = rangeOffset * startRatio;
21345 var endOffset = rangeOffset * endRatio;
21346 var newStart = Math.max(0, start - startOffset);
21347 var newEnd = Math.min(1, end + endOffset);
21348 var newRange = [newStart, newEnd]; // 如果已经到了最小比例,则不能再继续再放大
21349
21350 if (newEnd - newStart < minScale) {
21351 return this.state.range[dim];
21352 }
21353
21354 return this.updateRange(newRange, dim);
21355 }
21356 }, {
21357 key: "updateRange",
21358 value: function updateRange$1(originalRange, dim) {
21359 if (!originalRange) return;
21360
21361 var _originalRange = _slicedToArray(originalRange, 2),
21362 start = _originalRange[0],
21363 end = _originalRange[1];
21364
21365 var rangeLength = end - start; // 处理边界值
21366
21367 var newRange;
21368
21369 if (start < 0) {
21370 newRange = [0, rangeLength];
21371 } else if (end > 1) {
21372 newRange = [1 - rangeLength, 1];
21373 } else {
21374 newRange = originalRange;
21375 }
21376
21377 var props = this.props,
21378 scale = this.scale,
21379 originScale = this.originScale,
21380 state = this.state;
21381 var chart = props.chart,
21382 data = props.data,
21383 autoFit = props.autoFit;
21384 var range = state.range;
21385 if (range && isEqual$1(newRange, range[dim])) return newRange; // 更新主 scale
21386
21387 updateRange(scale[dim], originScale[dim], newRange);
21388
21389 if (autoFit) {
21390 var followScale = this._getFollowScales(dim);
21391
21392 this.updateFollow(followScale, scale[dim], data);
21393 } // 手势变化不执行动画
21394
21395
21396 var animate = chart.animate;
21397 chart.setAnimate(false);
21398 chart.forceUpdate(function () {
21399 chart.setAnimate(animate);
21400 });
21401 return newRange;
21402 }
21403 }, {
21404 key: "updateFollow",
21405 value: function updateFollow$1(scales, mainScale, data) {
21406 updateFollow(scales, mainScale, data);
21407 }
21408 }, {
21409 key: "_getScale",
21410 value: function _getScale(dim) {
21411 var _this$props = this.props,
21412 coord = _this$props.coord,
21413 chart = _this$props.chart;
21414
21415 if (dim === 'x') {
21416 return coord.transposed ? chart.getYScales()[0] : chart.getXScales()[0];
21417 } else {
21418 return coord.transposed ? chart.getXScales()[0] : chart.getYScales()[0];
21419 }
21420 }
21421 }, {
21422 key: "_getFollowScales",
21423 value: function _getFollowScales(dim) {
21424 var _this$props2 = this.props,
21425 coord = _this$props2.coord,
21426 chart = _this$props2.chart;
21427
21428 if (dim === 'x') {
21429 return coord.transposed ? chart.getXScales() : chart.getYScales();
21430 }
21431
21432 if (dim === 'y') {
21433 return coord.transposed ? chart.getYScales() : chart.getXScales();
21434 }
21435 }
21436 }, {
21437 key: "_bindEvents",
21438 value: function _bindEvents() {
21439 var _this4 = this;
21440
21441 var context = this.context,
21442 props = this.props,
21443 scale = this.scale;
21444 var canvas = context.canvas;
21445 var onPinchStart = props.onPinchStart,
21446 onPanStart = props.onPanStart,
21447 onPanEnd = props.onPanEnd,
21448 pan = props.pan,
21449 pinch = props.pinch,
21450 swipe = props.swipe,
21451 onInit = props.onInit,
21452 onPan = props.onPan,
21453 onPinch = props.onPinch,
21454 onPinchEnd = props.onPinchEnd; // 统一绑定事件
21455
21456 if (pan !== false) {
21457 canvas.on('panstart', function () {
21458 _this4.onStart();
21459
21460 onPanStart({
21461 scale: scale
21462 });
21463 });
21464 canvas.on('pan', function (ev) {
21465 _this4.onPan(ev);
21466
21467 onPan(ev);
21468 });
21469 canvas.on('panend', function () {
21470 _this4.onEnd();
21471
21472 onPanEnd({
21473 scale: scale
21474 });
21475 });
21476 }
21477
21478 if (pinch !== false) {
21479 canvas.on('pinchstart', function () {
21480 _this4.onStart();
21481
21482 onPinchStart();
21483 });
21484 canvas.on('pinch', function (ev) {
21485 _this4.onPinch(ev);
21486
21487 onPinch(ev);
21488 });
21489 canvas.on('pinchend', function () {
21490 _this4.onEnd();
21491
21492 onPinchEnd({
21493 scale: scale
21494 });
21495 });
21496 }
21497
21498 if (swipe !== false) {
21499 canvas.on('swipe', this.onSwipe);
21500 }
21501
21502 onInit({
21503 scale: scale
21504 });
21505 }
21506 }, {
21507 key: "_clearEvents",
21508 value: function _clearEvents() {
21509 var _this5 = this;
21510
21511 var context = this.context,
21512 props = this.props,
21513 scale = this.scale;
21514 var canvas = context.canvas;
21515 var onPinchEnd = props.onPinchEnd,
21516 onPanEnd = props.onPanEnd,
21517 onPinchStart = props.onPinchStart,
21518 pan = props.pan,
21519 pinch = props.pinch,
21520 onPan = props.onPan,
21521 onPinch = props.onPinch,
21522 swipe = props.swipe; // 统一解绑事件
21523
21524 if (pan !== false) {
21525 canvas.off('panstart', function () {
21526 _this5.onStart();
21527
21528 onPinchStart();
21529 });
21530 canvas.off('pan', function (ev) {
21531 _this5.onPan(ev);
21532
21533 onPan(ev);
21534 });
21535 canvas.off('panend', function () {
21536 _this5.onEnd();
21537
21538 onPanEnd({
21539 scale: scale
21540 });
21541 });
21542 }
21543
21544 if (pinch !== false) {
21545 canvas.off('pinchstart', function () {
21546 _this5.onStart();
21547
21548 onPinchStart();
21549 });
21550 canvas.off('pinch', function (ev) {
21551 _this5.onPinch(ev);
21552
21553 onPinch(ev);
21554 });
21555 canvas.off('pinchend', function () {
21556 _this5.onEnd();
21557
21558 onPinchEnd({
21559 scale: scale
21560 });
21561 });
21562 }
21563
21564 if (swipe !== false) {
21565 canvas.off('swipe', this.onSwipe);
21566 }
21567 }
21568 }]);
21569
21570 return Zoom;
21571 }(Component);
21572
21573 var withScrollBar = (function (View) {
21574 return /*#__PURE__*/function (_Zoom) {
21575 _inherits(ScrollBar, _Zoom);
21576
21577 var _super = _createSuper(ScrollBar);
21578
21579 function ScrollBar() {
21580 _classCallCheck(this, ScrollBar);
21581
21582 return _super.apply(this, arguments);
21583 }
21584
21585 _createClass(ScrollBar, [{
21586 key: "willMount",
21587 value: function willMount() {
21588 _get$1(_getPrototypeOf(ScrollBar.prototype), "willMount", this).call(this);
21589
21590 var context = this.context,
21591 props = this.props;
21592 var visible = props.visible,
21593 _props$position = props.position,
21594 position = _props$position === void 0 ? 'bottom' : _props$position,
21595 _props$margin = props.margin,
21596 margin = _props$margin === void 0 ? '16px' : _props$margin,
21597 chart = props.chart;
21598 var marginNumber = context.px2hd(margin);
21599
21600 if (visible === false) {
21601 return null;
21602 }
21603
21604 chart.updateCoordFor(this, {
21605 position: position,
21606 width: position === 'left' || position === 'right' ? marginNumber : 0,
21607 height: position === 'bottom' || position === 'top' ? marginNumber : 0
21608 });
21609 }
21610 }, {
21611 key: "render",
21612 value: function render() {
21613 var props = this.props,
21614 state = this.state;
21615 var visible = props.visible;
21616
21617 if (visible === false) {
21618 return null;
21619 }
21620
21621 return jsx(View, _objectSpread(_objectSpread({
21622 position: "bottom"
21623 }, props), state));
21624 }
21625 }]);
21626
21627 return ScrollBar;
21628 }(Zoom);
21629 });
21630
21631 var Horizontal = (function (props, context) {
21632 var coord = props.coord,
21633 range = props.range,
21634 position = props.position,
21635 layout = props.layout;
21636 var left = coord.left,
21637 width = coord.width;
21638 var top = layout.top,
21639 height = layout.height;
21640
21641 var _ref = (range === null || range === void 0 ? void 0 : range.x) || (range === null || range === void 0 ? void 0 : range.y),
21642 _ref2 = _slicedToArray(_ref, 2),
21643 start = _ref2[0],
21644 end = _ref2[1];
21645
21646 var barLeft = width * start;
21647 var barWidth = width * (end - start);
21648 return jsx("group", {
21649 style: {
21650 left: left,
21651 top: position === 'top' ? top - context.px2hd('8px') : top + height
21652 }
21653 }, jsx("line", {
21654 style: {
21655 position: 'absolute',
21656 left: 0,
21657 width: width,
21658 height: 0
21659 },
21660 attrs: {
21661 stroke: 'rgba(202, 215, 239, .2)',
21662 lineCap: 'round',
21663 lineWidth: '8px'
21664 }
21665 }), jsx("line", {
21666 style: {
21667 position: 'absolute',
21668 left: barLeft,
21669 width: barWidth,
21670 height: 0
21671 },
21672 attrs: {
21673 stroke: 'rgba(202, 215, 239, .5)',
21674 lineCap: 'round',
21675 lineWidth: '8px'
21676 }
21677 }));
21678 });
21679
21680 var Vertical = (function (props, context) {
21681 var coord = props.coord,
21682 range = props.range,
21683 position = props.position,
21684 layout = props.layout;
21685 var top = coord.top,
21686 height = coord.height;
21687 var left = layout.left,
21688 width = layout.width;
21689
21690 var _ref = (range === null || range === void 0 ? void 0 : range.y) || (range === null || range === void 0 ? void 0 : range.x),
21691 _ref2 = _slicedToArray(_ref, 2),
21692 start = _ref2[0],
21693 end = _ref2[1];
21694
21695 var barTop = height * start;
21696 var barHeight = height * (end - start);
21697 return jsx("group", {
21698 style: {
21699 top: top,
21700 left: position === 'left' ? left - context.px2hd('8px') : left + width
21701 }
21702 }, jsx("line", {
21703 style: {
21704 position: 'absolute',
21705 top: 0,
21706 left: 0,
21707 width: 0,
21708 height: height
21709 },
21710 attrs: {
21711 stroke: 'rgba(202, 215, 239, .2)',
21712 lineCap: 'round',
21713 lineWidth: '8px'
21714 }
21715 }), jsx("line", {
21716 style: {
21717 position: 'absolute',
21718 top: barTop,
21719 width: 0,
21720 height: barHeight
21721 },
21722 attrs: {
21723 stroke: 'rgba(202, 215, 239, .5)',
21724 lineCap: 'round',
21725 lineWidth: '8px'
21726 }
21727 }));
21728 });
21729
21730 var ScrollBarView = (function (props) {
21731 var position = props.position,
21732 mode = props.mode;
21733
21734 if (mode.length > 1) {
21735 return jsx("group", null, jsx(Vertical, _objectSpread({}, props)), jsx(Horizontal, _objectSpread({}, props)));
21736 }
21737
21738 if (position === 'left' || position === 'right') {
21739 return jsx(Vertical, _objectSpread({}, props));
21740 }
21741
21742 return jsx(Horizontal, _objectSpread({}, props));
21743 });
21744
21745 var index$c = withScrollBar(ScrollBarView);
21746
21747 exports.ArcGuide = ArcGuide;
21748 exports.Area = index$1;
21749 exports.AreaView = AreaView;
21750 exports.Axis = index$4;
21751 exports.AxisView = AxisView;
21752 exports.Canvas = Canvas$1;
21753 exports.Chart = Chart;
21754 exports.Children = Children;
21755 exports.Component = Component;
21756 exports.Fragment = fragment;
21757 exports.Gauge = index$b;
21758 exports.GaugeView = GaugeView;
21759 exports.Geometry = Geometry;
21760 exports.Guide = index$6;
21761 exports.ImageGuide = ImageGuide;
21762 exports.Interval = index$2;
21763 exports.IntervalView = intervalView;
21764 exports.Legend = index$5;
21765 exports.LegendView = LegendView;
21766 exports.Line = index;
21767 exports.LineGuide = LineGuide;
21768 exports.LineView = LineView;
21769 exports.PieLabel = index$a;
21770 exports.PieLabelView = PieLabelView;
21771 exports.Point = index$3;
21772 exports.PointGuide = PointGuide;
21773 exports.PointView = PointView;
21774 exports.RectGuide = RectGuide;
21775 exports.ScrollBar = index$c;
21776 exports.ScrollBarView = ScrollBarView;
21777 exports.Sunburst = index$9;
21778 exports.SunburstView = SunburstView;
21779 exports.TagGuide = TagGuide;
21780 exports.TextGuide = TextGuide;
21781 exports.Timeline = Timeline;
21782 exports.Tooltip = index$7;
21783 exports.TooltipView = TooltipView;
21784 exports.Treemap = index$8;
21785 exports.TreemapView = TreemapView;
21786 exports.Zoom = Zoom;
21787 exports.createElement = jsx;
21788 exports.createRef = createRef;
21789 exports.jsx = jsx;
21790 exports.render = render$1;
21791 exports.renderShape = renderShape;
21792 exports.withArea = withArea;
21793 exports.withAxis = withAxis;
21794 exports.withGauge = withGauge;
21795 exports.withGuide = withGuide;
21796 exports.withInterval = withInterval;
21797 exports.withLegend = withLegend;
21798 exports.withLine = withLine;
21799 exports.withPieLabel = withPieLabel;
21800 exports.withPoint = withPoint;
21801 exports.withScrollBar = withScrollBar;
21802 exports.withSunburst = withSunburst;
21803 exports.withTooltip = withTooltip;
21804 exports.withTreemap = withTreemap;
21805
21806 Object.defineProperty(exports, '__esModule', { value: true });
21807
21808})));