liyongli пре 3 година
комит
33ea84024b
100 измењених фајлова са 25648 додато и 0 уклоњено
  1. 31 0
      .eslintrc.js
  2. 14 0
      .gitignore
  3. 29 0
      miniprogram/app.json
  4. 7 0
      miniprogram/app.less
  5. 17 0
      miniprogram/app.ts
  6. 6 0
      miniprogram/config_base.ts
  7. 22995 0
      miniprogram/miniprogram_npm/@antv/wx-f2/index.js
  8. 0 0
      miniprogram/miniprogram_npm/@antv/wx-f2/index.js.map
  9. 4 0
      miniprogram/miniprogram_npm/@antv/wx-f2/index.json
  10. 8 0
      miniprogram/miniprogram_npm/@antv/wx-f2/index.wxml
  11. 4 0
      miniprogram/miniprogram_npm/@antv/wx-f2/index.wxss
  12. 1 0
      miniprogram/miniprogram_npm/@vant/weapp/action-sheet/index.d.ts
  13. 73 0
      miniprogram/miniprogram_npm/@vant/weapp/action-sheet/index.js
  14. 8 0
      miniprogram/miniprogram_npm/@vant/weapp/action-sheet/index.json
  15. 69 0
      miniprogram/miniprogram_npm/@vant/weapp/action-sheet/index.wxml
  16. 1 0
      miniprogram/miniprogram_npm/@vant/weapp/action-sheet/index.wxss
  17. 1 0
      miniprogram/miniprogram_npm/@vant/weapp/area/index.d.ts
  18. 232 0
      miniprogram/miniprogram_npm/@vant/weapp/area/index.js
  19. 6 0
      miniprogram/miniprogram_npm/@vant/weapp/area/index.json
  20. 20 0
      miniprogram/miniprogram_npm/@vant/weapp/area/index.wxml
  21. 8 0
      miniprogram/miniprogram_npm/@vant/weapp/area/index.wxs
  22. 1 0
      miniprogram/miniprogram_npm/@vant/weapp/area/index.wxss
  23. 1 0
      miniprogram/miniprogram_npm/@vant/weapp/button/index.d.ts
  24. 67 0
      miniprogram/miniprogram_npm/@vant/weapp/button/index.js
  25. 7 0
      miniprogram/miniprogram_npm/@vant/weapp/button/index.json
  26. 53 0
      miniprogram/miniprogram_npm/@vant/weapp/button/index.wxml
  27. 39 0
      miniprogram/miniprogram_npm/@vant/weapp/button/index.wxs
  28. 0 0
      miniprogram/miniprogram_npm/@vant/weapp/button/index.wxss
  29. 68 0
      miniprogram/miniprogram_npm/@vant/weapp/calendar/calendar.wxml
  30. 1 0
      miniprogram/miniprogram_npm/@vant/weapp/calendar/components/header/index.d.ts
  31. 45 0
      miniprogram/miniprogram_npm/@vant/weapp/calendar/components/header/index.js
  32. 3 0
      miniprogram/miniprogram_npm/@vant/weapp/calendar/components/header/index.json
  33. 16 0
      miniprogram/miniprogram_npm/@vant/weapp/calendar/components/header/index.wxml
  34. 1 0
      miniprogram/miniprogram_npm/@vant/weapp/calendar/components/header/index.wxss
  35. 6 0
      miniprogram/miniprogram_npm/@vant/weapp/calendar/components/month/index.d.ts
  36. 158 0
      miniprogram/miniprogram_npm/@vant/weapp/calendar/components/month/index.js
  37. 3 0
      miniprogram/miniprogram_npm/@vant/weapp/calendar/components/month/index.json
  38. 39 0
      miniprogram/miniprogram_npm/@vant/weapp/calendar/components/month/index.wxml
  39. 71 0
      miniprogram/miniprogram_npm/@vant/weapp/calendar/components/month/index.wxs
  40. 0 0
      miniprogram/miniprogram_npm/@vant/weapp/calendar/components/month/index.wxss
  41. 1 0
      miniprogram/miniprogram_npm/@vant/weapp/calendar/index.d.ts
  42. 360 0
      miniprogram/miniprogram_npm/@vant/weapp/calendar/index.js
  43. 10 0
      miniprogram/miniprogram_npm/@vant/weapp/calendar/index.json
  44. 25 0
      miniprogram/miniprogram_npm/@vant/weapp/calendar/index.wxml
  45. 38 0
      miniprogram/miniprogram_npm/@vant/weapp/calendar/index.wxs
  46. 1 0
      miniprogram/miniprogram_npm/@vant/weapp/calendar/index.wxss
  47. 12 0
      miniprogram/miniprogram_npm/@vant/weapp/calendar/utils.d.ts
  48. 97 0
      miniprogram/miniprogram_npm/@vant/weapp/calendar/utils.js
  49. 25 0
      miniprogram/miniprogram_npm/@vant/weapp/calendar/utils.wxs
  50. 1 0
      miniprogram/miniprogram_npm/@vant/weapp/card/index.d.ts
  51. 51 0
      miniprogram/miniprogram_npm/@vant/weapp/card/index.js
  52. 6 0
      miniprogram/miniprogram_npm/@vant/weapp/card/index.json
  53. 56 0
      miniprogram/miniprogram_npm/@vant/weapp/card/index.wxml
  54. 1 0
      miniprogram/miniprogram_npm/@vant/weapp/card/index.wxss
  55. 1 0
      miniprogram/miniprogram_npm/@vant/weapp/cell-group/index.d.ts
  56. 13 0
      miniprogram/miniprogram_npm/@vant/weapp/cell-group/index.js
  57. 3 0
      miniprogram/miniprogram_npm/@vant/weapp/cell-group/index.json
  58. 11 0
      miniprogram/miniprogram_npm/@vant/weapp/cell-group/index.wxml
  59. 1 0
      miniprogram/miniprogram_npm/@vant/weapp/cell-group/index.wxss
  60. 1 0
      miniprogram/miniprogram_npm/@vant/weapp/cell/index.d.ts
  61. 40 0
      miniprogram/miniprogram_npm/@vant/weapp/cell/index.js
  62. 6 0
      miniprogram/miniprogram_npm/@vant/weapp/cell/index.json
  63. 47 0
      miniprogram/miniprogram_npm/@vant/weapp/cell/index.wxml
  64. 17 0
      miniprogram/miniprogram_npm/@vant/weapp/cell/index.wxs
  65. 0 0
      miniprogram/miniprogram_npm/@vant/weapp/cell/index.wxss
  66. 1 0
      miniprogram/miniprogram_npm/@vant/weapp/checkbox-group/index.d.ts
  67. 39 0
      miniprogram/miniprogram_npm/@vant/weapp/checkbox-group/index.js
  68. 3 0
      miniprogram/miniprogram_npm/@vant/weapp/checkbox-group/index.json
  69. 5 0
      miniprogram/miniprogram_npm/@vant/weapp/checkbox-group/index.wxml
  70. 1 0
      miniprogram/miniprogram_npm/@vant/weapp/checkbox-group/index.wxss
  71. 1 0
      miniprogram/miniprogram_npm/@vant/weapp/checkbox/index.d.ts
  72. 79 0
      miniprogram/miniprogram_npm/@vant/weapp/checkbox/index.js
  73. 6 0
      miniprogram/miniprogram_npm/@vant/weapp/checkbox/index.json
  74. 31 0
      miniprogram/miniprogram_npm/@vant/weapp/checkbox/index.wxml
  75. 20 0
      miniprogram/miniprogram_npm/@vant/weapp/checkbox/index.wxs
  76. 1 0
      miniprogram/miniprogram_npm/@vant/weapp/checkbox/index.wxss
  77. 4 0
      miniprogram/miniprogram_npm/@vant/weapp/circle/canvas.d.ts
  78. 47 0
      miniprogram/miniprogram_npm/@vant/weapp/circle/canvas.js
  79. 1 0
      miniprogram/miniprogram_npm/@vant/weapp/circle/index.d.ts
  80. 203 0
      miniprogram/miniprogram_npm/@vant/weapp/circle/index.js
  81. 3 0
      miniprogram/miniprogram_npm/@vant/weapp/circle/index.json
  82. 9 0
      miniprogram/miniprogram_npm/@vant/weapp/circle/index.wxml
  83. 1 0
      miniprogram/miniprogram_npm/@vant/weapp/circle/index.wxss
  84. 1 0
      miniprogram/miniprogram_npm/@vant/weapp/col/index.d.ts
  85. 11 0
      miniprogram/miniprogram_npm/@vant/weapp/col/index.js
  86. 3 0
      miniprogram/miniprogram_npm/@vant/weapp/col/index.json
  87. 9 0
      miniprogram/miniprogram_npm/@vant/weapp/col/index.wxml
  88. 18 0
      miniprogram/miniprogram_npm/@vant/weapp/col/index.wxs
  89. 1 0
      miniprogram/miniprogram_npm/@vant/weapp/col/index.wxss
  90. 2 0
      miniprogram/miniprogram_npm/@vant/weapp/collapse-item/animate.d.ts
  91. 43 0
      miniprogram/miniprogram_npm/@vant/weapp/collapse-item/animate.js
  92. 1 0
      miniprogram/miniprogram_npm/@vant/weapp/collapse-item/index.d.ts
  93. 61 0
      miniprogram/miniprogram_npm/@vant/weapp/collapse-item/index.js
  94. 6 0
      miniprogram/miniprogram_npm/@vant/weapp/collapse-item/index.json
  95. 44 0
      miniprogram/miniprogram_npm/@vant/weapp/collapse-item/index.wxml
  96. 1 0
      miniprogram/miniprogram_npm/@vant/weapp/collapse-item/index.wxss
  97. 1 0
      miniprogram/miniprogram_npm/@vant/weapp/collapse/index.d.ts
  98. 48 0
      miniprogram/miniprogram_npm/@vant/weapp/collapse/index.js
  99. 3 0
      miniprogram/miniprogram_npm/@vant/weapp/collapse/index.json
  100. 3 0
      miniprogram/miniprogram_npm/@vant/weapp/collapse/index.wxml

+ 31 - 0
.eslintrc.js

@@ -0,0 +1,31 @@
+/*
+ * Eslint config file
+ * Documentation: https://eslint.org/docs/user-guide/configuring/
+ * Install the Eslint extension before using this feature.
+ */
+module.exports = {
+  env: {
+    es6: true,
+    browser: true,
+    node: true,
+  },
+  ecmaFeatures: {
+    modules: true,
+  },
+  parserOptions: {
+    ecmaVersion: 2018,
+    sourceType: 'module',
+  },
+  globals: {
+    wx: true,
+    App: true,
+    Page: true,
+    getCurrentPages: true,
+    getApp: true,
+    Component: true,
+    requirePlugin: true,
+    requireMiniProgram: true,
+  },
+  // extends: 'eslint:recommended',
+  rules: {},
+}

+ 14 - 0
.gitignore

@@ -0,0 +1,14 @@
+# Windows
+[Dd]esktop.ini
+Thumbs.db
+$RECYCLE.BIN/
+
+# macOS
+.DS_Store
+.fseventsd
+.Spotlight-V100
+.TemporaryItems
+.Trashes
+
+# Node.js
+node_modules/

+ 29 - 0
miniprogram/app.json

@@ -0,0 +1,29 @@
+{
+  "pages": [
+    "pages/channelAdvertising/index",
+    "pages/industryAdvertising/index"
+  ],
+  "window": {
+    "backgroundTextStyle": "light",
+    "navigationBarBackgroundColor": "#fff",
+    "navigationBarTitleText": "陕西广电融媒体集团创新中心",
+    "navigationBarTextStyle": "black"
+  },
+  "tabBar": {
+    "custom": false,
+    "color": "#646566",
+    "selectedColor": "#1989fa",
+    "position": "top",
+    "list": [
+      {
+        "pagePath": "pages/channelAdvertising/index",
+        "text": "频道广告"
+      },
+      {
+        "pagePath": "pages/industryAdvertising/index",
+        "text": "行业广告"
+      }
+    ]
+  },
+  "sitemapLocation": "sitemap.json"
+}

+ 7 - 0
miniprogram/app.less

@@ -0,0 +1,7 @@
+/**app.wxss**/
+page{
+  font-weight: 400;
+  font-size: 14px;
+  height: 100vh;
+  overflow-x: hidden;
+}

+ 17 - 0
miniprogram/app.ts

@@ -0,0 +1,17 @@
+// app.ts
+const baseConfig = require("./config_base")
+App<IAppOption>({
+  globalData: {
+    base: baseConfig,
+    tabActive: 0
+  },
+  onLaunch() {
+    // 登录
+    // wx.login({
+    //   success: res => {
+    //     console.log(res.code)
+    //     // 发送 res.code 到后台换取 openId, sessionKey, unionId
+    //   },
+    // })
+  },
+})

+ 6 - 0
miniprogram/config_base.ts

@@ -0,0 +1,6 @@
+const base = {
+  url: "https://topic.smcic.net"
+}
+
+
+module.exports = base;

+ 22995 - 0
miniprogram/miniprogram_npm/@antv/wx-f2/index.js

@@ -0,0 +1,22995 @@
+(function (factory) {
+    typeof define === 'function' && define.amd ? define(factory) :
+    factory();
+}((function () { 'use strict';
+
+    var isArrayLike = function (value) {
+        /**
+         * isArrayLike([1, 2, 3]) => true
+         * isArrayLike(document.body.children) => true
+         * isArrayLike('abc') => true
+         * isArrayLike(Function) => false
+         */
+        return value !== null && typeof value !== 'function' && isFinite(value.length);
+    };
+
+    var contains = function (arr, value) {
+        if (!isArrayLike(arr)) {
+            return false;
+        }
+        return arr.indexOf(value) > -1;
+    };
+
+    var filter = function (arr, func) {
+        if (!isArrayLike(arr)) {
+            return arr;
+        }
+        var result = [];
+        for (var index = 0; index < arr.length; index++) {
+            var value = arr[index];
+            if (func(value, index)) {
+                result.push(value);
+            }
+        }
+        return result;
+    };
+
+    /**
+     * Flattens `array` a single level deep.
+     *
+     * @param {Array} arr The array to inspect.
+     * @param {Array} values The values to exclude.
+     * @return {Array} Returns the new array of filtered values.
+     * @example
+     * difference([2, 1], [2, 3]);  // => [1]
+     */
+    var difference = function (arr, values) {
+        if (values === void 0) { values = []; }
+        return filter(arr, function (value) { return !contains(values, value); });
+    };
+
+    var toString = {}.toString;
+    var isType = function (value, type) { return toString.call(value) === '[object ' + type + ']'; };
+
+    /**
+     * 是否为函数
+     * @param  {*} fn 对象
+     * @return {Boolean}  是否函数
+     */
+    var isFunction = (function (value) {
+        return isType(value, 'Function');
+    });
+
+    // isFinite,
+    var isNil = function (value) {
+        /**
+         * isNil(null) => true
+         * isNil() => true
+         */
+        return value === null || value === undefined;
+    };
+
+    var isArray = (function (value) {
+        return Array.isArray ?
+            Array.isArray(value) :
+            isType(value, 'Array');
+    });
+
+    var isObject = (function (value) {
+        /**
+         * isObject({}) => true
+         * isObject([1, 2, 3]) => true
+         * isObject(Function) => true
+         * isObject(null) => false
+         */
+        var type = typeof value;
+        return value !== null && type === 'object' || type === 'function';
+    });
+
+    function each(elements, func) {
+        if (!elements) {
+            return;
+        }
+        var rst;
+        if (isArray(elements)) {
+            for (var i = 0, len = elements.length; i < len; i++) {
+                rst = func(elements[i], i);
+                if (rst === false) {
+                    break;
+                }
+            }
+        }
+        else if (isObject(elements)) {
+            for (var k in elements) {
+                if (elements.hasOwnProperty(k)) {
+                    rst = func(elements[k], k);
+                    if (rst === false) {
+                        break;
+                    }
+                }
+            }
+        }
+    }
+
+    var keys = Object.keys ? function (obj) { return Object.keys(obj); } : function (obj) {
+        var result = [];
+        each(obj, function (value, key) {
+            if (!(isFunction(obj) && key === 'prototype')) {
+                result.push(key);
+            }
+        });
+        return result;
+    };
+
+    function isMatch(obj, attrs) {
+        var _keys = keys(attrs);
+        var length = _keys.length;
+        if (isNil(obj))
+            return !length;
+        for (var i = 0; i < length; i += 1) {
+            var key = _keys[i];
+            if (attrs[key] !== obj[key] || !(key in obj)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    var isObjectLike = function (value) {
+        /**
+         * isObjectLike({}) => true
+         * isObjectLike([1, 2, 3]) => true
+         * isObjectLike(Function) => false
+         * isObjectLike(null) => false
+         */
+        return typeof value === 'object' && value !== null;
+    };
+
+    var isPlainObject = function (value) {
+        /**
+         * isObjectLike(new Foo) => false
+         * isObjectLike([1, 2, 3]) => false
+         * isObjectLike({ x: 0, y: 0 }) => true
+         * isObjectLike(Object.create(null)) => true
+         */
+        if (!isObjectLike(value) || !isType(value, 'Object')) {
+            return false;
+        }
+        if (Object.getPrototypeOf(value) === null) {
+            return true;
+        }
+        var proto = value;
+        while (Object.getPrototypeOf(proto) !== null) {
+            proto = Object.getPrototypeOf(proto);
+        }
+        return Object.getPrototypeOf(value) === proto;
+    };
+
+    function find(arr, predicate) {
+        if (!isArray(arr))
+            return null;
+        var _predicate;
+        if (isFunction(predicate)) {
+            _predicate = predicate;
+        }
+        if (isPlainObject(predicate)) {
+            _predicate = function (a) { return isMatch(a, predicate); };
+        }
+        if (_predicate) {
+            for (var i = 0; i < arr.length; i += 1) {
+                if (_predicate(arr[i])) {
+                    return arr[i];
+                }
+            }
+        }
+        return null;
+    }
+
+    function findIndex(arr, predicate, fromIndex) {
+        if (fromIndex === void 0) { fromIndex = 0; }
+        for (var i = fromIndex; i < arr.length; i++) {
+            if (predicate(arr[i], i)) {
+                // 找到终止循环
+                return i;
+            }
+        }
+        return -1;
+    }
+
+    var firstValue = function (data, name) {
+        var rst = null;
+        for (var i = 0; i < data.length; i++) {
+            var obj = data[i];
+            var value = obj[name];
+            if (!isNil(value)) {
+                if (isArray(value)) {
+                    rst = value[0]; // todo 这里是否应该使用递归,调用 firstValue @绝云
+                }
+                else {
+                    rst = value;
+                }
+                break;
+            }
+        }
+        return rst;
+    };
+
+    /**
+     * Flattens `array` a single level deep.
+     *
+     * @param {Array} arr The array to flatten.
+     * @return {Array} Returns the new flattened array.
+     * @example
+     *
+     * flatten([1, [2, [3, [4]], 5]]);  // => [1, 2, [3, [4]], 5]
+     */
+    var flatten = function (arr) {
+        if (!isArray(arr)) {
+            return [];
+        }
+        var rst = [];
+        for (var i = 0; i < arr.length; i++) {
+            rst = rst.concat(arr[i]);
+        }
+        return rst;
+    };
+
+    /**
+     * Flattens `array` a single level deep.
+     *
+     * @param {Array} arr The array to flatten.
+     * @param {Array} result The array to return.
+     * @return {Array} Returns the new flattened array.
+     * @example
+     *
+     * flattenDeep([1, [2, [3, [4]], 5]]);  // => [1, 2, 3, 4, 5]
+     */
+    var flattenDeep = function (arr, result) {
+        if (result === void 0) { result = []; }
+        if (!isArray(arr)) {
+            result.push(arr);
+        }
+        else {
+            for (var i = 0; i < arr.length; i += 1) {
+                flattenDeep(arr[i], result);
+            }
+        }
+        return result;
+    };
+
+    /**
+     * @param {Array} arr The array to iterate over.
+     * @return {*} Returns the maximum value.
+     * @example
+     *
+     * max([1, 2]);
+     * // => 2
+     *
+     * max([]);
+     * // => undefined
+     *
+     * const data = new Array(1250010).fill(1).map((d,idx) => idx);
+     *
+     * max(data);
+     * // => 1250010
+     * // Math.max(...data) will encounter "Maximum call stack size exceeded" error
+     */
+    var getMax = (function (arr) {
+        if (!isArray(arr)) {
+            return undefined;
+        }
+        return arr.reduce(function (prev, curr) {
+            return Math.max(prev, curr);
+        }, arr[0]);
+    });
+
+    /**
+     * @param {Array} arr The array to iterate over.
+     * @return {*} Returns the minimum value.
+     * @example
+     *
+     * min([1, 2]);
+     * // => 1
+     *
+     * min([]);
+     * // => undefined
+     *
+     * const data = new Array(1250010).fill(1).map((d,idx) => idx);
+     *
+     * min(data);
+     * // => 1250010
+     * // Math.min(...data) will encounter "Maximum call stack size exceeded" error
+     */
+    var getMin = (function (arr) {
+        if (!isArray(arr)) {
+            return undefined;
+        }
+        return arr.reduce(function (prev, curr) {
+            return Math.min(prev, curr);
+        }, arr[0]);
+    });
+
+    var getRange = function (values) {
+        // 存在 NaN 时,min,max 判定会出问题
+        var filterValues = values.filter(function (v) { return !isNaN(v); });
+        if (!filterValues.length) {
+            // 如果没有数值则直接返回0
+            return {
+                min: 0,
+                max: 0,
+            };
+        }
+        if (isArray(values[0])) {
+            var tmp = [];
+            for (var i = 0; i < values.length; i++) {
+                tmp = tmp.concat(values[i]);
+            }
+            filterValues = tmp;
+        }
+        var max = getMax(filterValues);
+        var min = getMin(filterValues);
+        return {
+            min: min,
+            max: max,
+        };
+    };
+
+    var arrPrototype = Array.prototype;
+    var splice = arrPrototype.splice;
+    var indexOf = arrPrototype.indexOf;
+    var pull = function (arr) {
+        var values = [];
+        for (var _i = 1; _i < arguments.length; _i++) {
+            values[_i - 1] = arguments[_i];
+        }
+        for (var i = 0; i < values.length; i++) {
+            var value = values[i];
+            var fromIndex = -1;
+            while ((fromIndex = indexOf.call(arr, value)) > -1) {
+                splice.call(arr, fromIndex, 1);
+            }
+        }
+        return arr;
+    };
+
+    var splice$1 = Array.prototype.splice;
+    var pullAt = function pullAt(arr, indexes) {
+        if (!isArrayLike(arr)) {
+            return [];
+        }
+        var length = arr ? indexes.length : 0;
+        var last = length - 1;
+        while (length--) {
+            var previous = void 0;
+            var index = indexes[length];
+            if (length === last || index !== previous) {
+                previous = index;
+                splice$1.call(arr, index, 1);
+            }
+        }
+        return arr;
+    };
+
+    var reduce = function (arr, fn, init) {
+        if (!isArray(arr) && !isPlainObject(arr)) {
+            return arr;
+        }
+        var result = init;
+        each(arr, function (data, i) {
+            result = fn(result, data, i);
+        });
+        return result;
+    };
+
+    var remove = function (arr, predicate) {
+        /**
+         * const arr = [1, 2, 3, 4]
+         * const evens = remove(arr, n => n % 2 == 0)
+         * console.log(arr) // => [1, 3]
+         * console.log(evens) // => [2, 4]
+         */
+        var result = [];
+        if (!isArrayLike(arr)) {
+            return result;
+        }
+        var i = -1;
+        var indexes = [];
+        var length = arr.length;
+        while (++i < length) {
+            var value = arr[i];
+            if (predicate(value, i, arr)) {
+                result.push(value);
+                indexes.push(i);
+            }
+        }
+        pullAt(arr, indexes);
+        return result;
+    };
+
+    var isString = (function (str) {
+        return isType(str, 'String');
+    });
+
+    function sortBy(arr, key) {
+        var comparer;
+        if (isFunction(key)) {
+            comparer = function (a, b) { return key(a) - key(b); };
+        }
+        else {
+            var keys_1 = [];
+            if (isString(key)) {
+                keys_1.push(key);
+            }
+            else if (isArray(key)) {
+                keys_1 = key;
+            }
+            comparer = function (a, b) {
+                for (var i = 0; i < keys_1.length; i += 1) {
+                    var prop = keys_1[i];
+                    if (a[prop] > b[prop]) {
+                        return 1;
+                    }
+                    if (a[prop] < b[prop]) {
+                        return -1;
+                    }
+                }
+                return 0;
+            };
+        }
+        arr.sort(comparer);
+        return arr;
+    }
+
+    function uniq(arr, cache) {
+        if (cache === void 0) { cache = new Map(); }
+        var r = [];
+        if (Array.isArray(arr)) {
+            for (var i = 0, len = arr.length; i < len; i++) {
+                var item = arr[i];
+                // 加一个 cache,提升性能
+                if (!cache.has(item)) {
+                    r.push(item);
+                    cache.set(item, true);
+                }
+            }
+        }
+        return r;
+    }
+
+    var union = function () {
+        var sources = [];
+        for (var _i = 0; _i < arguments.length; _i++) {
+            sources[_i] = arguments[_i];
+        }
+        return uniq([].concat.apply([], sources));
+    };
+
+    var valuesOfKey = (function (data, name) {
+        var rst = [];
+        var tmpMap = {};
+        for (var i = 0; i < data.length; i++) {
+            var obj = data[i];
+            var value = obj[name];
+            if (!isNil(value)) {
+                // flatten
+                if (!isArray(value)) {
+                    value = [value];
+                }
+                for (var j = 0; j < value.length; j++) {
+                    var val = value[j];
+                    // unique
+                    if (!tmpMap[val]) {
+                        rst.push(val);
+                        tmpMap[val] = true;
+                    }
+                }
+            }
+        }
+        return rst;
+    });
+
+    function head(o) {
+        if (isArrayLike(o)) {
+            return o[0];
+        }
+        return undefined;
+    }
+
+    function last(o) {
+        if (isArrayLike(o)) {
+            var arr = o;
+            return arr[arr.length - 1];
+        }
+        return undefined;
+    }
+
+    function startsWith(arr, e) {
+        return (isArray(arr) || isString(arr)) ? arr[0] === e : false;
+    }
+
+    function endsWith(arr, e) {
+        return (isArray(arr) || isString(arr)) ? arr[arr.length - 1] === e : false;
+    }
+
+    /**
+     * 只要有一个不满足条件就返回 false
+     * @param arr
+     * @param func
+     */
+    var every = function (arr, func) {
+        for (var i = 0; i < arr.length; i++) {
+            if (!func(arr[i], i))
+                return false;
+        }
+        return true;
+    };
+
+    /**
+     * 只要有一个满足条件就返回 true
+     * @param arr
+     * @param func
+     */
+    var some = function (arr, func) {
+        for (var i = 0; i < arr.length; i++) {
+            if (func(arr[i], i))
+                return true;
+        }
+        return false;
+    };
+
+    var hasOwnProperty = Object.prototype.hasOwnProperty;
+    function groupBy(data, condition) {
+        if (!condition || !isArray(data)) {
+            return {};
+        }
+        var result = {};
+        // 兼容方法和 字符串的写法
+        var predicate = isFunction(condition) ? condition : function (item) { return item[condition]; };
+        var key;
+        for (var i = 0; i < data.length; i++) {
+            var item = data[i];
+            key = predicate(item);
+            if (hasOwnProperty.call(result, key)) {
+                result[key].push(item);
+            }
+            else {
+                result[key] = [item];
+            }
+        }
+        return result;
+    }
+
+    /**
+     * 将数据分组成 map
+     * @param data
+     * @param condition
+     */
+    function groupToMap(data, condition) {
+        if (!condition) {
+            return {
+                0: data,
+            };
+        }
+        if (!isFunction(condition)) {
+            // 如果是字符串,则按照 a*b 风格成数组
+            var paramscondition_1 = isArray(condition) ? condition : condition.replace(/\s+/g, '').split('*');
+            condition = function (row) {
+                var unique = '_'; // 避免出现数字作为Key的情况,会进行按照数字的排序
+                // 根据字段列表的值,拼接成 key
+                for (var i = 0, l = paramscondition_1.length; i < l; i++) {
+                    unique += row[paramscondition_1[i]] && row[paramscondition_1[i]].toString();
+                }
+                return unique;
+            };
+        }
+        return groupBy(data, condition);
+    }
+
+    var group = (function (data, condition) {
+        if (!condition) {
+            // 没有条件,则自身改成数组
+            return [data];
+        }
+        var groups = groupToMap(data, condition);
+        var array = [];
+        for (var i in groups) {
+            array.push(groups[i]);
+        }
+        return array;
+    });
+
+    /**
+     * 获取封装的事件
+     * @protected
+     * @param  {Object} obj   对象
+     * @param  {String} action 事件名称
+     * @return {Function}        返回事件处理函数
+     */
+    function getWrapBehavior(obj, action) {
+        return obj['_wrap_' + action];
+    }
+
+    /**
+     * 封装事件,便于使用上下文this,和便于解除事件时使用
+     * @protected
+     * @param  {Object} obj   对象
+     * @param  {String} action 事件名称
+     * @return {Function}        返回事件处理函数
+     */
+    function wrapBehavior(obj, action) {
+        if (obj['_wrap_' + action]) {
+            return obj['_wrap_' + action];
+        }
+        var method = function (e) {
+            obj[action](e);
+        };
+        obj['_wrap_' + action] = method;
+        return method;
+    }
+
+    var numColorCache = {};
+    function numberToColor(num) {
+        // 增加缓存
+        var color = numColorCache[num];
+        if (!color) {
+            var str = num.toString(16);
+            for (var i = str.length; i < 6; i++) {
+                str = '0' + str;
+            }
+            color = '#' + str;
+            numColorCache[num] = color;
+        }
+        return color;
+    }
+
+    function parseRadius(radius) {
+        var r1 = 0, r2 = 0, r3 = 0, r4 = 0;
+        if (isArray(radius)) {
+            if (radius.length === 1) {
+                r1 = r2 = r3 = r4 = radius[0];
+            }
+            else if (radius.length === 2) {
+                r1 = r3 = radius[0];
+                r2 = r4 = radius[1];
+            }
+            else if (radius.length === 3) {
+                r1 = radius[0];
+                r2 = r4 = radius[1];
+                r3 = radius[2];
+            }
+            else {
+                r1 = radius[0];
+                r2 = radius[1];
+                r3 = radius[2];
+                r4 = radius[3];
+            }
+        }
+        else {
+            r1 = r2 = r3 = r4 = radius;
+        }
+        return {
+            r1: r1,
+            r2: r2,
+            r3: r3,
+            r4: r4
+        };
+    }
+
+    var clamp = function (a, min, max) {
+        if (a < min) {
+            return min;
+        }
+        else if (a > max) {
+            return max;
+        }
+        return a;
+    };
+
+    var fixedBase = function (v, base) {
+        var str = base.toString();
+        var index = str.indexOf('.');
+        if (index === -1) {
+            return Math.round(v);
+        }
+        var length = str.substr(index + 1).length;
+        if (length > 20) {
+            length = 20;
+        }
+        return parseFloat(v.toFixed(length));
+    };
+
+    /**
+     * 判断是否数字
+     * @return {Boolean} 是否数字
+     */
+    var isNumber = function (value) {
+        return isType(value, 'Number');
+    };
+
+    var isDecimal = function (num) {
+        return isNumber(num) && num % 1 !== 0;
+    };
+
+    var isEven = function (num) {
+        return isNumber(num) && num % 2 === 0;
+    };
+
+    var isInteger = Number.isInteger ? Number.isInteger : function (num) {
+        return isNumber(num) && num % 1 === 0;
+    };
+
+    var isNegative = function (num) {
+        return isNumber(num) && num < 0;
+    };
+
+    var PRECISION = 0.00001; // numbers less than this is considered as 0
+    function isNumberEqual(a, b, precision) {
+        if (precision === void 0) { precision = PRECISION; }
+        return Math.abs((a - b)) < precision;
+    }
+
+    var isOdd = function (num) {
+        return isNumber(num) && num % 2 !== 0;
+    };
+
+    var isPositive = function (num) {
+        return isNumber(num) && num > 0;
+    };
+
+    /**
+     * @param {Array} arr The array to iterate over.
+     * @param {Function} [fn] The iteratee invoked per element.
+     * @return {*} Returns the maximum value.
+     * @example
+     *
+     * var objects = [{ 'n': 1 }, { 'n': 2 }];
+     *
+     * maxBy(objects, function(o) { return o.n; });
+     * // => { 'n': 2 }
+     *
+     * maxBy(objects, 'n');
+     * // => { 'n': 2 }
+     */
+    var maxBy = (function (arr, fn) {
+        if (!isArray(arr)) {
+            return undefined;
+        }
+        var maxItem;
+        var max = -Infinity;
+        for (var i = 0; i < arr.length; i++) {
+            var item = arr[i];
+            var v = isFunction(fn) ? fn(item) : item[fn];
+            if (v > max) {
+                maxItem = item;
+                max = v;
+            }
+        }
+        return maxItem;
+    });
+
+    /**
+     * @param {Array} arr The array to iterate over.
+     * @param {Function} [fn] The iteratee invoked per element.
+     * @return {*} Returns the minimum value.
+     * @example
+     *
+     * var objects = [{ 'n': 1 }, { 'n': 2 }];
+     *
+     * minBy(objects, function(o) { return o.n; });
+     * // => { 'n': 1 }
+     *
+     * minBy(objects, 'n');
+     * // => { 'n': 1 }
+     */
+    var minBy = (function (arr, fn) {
+        if (!isArray(arr)) {
+            return undefined;
+        }
+        var minItem;
+        var min = Infinity;
+        for (var i = 0; i < arr.length; i++) {
+            var item = arr[i];
+            var v = isFunction(fn) ? fn(item) : item[fn];
+            if (v < min) {
+                minItem = item;
+                min = v;
+            }
+        }
+        return minItem;
+    });
+
+    var mod = function (n, m) {
+        return ((n % m) + m) % m;
+    };
+
+    var DEGREE = 180 / Math.PI;
+    var toDegree = function (radian) {
+        return DEGREE * radian;
+    };
+
+    var RADIAN = Math.PI / 180;
+    var toRadian = function (degree) {
+        return RADIAN * degree;
+    };
+
+    var has = (function (obj, key) { return obj.hasOwnProperty(key); });
+
+    // @ts-ignore
+    var values = Object.values ? function (obj) { return Object.values(obj); } : function (obj) {
+        var result = [];
+        each(obj, function (value, key) {
+            if (!(isFunction(obj) && key === 'prototype')) {
+                result.push(value);
+            }
+        });
+        return result;
+    };
+
+    var hasValue = (function (obj, value) { return contains(values(obj), value); });
+
+    var toString$1 = (function (value) {
+        if (isNil(value))
+            return '';
+        return value.toString();
+    });
+
+    var lowerCase = function (str) {
+        return toString$1(str).toLowerCase();
+    };
+
+    var lowerFirst = function (value) {
+        var str = toString$1(value);
+        return str.charAt(0).toLowerCase() + str.substring(1);
+    };
+
+    function substitute(str, o) {
+        if (!str || !o) {
+            return str;
+        }
+        return str.replace(/\\?\{([^{}]+)\}/g, function (match, name) {
+            if (match.charAt(0) === '\\') {
+                return match.slice(1);
+            }
+            return (o[name] === undefined) ? '' : o[name];
+        });
+    }
+
+    var upperCase = function (str) {
+        return toString$1(str).toUpperCase();
+    };
+
+    var upperFirst = function (value) {
+        var str = toString$1(value);
+        return str.charAt(0).toUpperCase() + str.substring(1);
+    };
+
+    var toString$2 = {}.toString;
+    var getType = function (value) {
+        return toString$2.call(value).replace(/^\[object /, '').replace(/]$/, '');
+    };
+
+    /**
+     * 是否是参数类型
+     *
+     * @param {Object} value 测试的值
+     * @return {Boolean}
+     */
+    var isArguments = function (value) {
+        return isType(value, 'Arguments');
+    };
+
+    /**
+     * 是否是布尔类型
+     *
+     * @param {Object} value 测试的值
+     * @return {Boolean}
+     */
+    var isBoolean = function (value) {
+        return isType(value, 'Boolean');
+    };
+
+    var isDate = function (value) {
+        return isType(value, 'Date');
+    };
+
+    /**
+     * 是否是参数类型
+     *
+     * @param {Object} value 测试的值
+     * @return {Boolean}
+     */
+    var isError = function (value) {
+        return isType(value, 'Error');
+    };
+
+    /**
+     * 判断是否为有限数
+     * @return {Boolean}
+     */
+    function _isFinite (value) {
+        return isNumber(value) && isFinite(value);
+    }
+
+    var isNull = function (value) {
+        return value === null;
+    };
+
+    var objectProto = Object.prototype;
+    var isPrototype = function (value) {
+        var Ctor = value && value.constructor;
+        var proto = (typeof Ctor === 'function' && Ctor.prototype) || objectProto;
+        return value === proto;
+    };
+
+    var isRegExp = function (str) {
+        return isType(str, 'RegExp');
+    };
+
+    var isUndefined = function (value) {
+        return value === undefined;
+    };
+
+    /**
+     * 判断是否HTML元素
+     * @return {Boolean} 是否HTML元素
+     */
+    var isElement = function (o) {
+        return o instanceof Element || o instanceof HTMLDocument;
+    };
+
+    function requestAnimationFrame(fn) {
+        var method = window.requestAnimationFrame ||
+            window.webkitRequestAnimationFrame ||
+            // @ts-ignore
+            window.mozRequestAnimationFrame ||
+            // @ts-ignore
+            window.msRequestAnimationFrame ||
+            function (f) {
+                return setTimeout(f, 16);
+            };
+        return method(fn);
+    }
+
+    function cancelAnimationFrame(handler) {
+        var method = window.cancelAnimationFrame ||
+            window.webkitCancelAnimationFrame ||
+            // @ts-ignore
+            window.mozCancelAnimationFrame ||
+            // @ts-ignore
+            window.msCancelAnimationFrame ||
+            clearTimeout;
+        method(handler);
+    }
+
+    // FIXME: Mutable param should be forbidden in static lang.
+    function _mix(dist, obj) {
+        for (var key in obj) {
+            if (obj.hasOwnProperty(key) && key !== 'constructor' && obj[key] !== undefined) {
+                dist[key] = obj[key];
+            }
+        }
+    }
+    function mix(dist, src1, src2, src3) {
+        if (src1)
+            _mix(dist, src1);
+        if (src2)
+            _mix(dist, src2);
+        if (src3)
+            _mix(dist, src3);
+        return dist;
+    }
+
+    var augment = function () {
+        var args = [];
+        for (var _i = 0; _i < arguments.length; _i++) {
+            args[_i] = arguments[_i];
+        }
+        var c = args[0];
+        for (var i = 1; i < args.length; i++) {
+            var obj = args[i];
+            if (isFunction(obj)) {
+                obj = obj.prototype;
+            }
+            mix(c.prototype, obj);
+        }
+    };
+
+    var clone = function (obj) {
+        if (typeof obj !== 'object' || obj === null) {
+            return obj;
+        }
+        var rst;
+        if (isArray(obj)) {
+            rst = [];
+            for (var i = 0, l = obj.length; i < l; i++) {
+                if (typeof obj[i] === 'object' && obj[i] != null) {
+                    rst[i] = clone(obj[i]);
+                }
+                else {
+                    rst[i] = obj[i];
+                }
+            }
+        }
+        else {
+            rst = {};
+            for (var k in obj) {
+                if (typeof obj[k] === 'object' && obj[k] != null) {
+                    rst[k] = clone(obj[k]);
+                }
+                else {
+                    rst[k] = obj[k];
+                }
+            }
+        }
+        return rst;
+    };
+
+    function debounce(func, wait, immediate) {
+        var timeout;
+        return function () {
+            var context = this, args = arguments;
+            var later = function () {
+                timeout = null;
+                if (!immediate) {
+                    func.apply(context, args);
+                }
+            };
+            var callNow = immediate && !timeout;
+            clearTimeout(timeout);
+            timeout = setTimeout(later, wait);
+            if (callNow) {
+                func.apply(context, args);
+            }
+        };
+    }
+
+    /**
+     * _.memoize(calColor);
+     * _.memoize(calColor, (...args) => args[0]);
+     * @param f
+     * @param resolver
+     */
+    var memoize = (function (f, resolver) {
+        if (!isFunction(f)) {
+            throw new TypeError('Expected a function');
+        }
+        var memoized = function () {
+            var args = [];
+            for (var _i = 0; _i < arguments.length; _i++) {
+                args[_i] = arguments[_i];
+            }
+            // 使用方法构造 key,如果不存在 resolver,则直接取第一个参数作为 key
+            var key = resolver ? resolver.apply(this, args) : args[0];
+            var cache = memoized.cache;
+            if (cache.has(key)) {
+                return cache.get(key);
+            }
+            var result = f.apply(this, args);
+            // 缓存起来
+            cache.set(key, result);
+            return result;
+        };
+        memoized.cache = new Map();
+        return memoized;
+    });
+
+    var MAX_MIX_LEVEL = 5;
+    function _deepMix(dist, src, level, maxLevel) {
+        level = level || 0;
+        maxLevel = maxLevel || MAX_MIX_LEVEL;
+        for (var key in src) {
+            if (src.hasOwnProperty(key)) {
+                var value = src[key];
+                if (value !== null && isPlainObject(value)) {
+                    if (!isPlainObject(dist[key])) {
+                        dist[key] = {};
+                    }
+                    if (level < maxLevel) {
+                        _deepMix(dist[key], value, level + 1, maxLevel);
+                    }
+                    else {
+                        dist[key] = src[key];
+                    }
+                }
+                else if (isArray(value)) {
+                    dist[key] = [];
+                    dist[key] = dist[key].concat(value);
+                }
+                else if (value !== undefined) {
+                    dist[key] = value;
+                }
+            }
+        }
+    }
+    // todo 重写
+    var deepMix = function (rst) {
+        var args = [];
+        for (var _i = 1; _i < arguments.length; _i++) {
+            args[_i - 1] = arguments[_i];
+        }
+        for (var i = 0; i < args.length; i += 1) {
+            _deepMix(rst, args[i]);
+        }
+        return rst;
+    };
+
+    var extend = function (subclass, superclass, overrides, staticOverrides) {
+        // 如果只提供父类构造函数,则自动生成子类构造函数
+        if (!isFunction(superclass)) {
+            overrides = superclass;
+            superclass = subclass;
+            subclass = function () { };
+        }
+        var create = Object.create ?
+            function (proto, c) {
+                return Object.create(proto, {
+                    constructor: {
+                        value: c
+                    }
+                });
+            } :
+            function (proto, c) {
+                function Tmp() { }
+                Tmp.prototype = proto;
+                var o = new Tmp();
+                o.constructor = c;
+                return o;
+            };
+        var superObj = create(superclass.prototype, subclass); // new superclass(),//实例化父类作为子类的prototype
+        subclass.prototype = mix(superObj, subclass.prototype); // 指定子类的prototype
+        subclass.superclass = create(superclass.prototype, superclass);
+        mix(superObj, overrides);
+        mix(subclass, staticOverrides);
+        return subclass;
+    };
+
+    var indexOf$1 = function (arr, obj) {
+        if (!isArrayLike(arr)) {
+            return -1;
+        }
+        var m = Array.prototype.indexOf;
+        if (m) {
+            return m.call(arr, obj);
+        }
+        var index = -1;
+        for (var i = 0; i < arr.length; i++) {
+            if (arr[i] === obj) {
+                index = i;
+                break;
+            }
+        }
+        return index;
+    };
+
+    var hasOwnProperty$1 = Object.prototype.hasOwnProperty;
+    function isEmpty(value) {
+        /**
+         * isEmpty(null) => true
+         * isEmpty() => true
+         * isEmpty(true) => true
+         * isEmpty(1) => true
+         * isEmpty([1, 2, 3]) => false
+         * isEmpty('abc') => false
+         * isEmpty({ a: 1 }) => false
+         */
+        if (isNil(value)) {
+            return true;
+        }
+        if (isArrayLike(value)) {
+            return !value.length;
+        }
+        var type = getType(value);
+        if (type === 'Map' || type === 'Set') {
+            return !value.size;
+        }
+        if (isPrototype(value)) {
+            return !Object.keys(value).length;
+        }
+        for (var key in value) {
+            if (hasOwnProperty$1.call(value, key)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    var isEqual = function (value, other) {
+        if (value === other) {
+            return true;
+        }
+        if (!value || !other) {
+            return false;
+        }
+        if (isString(value) || isString(other)) {
+            return false;
+        }
+        if (isArrayLike(value) || isArrayLike(other)) {
+            if (value.length !== other.length) {
+                return false;
+            }
+            var rst = true;
+            for (var i = 0; i < value.length; i++) {
+                rst = isEqual(value[i], other[i]);
+                if (!rst) {
+                    break;
+                }
+            }
+            return rst;
+        }
+        if (isObjectLike(value) || isObjectLike(other)) {
+            var valueKeys = Object.keys(value);
+            var otherKeys = Object.keys(other);
+            if (valueKeys.length !== otherKeys.length) {
+                return false;
+            }
+            var rst = true;
+            for (var i = 0; i < valueKeys.length; i++) {
+                rst = isEqual(value[valueKeys[i]], other[valueKeys[i]]);
+                if (!rst) {
+                    break;
+                }
+            }
+            return rst;
+        }
+        return false;
+    };
+
+    /**
+     * @param {*} value The value to compare.
+     * @param {*} other The other value to compare.
+     * @param {Function} [fn] The function to customize comparisons.
+     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
+     * @example
+     *
+     * function isGreeting(value) {
+     *   return /^h(?:i|ello)$/.test(value);
+     * }
+     *
+     * function customizer(objValue, othValue) {
+     *   if (isGreeting(objValue) && isGreeting(othValue)) {
+     *     return true;
+     *   }
+     * }
+     *
+     * var array = ['hello', 'goodbye'];
+     * var other = ['hi', 'goodbye'];
+     *
+     * isEqualWith(array, other, customizer);  // => true
+     */
+    var isEqualWith = (function (value, other, fn) {
+        if (!isFunction(fn)) {
+            return isEqual(value, other);
+        }
+        return !!fn(value, other);
+    });
+
+    var map = function (arr, func) {
+        if (!isArrayLike(arr)) {
+            // @ts-ignore
+            return arr;
+        }
+        var result = [];
+        for (var index = 0; index < arr.length; index++) {
+            var value = arr[index];
+            result.push(func(value, index));
+        }
+        return result;
+    };
+
+    var identity = function (v) { return v; };
+    var mapValues = (function (object, func) {
+        if (func === void 0) { func = identity; }
+        var r = {};
+        if (isObject(object) && !isNil(object)) {
+            Object.keys(object).forEach(function (key) {
+                // @ts-ignore
+                r[key] = func(object[key], key);
+            });
+        }
+        return r;
+    });
+
+    /**
+     * https://github.com/developit/dlv/blob/master/index.js
+     * @param obj
+     * @param key
+     * @param defaultValue
+     */
+    var get = (function (obj, key, defaultValue) {
+        var p = 0;
+        var keyArr = isString(key) ? key.split('.') : key;
+        while (obj && p < keyArr.length) {
+            obj = obj[keyArr[p++]];
+        }
+        return (obj === undefined || p < keyArr.length) ? defaultValue : obj;
+    });
+
+    /**
+     * https://github.com/developit/dlv/blob/master/index.js
+     * @param obj
+     * @param path
+     * @param value
+     */
+    var set = (function (obj, path, value) {
+        var o = obj;
+        var keyArr = isString(path) ? path.split('.') : path;
+        keyArr.forEach(function (key, idx) {
+            // 不是最后一个
+            if (idx < keyArr.length - 1) {
+                if (!isObject(o[key])) {
+                    o[key] = isNumber(keyArr[idx + 1]) ? [] : {};
+                }
+                o = o[key];
+            }
+            else {
+                o[key] = value;
+            }
+        });
+        return obj;
+    });
+
+    var hasOwnProperty$2 = Object.prototype.hasOwnProperty;
+    var pick = (function (object, keys) {
+        if (object === null || !isPlainObject(object)) {
+            return {};
+        }
+        var result = {};
+        each(keys, function (key) {
+            if (hasOwnProperty$2.call(object, key)) {
+                result[key] = object[key];
+            }
+        });
+        return result;
+    });
+
+    var omit = (function (obj, keys) {
+        return reduce(obj, function (r, curr, key) {
+            if (!keys.includes(key)) {
+                r[key] = curr;
+            }
+            return r;
+        }, {});
+    });
+
+    var throttle = (function (func, wait, options) {
+        var timeout, context, args, result;
+        var previous = 0;
+        if (!options)
+            options = {};
+        var later = function () {
+            previous = options.leading === false ? 0 : Date.now();
+            timeout = null;
+            result = func.apply(context, args);
+            if (!timeout)
+                context = args = null;
+        };
+        var throttled = function () {
+            var now = Date.now();
+            if (!previous && options.leading === false)
+                previous = now;
+            var remaining = wait - (now - previous);
+            context = this;
+            args = arguments;
+            if (remaining <= 0 || remaining > wait) {
+                if (timeout) {
+                    clearTimeout(timeout);
+                    timeout = null;
+                }
+                previous = now;
+                result = func.apply(context, args);
+                if (!timeout)
+                    context = args = null;
+            }
+            else if (!timeout && options.trailing !== false) {
+                timeout = setTimeout(later, remaining);
+            }
+            return result;
+        };
+        throttled.cancel = function () {
+            clearTimeout(timeout);
+            previous = 0;
+            timeout = context = args = null;
+        };
+        return throttled;
+    });
+
+    var toArray = (function (value) {
+        return isArrayLike(value) ? Array.prototype.slice.call(value) : [];
+    });
+
+    var map$1 = {};
+    var uniqueId = (function (prefix) {
+        prefix = prefix || 'g';
+        if (!map$1[prefix]) {
+            map$1[prefix] = 1;
+        }
+        else {
+            map$1[prefix] += 1;
+        }
+        return prefix + map$1[prefix];
+    });
+
+    var noop = (function () { });
+
+    var identity$1 = (function (v) { return v; });
+
+    function size(o) {
+        if (isNil(o)) {
+            return 0;
+        }
+        if (isArrayLike(o)) {
+            return o.length;
+        }
+        return Object.keys(o).length;
+    }
+
+    /*! *****************************************************************************
+    Copyright (c) Microsoft Corporation.
+
+    Permission to use, copy, modify, and/or distribute this software for any
+    purpose with or without fee is hereby granted.
+
+    THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+    REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+    AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+    INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+    LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+    OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+    PERFORMANCE OF THIS SOFTWARE.
+    ***************************************************************************** */
+    /* global Reflect, Promise */
+
+    var extendStatics = function(d, b) {
+        extendStatics = Object.setPrototypeOf ||
+            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+            function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
+        return extendStatics(d, b);
+    };
+
+    function __extends(d, b) {
+        if (typeof b !== "function" && b !== null)
+            throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
+        extendStatics(d, b);
+        function __() { this.constructor = d; }
+        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+    }
+
+    /** @deprecated */
+    function __spreadArrays() {
+        for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
+        for (var r = Array(s), k = 0, i = 0; i < il; i++)
+            for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
+                r[k] = a[j];
+        return r;
+    }
+
+    function __spreadArray(to, from, pack) {
+        if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
+            if (ar || !(i in from)) {
+                if (!ar) ar = Array.prototype.slice.call(from, 0, i);
+                ar[i] = from[i];
+            }
+        }
+        return to.concat(ar || Array.prototype.slice.call(from));
+    }
+
+    var ctx;
+    /**
+     * 计算文本的宽度
+     */
+    var measureTextWidth = memoize(function (text, font) {
+        if (font === void 0) { font = {}; }
+        var fontSize = font.fontSize, fontFamily = font.fontFamily, fontWeight = font.fontWeight, fontStyle = font.fontStyle, fontVariant = font.fontVariant;
+        if (!ctx) {
+            ctx = document.createElement('canvas').getContext('2d');
+        }
+        ctx.font = [fontStyle, fontVariant, fontWeight, fontSize + "px", fontFamily].join(' ');
+        return ctx.measureText(isString(text) ? text : '').width;
+    }, function (text, font) {
+        if (font === void 0) { font = {}; }
+        return __spreadArrays([text], values(font)).join('');
+    });
+
+    /**
+     * 获取文本的 ... 文本。
+     * 算法(减少每次 measureText 的长度,measureText 的性能跟字符串时间相关):
+     * 1. 先通过 STEP 逐步计算,找到最后一个小于 maxWidth 的字符串
+     * 2. 然后对最后这个字符串二分计算
+     * @param text 需要计算的文本, 由于历史原因 除了支持string,还支持空值,number和数组等
+     * @param maxWidth 最大宽度
+     * @param font 字体
+     * @param str 要替换的文本
+     */
+    var getEllipsisText = (function (text, maxWidth, font, str) {
+        if (str === void 0) { str = '...'; }
+        var STEP = 16; // 每次 16,调参工程师
+        var PLACEHOLDER_WIDTH = measureTextWidth(str, font);
+        var leftText = !isString(text) ? toString$1(text) : text;
+        var leftWidth = maxWidth;
+        var r = []; // 最终的分段字符串
+        var currentText;
+        var currentWidth;
+        if (measureTextWidth(text, font) <= maxWidth) {
+            return text;
+        }
+        // 首先通过 step 计算,找出最大的未超出长度的
+        // eslint-disable-next-line no-constant-condition
+        while (true) {
+            // 更新字符串
+            currentText = leftText.substr(0, STEP);
+            // 计算宽度
+            currentWidth = measureTextWidth(currentText, font);
+            // 超出剩余宽度,则停止
+            if (currentWidth + PLACEHOLDER_WIDTH > leftWidth) {
+                if (currentWidth > leftWidth) {
+                    break;
+                }
+            }
+            r.push(currentText);
+            // 没有超出,则计算剩余宽度
+            leftWidth -= currentWidth;
+            leftText = leftText.substr(STEP);
+            // 字符串整体没有超出
+            if (!leftText) {
+                return r.join('');
+            }
+        }
+        // 最下的最后一个 STEP,使用 1 递增(用二分效果更高)
+        // eslint-disable-next-line no-constant-condition
+        while (true) {
+            // 更新字符串
+            currentText = leftText.substr(0, 1);
+            // 计算宽度
+            currentWidth = measureTextWidth(currentText, font);
+            // 超出剩余宽度,则停止
+            if (currentWidth + PLACEHOLDER_WIDTH > leftWidth) {
+                break;
+            }
+            r.push(currentText);
+            // 没有超出,则计算剩余宽度
+            leftWidth -= currentWidth;
+            leftText = leftText.substr(1);
+            if (!leftText) {
+                return r.join('');
+            }
+        }
+        return "" + r.join('') + str;
+    });
+
+    /**
+     * k-v 存储
+     */
+    var default_1 = /** @class */ (function () {
+        function default_1() {
+            this.map = {};
+        }
+        default_1.prototype.has = function (key) {
+            return this.map[key] !== undefined;
+        };
+        default_1.prototype.get = function (key, def) {
+            var v = this.map[key];
+            return v === undefined ? def : v;
+        };
+        default_1.prototype.set = function (key, value) {
+            this.map[key] = value;
+        };
+        default_1.prototype.clear = function () {
+            this.map = {};
+        };
+        default_1.prototype.delete = function (key) {
+            delete this.map[key];
+        };
+        default_1.prototype.size = function () {
+            return Object.keys(this.map).length;
+        };
+        return default_1;
+    }());
+
+    // array
+
+    var esm = /*#__PURE__*/Object.freeze({
+        __proto__: null,
+        contains: contains,
+        includes: contains,
+        difference: difference,
+        find: find,
+        findIndex: findIndex,
+        firstValue: firstValue,
+        flatten: flatten,
+        flattenDeep: flattenDeep,
+        getRange: getRange,
+        pull: pull,
+        pullAt: pullAt,
+        reduce: reduce,
+        remove: remove,
+        sortBy: sortBy,
+        union: union,
+        uniq: uniq,
+        valuesOfKey: valuesOfKey,
+        head: head,
+        last: last,
+        startsWith: startsWith,
+        endsWith: endsWith,
+        filter: filter,
+        every: every,
+        some: some,
+        group: group,
+        groupBy: groupBy,
+        groupToMap: groupToMap,
+        getWrapBehavior: getWrapBehavior,
+        wrapBehavior: wrapBehavior,
+        number2color: numberToColor,
+        parseRadius: parseRadius,
+        clamp: clamp,
+        fixedBase: fixedBase,
+        isDecimal: isDecimal,
+        isEven: isEven,
+        isInteger: isInteger,
+        isNegative: isNegative,
+        isNumberEqual: isNumberEqual,
+        isOdd: isOdd,
+        isPositive: isPositive,
+        max: getMax,
+        maxBy: maxBy,
+        min: getMin,
+        minBy: minBy,
+        mod: mod,
+        toDegree: toDegree,
+        toInteger: parseInt,
+        toRadian: toRadian,
+        forIn: each,
+        has: has,
+        hasKey: has,
+        hasValue: hasValue,
+        keys: keys,
+        isMatch: isMatch,
+        values: values,
+        lowerCase: lowerCase,
+        lowerFirst: lowerFirst,
+        substitute: substitute,
+        upperCase: upperCase,
+        upperFirst: upperFirst,
+        getType: getType,
+        isArguments: isArguments,
+        isArray: isArray,
+        isArrayLike: isArrayLike,
+        isBoolean: isBoolean,
+        isDate: isDate,
+        isError: isError,
+        isFunction: isFunction,
+        isFinite: _isFinite,
+        isNil: isNil,
+        isNull: isNull,
+        isNumber: isNumber,
+        isObject: isObject,
+        isObjectLike: isObjectLike,
+        isPlainObject: isPlainObject,
+        isPrototype: isPrototype,
+        isRegExp: isRegExp,
+        isString: isString,
+        isType: isType,
+        isUndefined: isUndefined,
+        isElement: isElement,
+        requestAnimationFrame: requestAnimationFrame,
+        clearAnimationFrame: cancelAnimationFrame,
+        augment: augment,
+        clone: clone,
+        debounce: debounce,
+        memoize: memoize,
+        deepMix: deepMix,
+        each: each,
+        extend: extend,
+        indexOf: indexOf$1,
+        isEmpty: isEmpty,
+        isEqual: isEqual,
+        isEqualWith: isEqualWith,
+        map: map,
+        mapValues: mapValues,
+        mix: mix,
+        assign: mix,
+        get: get,
+        set: set,
+        pick: pick,
+        omit: omit,
+        throttle: throttle,
+        toArray: toArray,
+        toString: toString$1,
+        uniqueId: uniqueId,
+        noop: noop,
+        identity: identity$1,
+        size: size,
+        measureTextWidth: measureTextWidth,
+        getEllipsisText: getEllipsisText,
+        Cache: default_1
+    });
+
+    function merge(dataArray) {
+      var rst = [];
+
+      for (var i = 0, len = dataArray.length; i < len; i++) {
+        rst = rst.concat(dataArray[i]);
+      }
+
+      return rst;
+    }
+
+    function values$1(data, name) {
+      var rst = [];
+      var tmpMap = {};
+
+      for (var i = 0, len = data.length; i < len; i++) {
+        var obj = data[i];
+        var value = obj[name];
+
+        if (!isNil(value)) {
+          if (!isArray(value)) {
+            if (!tmpMap[value]) {
+              rst.push(value);
+              tmpMap[value] = true;
+            }
+          } else {
+            each(value, function (val) {
+              if (!tmpMap[val]) {
+                rst.push(val);
+                tmpMap[val] = true;
+              }
+            });
+          }
+        }
+      }
+
+      return rst;
+    }
+
+    function firstValue$1(data, name) {
+      var rst = null;
+
+      for (var i = 0, len = data.length; i < len; i++) {
+        var obj = data[i];
+        var value = obj[name];
+
+        if (!isNil(value)) {
+          if (isArray(value)) {
+            rst = value[0];
+          } else {
+            rst = value;
+          }
+
+          break;
+        }
+      }
+
+      return rst;
+    }
+
+    function groupToMap$1(data, fields) {
+      if (!fields) {
+        return {
+          0: data
+        };
+      }
+
+      var callback = function callback(row) {
+        var unique = '_';
+
+        for (var i = 0, l = fields.length; i < l; i++) {
+          unique += row[fields[i]] && row[fields[i]].toString();
+        }
+
+        return unique;
+      };
+
+      var groups = {};
+
+      for (var i = 0, len = data.length; i < len; i++) {
+        var row = data[i];
+        var key = callback(row);
+
+        if (groups[key]) {
+          groups[key].push(row);
+        } else {
+          groups[key] = [row];
+        }
+      }
+
+      return groups;
+    }
+
+    function group$1(data, fields) {
+      var appendConditions = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
+
+      if (!fields) {
+        return [data];
+      }
+
+      var groups = groupToMap$1(data, fields);
+      var array = [];
+
+      if (fields.length === 1 && appendConditions[fields[0]]) {
+        var _values = appendConditions[fields[0]];
+        each(_values, function (value) {
+          value = '_' + value;
+          array.push(groups[value]);
+        });
+      } else {
+        for (var i in groups) {
+          array.push(groups[i]);
+        }
+      }
+
+      return array;
+    }
+
+    function remove$1(arr, obj) {
+      if (!arr) {
+        return;
+      }
+
+      var index = arr.indexOf(obj);
+
+      if (index !== -1) {
+        arr.splice(index, 1);
+      }
+    }
+
+    function getRange$1(values) {
+      if (!values.length) {
+        return {
+          min: 0,
+          max: 0
+        };
+      }
+
+      var max = Math.max.apply(null, values);
+      var min = Math.min.apply(null, values);
+      return {
+        min,
+        max
+      };
+    }
+
+    var array = /*#__PURE__*/Object.freeze({
+        __proto__: null,
+        merge: merge,
+        values: values$1,
+        firstValue: firstValue$1,
+        group: group$1,
+        groupToMap: groupToMap$1,
+        remove: remove$1,
+        getRange: getRange$1
+    });
+
+    /**
+     * Detects support for options object argument in addEventListener.
+     * https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Safely_detecting_option_support
+     * @private
+     */
+    var supportsEventListenerOptions = function () {
+      var supports = false;
+
+      try {
+        var options = Object.defineProperty({}, 'passive', {
+          get() {
+            supports = true;
+          }
+
+        });
+        window.addEventListener('e', null, options);
+      } catch (e) {// continue regardless of error
+      }
+
+      return supports;
+    }(); // Default passive to true as expected by Chrome for 'touchstart' and 'touchend' events.
+    // https://github.com/chartjs/Chart.js/issues/4287
+
+
+    var eventListenerOptions = supportsEventListenerOptions ? {
+      passive: true
+    } : false;
+    /* global wx, my */
+    // weixin miniprogram
+
+    var isWx = typeof wx === 'object' && typeof wx.getSystemInfoSync === 'function'; // ant miniprogram
+
+    var isMy = typeof my === 'object' && typeof my.getSystemInfoSync === 'function'; // in node
+
+    var isNode = typeof global && !typeof window; // in browser
+
+    var isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined' && typeof window.sessionStorage !== 'undefined';
+
+    function isCanvasElement(el) {
+      if (!el || typeof el !== 'object') return false;
+
+      if (el.nodeType === 1 && el.nodeName) {
+        // HTMLCanvasElement
+        return true;
+      } // CanvasElement
+
+
+      return !!el.isCanvasElement;
+    }
+
+    function getPixelRatio() {
+      return window && window.devicePixelRatio || 1;
+    }
+
+    function getStyle(el, property) {
+      return el.currentStyle ? el.currentStyle[property] : document.defaultView.getComputedStyle(el, null).getPropertyValue(property);
+    }
+
+    function getWidth(el) {
+      var width = getStyle(el, 'width');
+
+      if (width === 'auto') {
+        width = el.offsetWidth;
+      }
+
+      return parseFloat(width);
+    }
+
+    function getHeight(el) {
+      var height = getStyle(el, 'height');
+
+      if (height === 'auto') {
+        height = el.offsetHeight;
+      }
+
+      return parseFloat(height);
+    }
+
+    function getDomById(id) {
+      if (!id) {
+        return null;
+      }
+
+      return document.getElementById(id);
+    }
+
+    function getRelativePosition(point, canvas) {
+      var canvasDom = canvas.get('el');
+      if (!canvasDom) return point;
+      var {
+        top,
+        right,
+        bottom,
+        left
+      } = canvasDom.getBoundingClientRect();
+      var paddingLeft = parseFloat(getStyle(canvasDom, 'padding-left'));
+      var paddingTop = parseFloat(getStyle(canvasDom, 'padding-top'));
+      var paddingRight = parseFloat(getStyle(canvasDom, 'padding-right'));
+      var paddingBottom = parseFloat(getStyle(canvasDom, 'padding-bottom'));
+      var width = right - left - paddingLeft - paddingRight;
+      var height = bottom - top - paddingTop - paddingBottom;
+      var pixelRatio = canvas.get('pixelRatio');
+      var mouseX = (point.x - left - paddingLeft) / width * canvasDom.width / pixelRatio;
+      var mouseY = (point.y - top - paddingTop) / height * canvasDom.height / pixelRatio;
+      return {
+        x: mouseX,
+        y: mouseY
+      };
+    }
+
+    function addEventListener(source, type, listener) {
+      source.addEventListener(type, listener, eventListenerOptions);
+    }
+
+    function removeEventListener(source, type, listener) {
+      source.removeEventListener(type, listener, eventListenerOptions);
+    }
+
+    function createEventObj(type, chart, x, y, nativeEvent) {
+      return {
+        type,
+        chart,
+        native: nativeEvent || null,
+        x: x !== undefined ? x : null,
+        y: y !== undefined ? y : null
+      };
+    }
+
+    function createEvent(event, chart) {
+      var type = event.type;
+      var clientPoint; // 说明是touch相关事件
+
+      if (event.touches) {
+        // https://developer.mozilla.org/zh-CN/docs/Web/API/TouchEvent/changedTouches
+        // 这里直接拿changedTouches就可以了,不管是touchstart, touchmove, touchend changedTouches 都是有的
+        // 为了以防万一,做个空判断
+        var touch = event.changedTouches[0] || {}; // x, y: 相对canvas原点的位置,clientX, clientY 相对于可视窗口的位置
+
+        var {
+          x,
+          y,
+          clientX,
+          clientY
+        } = touch; // 小程序环境会有x,y,这里就直接返回
+
+        if (x && y) {
+          return createEventObj(type, chart, x, y, event);
+        }
+
+        clientPoint = {
+          x: clientX,
+          y: clientY
+        };
+      } else {
+        // mouse相关事件
+        clientPoint = {
+          x: event.clientX,
+          y: event.clientY
+        };
+      } // 理论上应该是只有有在浏览器环境才会走到这里
+
+
+      var canvas = chart.get('canvas'); // 通过clientX, clientY 计算x, y
+
+      var point = getRelativePosition(clientPoint, canvas);
+      return createEventObj(type, chart, point.x, point.y, event);
+    }
+
+    function measureText(text, font, ctx) {
+      if (!ctx) {
+        ctx = document.createElement('canvas').getContext('2d');
+      }
+
+      ctx.font = font || '12px sans-serif';
+      return ctx.measureText(text);
+    }
+
+    /**
+     * @fileOverview Utility for F2
+     * @author dxq613 @gmail.com
+     * @author sima.zhang1990@gmail.com
+     */
+
+    function isObjectValueEqual(a, b) {
+      // for vue.js
+      a = Object.assign({}, a);
+      b = Object.assign({}, b);
+      var aProps = Object.getOwnPropertyNames(a);
+      var bProps = Object.getOwnPropertyNames(b);
+
+      if (aProps.length !== bProps.length) {
+        return false;
+      }
+
+      for (var i = 0, len = aProps.length; i < len; i++) {
+        var propName = aProps[i];
+
+        if (a[propName] !== b[propName]) {
+          return false;
+        }
+      }
+
+      return true;
+    }
+
+    function parsePadding(padding) {
+      var top;
+      var right;
+      var bottom;
+      var left;
+
+      if (isNumber(padding) || isString(padding)) {
+        top = bottom = left = right = padding;
+      } else if (isArray(padding)) {
+        top = padding[0];
+        right = !isNil(padding[1]) ? padding[1] : padding[0];
+        bottom = !isNil(padding[2]) ? padding[2] : padding[0];
+        left = !isNil(padding[3]) ? padding[3] : right;
+      }
+
+      return [top, right, bottom, left];
+    }
+
+    function directionEnabled(mode, dir) {
+      if (mode === undefined) {
+        return true;
+      } else if (typeof mode === 'string') {
+        return mode.indexOf(dir) !== -1;
+      }
+
+      return false;
+    }
+
+    function toTimeStamp(value) {
+      if (isString(value)) {
+        if (value.indexOf('T') > 0) {
+          value = new Date(value).getTime();
+        } else {
+          // new Date('2010/01/10') 和 new Date('2010-01-10') 的差别在于:
+          // 如果仅有年月日时,前者是带有时区的: Fri Jan 10 2020 02:40:13 GMT+0800 (中国标准时间)
+          // 后者会格式化成 Sun Jan 10 2010 08:00:00 GMT+0800 (中国标准时间)
+          value = new Date(value.replace(/-/gi, '/')).getTime();
+        }
+      }
+
+      if (isDate(value)) {
+        value = value.getTime();
+      }
+
+      return value;
+    }
+
+    var Util = /*#__PURE__*/Object.freeze({
+        __proto__: null,
+        Array: array,
+        upperFirst: upperFirst,
+        lowerFirst: lowerFirst,
+        isString: isString,
+        isNumber: isNumber,
+        isBoolean: isBoolean,
+        isFunction: isFunction,
+        isDate: isDate,
+        isArray: isArray,
+        isNil: isNil,
+        isObject: isObject,
+        isPlainObject: isPlainObject,
+        isEqual: isEqual,
+        deepMix: deepMix,
+        mix: mix,
+        each: each,
+        uniq: uniq,
+        find: find,
+        isObjectValueEqual: isObjectValueEqual,
+        parsePadding: parsePadding,
+        directionEnabled: directionEnabled,
+        toTimeStamp: toTimeStamp,
+        isWx: isWx,
+        isMy: isMy,
+        isNode: isNode,
+        isBrowser: isBrowser,
+        isCanvasElement: isCanvasElement,
+        getPixelRatio: getPixelRatio,
+        getStyle: getStyle,
+        getWidth: getWidth,
+        getHeight: getHeight,
+        getDomById: getDomById,
+        getRelativePosition: getRelativePosition,
+        addEventListener: addEventListener,
+        removeEventListener: removeEventListener,
+        createEvent: createEvent,
+        measureText: measureText
+    });
+
+    /**
+     * @fileOverview default theme
+     * @author dxq613@gail.com
+     */
+    var color1 = '#E8E8E8'; // color of axis-line and axis-grid
+
+    var color2 = '#808080'; // color of axis label
+
+    var defaultAxis = {
+      label: {
+        fill: color2,
+        fontSize: 10
+      },
+      line: {
+        stroke: color1,
+        lineWidth: 1
+      },
+      grid: {
+        type: 'line',
+        stroke: color1,
+        lineWidth: 1,
+        lineDash: [2]
+      },
+      tickLine: null,
+      labelOffset: 7.5
+    };
+    var Theme = {
+      fontFamily: '"Helvetica Neue", "San Francisco", Helvetica, Tahoma, Arial, "PingFang SC", "Hiragino Sans GB", "Heiti SC", "Microsoft YaHei", sans-serif',
+      defaultColor: '#1890FF',
+      pixelRatio: 1,
+      padding: 'auto',
+      appendPadding: 15,
+      colors: ['#1890FF', '#2FC25B', '#FACC14', '#223273', '#8543E0', '#13C2C2', '#3436C7', '#F04864'],
+      shapes: {
+        line: ['line', 'dash'],
+        point: ['circle', 'hollowCircle']
+      },
+      sizes: [4, 10],
+      axis: {
+        common: defaultAxis,
+        // common axis configuration
+        bottom: mix({}, defaultAxis, {
+          grid: null
+        }),
+        left: mix({}, defaultAxis, {
+          line: null
+        }),
+        right: mix({}, defaultAxis, {
+          line: null
+        }),
+        circle: mix({}, defaultAxis, {
+          line: null
+        }),
+        radius: mix({}, defaultAxis, {
+          labelOffset: 4
+        })
+      },
+      shape: {
+        line: {
+          lineWidth: 2,
+          lineJoin: 'round',
+          lineCap: 'round'
+        },
+        point: {
+          lineWidth: 0,
+          size: 3
+        },
+        area: {
+          fillOpacity: 0.1
+        }
+      },
+      _defaultAxis: defaultAxis
+    };
+
+    var Global = {
+      version: '3.7.8',
+      scales: {},
+      widthRatio: {
+        column: 1 / 2,
+        rose: 0.999999,
+        multiplePie: 3 / 4
+      },
+      lineDash: [4, 4]
+    };
+
+    Global.setTheme = function (theme) {
+      deepMix(Global, theme);
+    };
+
+    Global.setTheme(Theme);
+
+    var EVENT_AFTER_INIT = 'afterinit';
+    var EVENT_BEFORE_RENDER = 'beforerender';
+    var EVENT_AFTER_RENDER = 'afterrender';
+    var EVENT_BEFORE_DATA_CHANGE = 'beforedatachange';
+    var EVENT_AFTER_DATA_CHANGE = 'afterdatachange';
+    var EVENT_AFTER_SIZE_CHANGE = '_aftersizechange';
+    var EVENT_AFTER_GEOM_INIT = '_aftergeominit';
+    var EVENT_BEFORE_GEOM_DRAW = 'beforegeomdraw';
+    var EVENT_AFTER_GEOM_DRAW = 'aftergeomdraw';
+    var EVENT_CLEAR = 'clear';
+    var EVENT_CLEAR_INNER = 'clearinner';
+    var EVENT_REPAINT = 'repaint';
+
+    // 实现简单的事件机制
+
+    class EventEmit {
+      constructor() {
+        this.__events = {};
+      }
+
+      on(type, listener) {
+        if (!type || !listener) {
+          return;
+        }
+
+        var events = this.__events[type] || [];
+        events.push(listener);
+        this.__events[type] = events;
+      }
+
+      emit(type, e) {
+        var _this = this;
+
+        if (isObject(type)) {
+          e = type;
+          type = e && e.type;
+        }
+
+        if (!type) {
+          return;
+        }
+
+        var events = this.__events[type];
+
+        if (!events || !events.length) {
+          return;
+        }
+
+        events.forEach(function (listener) {
+          listener.call(_this, e);
+        });
+      }
+
+      off(type, listener) {
+        var __events = this.__events;
+        var events = __events[type];
+
+        if (!events || !events.length) {
+          return;
+        } // 如果没有指定方法,则删除所有项
+
+
+        if (!listener) {
+          delete __events[type];
+          return;
+        } // 删除指定的 listener
+
+
+        for (var i = 0, len = events.length; i < len; i++) {
+          if (events[i] === listener) {
+            events.splice(i, 1);
+            i--;
+          }
+        }
+      }
+
+    }
+
+    /**
+     * @fileOverview Base class of chart and geometry
+     * @author dxq613@gmail.com
+     */
+
+    class Base extends EventEmit {
+      getDefaultCfg() {
+        return {};
+      }
+
+      constructor(cfg) {
+        super();
+        var attrs = {};
+        var defaultCfg = this.getDefaultCfg();
+        this._attrs = attrs;
+        mix(attrs, defaultCfg, cfg);
+      }
+
+      get(name) {
+        return this._attrs[name];
+      }
+
+      set(name, value) {
+        this._attrs[name] = value;
+      }
+
+      destroy() {
+        this._attrs = {};
+        this.destroyed = true;
+      }
+
+    }
+
+    class Plot {
+      constructor(cfg) {
+        mix(this, cfg);
+
+        this._init();
+      }
+
+      _init() {
+        var self = this;
+        var start = self.start;
+        var end = self.end;
+        var xMin = Math.min(start.x, end.x);
+        var xMax = Math.max(start.x, end.x);
+        var yMin = Math.min(start.y, end.y);
+        var yMax = Math.max(start.y, end.y);
+        this.tl = {
+          x: xMin,
+          y: yMin
+        };
+        this.tr = {
+          x: xMax,
+          y: yMin
+        };
+        this.bl = {
+          x: xMin,
+          y: yMax
+        };
+        this.br = {
+          x: xMax,
+          y: yMax
+        };
+        this.width = xMax - xMin;
+        this.height = yMax - yMin;
+      }
+      /**
+       * reset
+       * @param  {Object} start start point
+       * @param  {Object} end end point
+       */
+
+
+      reset(start, end) {
+        this.start = start;
+        this.end = end;
+
+        this._init();
+      }
+      /**
+       * check the point is in the range of plot
+       * @param  {Number}  x x value
+       * @param  {[type]}  y y value
+       * @return {Boolean} return the result
+       */
+
+
+      isInRange(x, y) {
+        if (isObject(x)) {
+          y = x.y;
+          x = x.x;
+        }
+
+        var tl = this.tl;
+        var br = this.br;
+        return tl.x <= x && x <= br.x && tl.y <= y && y <= br.y;
+      }
+
+    }
+
+    var Matrix = {
+      generateDefault() {
+        return [1, 0, 0, 1, 0, 0];
+      },
+
+      isChanged(m) {
+        return m[0] !== 1 || m[1] !== 0 || m[2] !== 0 || m[3] !== 1 || m[4] !== 0 || m[5] !== 0;
+      },
+
+      multiply(m1, m2) {
+        var m11 = m1[0] * m2[0] + m1[2] * m2[1];
+        var m12 = m1[1] * m2[0] + m1[3] * m2[1];
+        var m21 = m1[0] * m2[2] + m1[2] * m2[3];
+        var m22 = m1[1] * m2[2] + m1[3] * m2[3];
+        var dx = m1[0] * m2[4] + m1[2] * m2[5] + m1[4];
+        var dy = m1[1] * m2[4] + m1[3] * m2[5] + m1[5];
+        return [m11, m12, m21, m22, dx, dy];
+      },
+
+      scale(out, m, v) {
+        out[0] = m[0] * v[0];
+        out[1] = m[1] * v[0];
+        out[2] = m[2] * v[1];
+        out[3] = m[3] * v[1];
+        out[4] = m[4];
+        out[5] = m[5];
+        return out;
+      },
+
+      rotate(out, m, radian) {
+        var c = Math.cos(radian);
+        var s = Math.sin(radian);
+        var m11 = m[0] * c + m[2] * s;
+        var m12 = m[1] * c + m[3] * s;
+        var m21 = m[0] * -s + m[2] * c;
+        var m22 = m[1] * -s + m[3] * c;
+        out[0] = m11;
+        out[1] = m12;
+        out[2] = m21;
+        out[3] = m22;
+        out[4] = m[4];
+        out[5] = m[5];
+        return out;
+      },
+
+      translate(out, m, v) {
+        out[0] = m[0];
+        out[1] = m[1];
+        out[2] = m[2];
+        out[3] = m[3];
+        out[4] = m[4] + m[0] * v[0] + m[2] * v[1];
+        out[5] = m[5] + m[1] * v[0] + m[3] * v[1];
+        return out;
+      },
+
+      transform(m, actions) {
+        var out = [].concat(m);
+
+        for (var i = 0, len = actions.length; i < len; i++) {
+          var action = actions[i];
+
+          switch (action[0]) {
+            case 't':
+              Matrix.translate(out, out, [action[1], action[2]]);
+              break;
+
+            case 's':
+              Matrix.scale(out, out, [action[1], action[2]]);
+              break;
+
+            case 'r':
+              Matrix.rotate(out, out, action[1]);
+              break;
+          }
+        }
+
+        return out;
+      }
+
+    };
+
+    /**
+     * 2 Dimensional Vector
+     * @module vector2
+     */
+    var Vector2 = {
+      /**
+       * Creates a new, empty vector2
+       *
+       * @return {vector2} a new 2D vector
+       */
+      create() {
+        return [0, 0];
+      },
+
+      /**
+       * Calculates the length of a vector2
+       *
+       * @param {vector2} v vector to calculate length of
+       * @return {Number} length of v
+       */
+      length(v) {
+        var x = v[0];
+        var y = v[1];
+        return Math.sqrt(x * x + y * y);
+      },
+
+      /**
+       * Normalize a vector2
+       *
+       * @param {vector2} out the receiving vector
+       * @param {vector2} v vector to normalize
+       * @return {vector2} out
+       */
+      normalize(out, v) {
+        var len = this.length(v);
+
+        if (len === 0) {
+          out[0] = 0;
+          out[1] = 0;
+        } else {
+          out[0] = v[0] / len;
+          out[1] = v[1] / len;
+        }
+
+        return out;
+      },
+
+      /**
+       * Adds two vector2's
+       *
+       * @param {vector2} out the receiving vector
+       * @param {vector2} v1 the first operand
+       * @param {vector2} v2 the second operand
+       * @return {vector2} out
+       */
+      add(out, v1, v2) {
+        out[0] = v1[0] + v2[0];
+        out[1] = v1[1] + v2[1];
+        return out;
+      },
+
+      /**
+       * Subtracts vector v2 from vector v1
+       *
+       * @param {vector2} out the receiving vector
+       * @param {vector2} v1 the first operand
+       * @param {vector2} v2 the second operand
+       * @return {vector2} out
+       */
+      sub(out, v1, v2) {
+        out[0] = v1[0] - v2[0];
+        out[1] = v1[1] - v2[1];
+        return out;
+      },
+
+      /**
+       * Scales a vector2 by a scalar number
+       *
+       * @param {vector2} out the receiving vector
+       * @param {vector2} v the vector to scale
+       * @param {Number} s amount to scale the vector by
+       * @return {vector2} out
+       */
+      scale(out, v, s) {
+        out[0] = v[0] * s;
+        out[1] = v[1] * s;
+        return out;
+      },
+
+      /**
+       * Calculates the dot product of two vector2's
+       *
+       * @param {vector2} v1 the first operand
+       * @param {vector2} v2 the second operand
+       * @return {Number} dot product of v1 and v2
+       */
+      dot(v1, v2) {
+        return v1[0] * v2[0] + v1[1] * v2[1];
+      },
+
+      /**
+       * Calculates the direction of two vector2's
+       *
+       * @param {vector2} v1 the first operand
+       * @param {vector2} v2 the second operand
+       * @return {Boolean} the direction of v1 and v2
+       */
+      direction(v1, v2) {
+        return v1[0] * v2[1] - v2[0] * v1[1];
+      },
+
+      /**
+       * Calculates the angle of two vector2's
+       *
+       * @param {vector2} v1 the first operand
+       * @param {vector2} v2 the second operand
+       * @return {Number} angle of v1 and v2
+       */
+      angle(v1, v2) {
+        var theta = this.dot(v1, v2) / (this.length(v1) * this.length(v2));
+        return Math.acos(theta);
+      },
+
+      /**
+       * Calculates the angle of two vector2's with direction
+       *
+       * @param {vector2} v1 the first operand
+       * @param {vector2} v2 the second operand
+       * @param {Boolean} direction the direction of two vector2's
+       * @return {Number} angle of v1 and v2
+       */
+      angleTo(v1, v2, direction) {
+        var angle = this.angle(v1, v2);
+        var angleLargeThanPI = this.direction(v1, v2) >= 0;
+
+        if (direction) {
+          if (angleLargeThanPI) {
+            return Math.PI * 2 - angle;
+          }
+
+          return angle;
+        }
+
+        if (angleLargeThanPI) {
+          return angle;
+        }
+
+        return Math.PI * 2 - angle;
+      },
+
+      /**
+       * whether a vector2 is zero vector
+       *
+       * @param  {vector2} v vector to calculate
+       * @return {Boolean}   is or not a zero vector
+       */
+      zero(v) {
+        return v[0] === 0 && v[1] === 0;
+      },
+
+      /**
+       * Calculates the euclidian distance between two vector2's
+       *
+       * @param {vector2} v1 the first operand
+       * @param {vector2} v2 the second operand
+       * @return {Number} distance between a and b
+       */
+      distance(v1, v2) {
+        var x = v2[0] - v1[0];
+        var y = v2[1] - v1[1];
+        return Math.sqrt(x * x + y * y);
+      },
+
+      /**
+       * Creates a new vector2 initialized with values from an existing vector
+       *
+       * @param {vector2} v vector to clone
+       * @return {Array} a new 2D vector
+       */
+      clone(v) {
+        return [v[0], v[1]];
+      },
+
+      /**
+       * Return the minimum of two vector2's
+       *
+       * @param {vector2} out the receiving vector
+       * @param {vector2} v1 the first operand
+       * @param {vector2} v2 the second operand
+       * @return {vector2} out
+       */
+      min(out, v1, v2) {
+        out[0] = Math.min(v1[0], v2[0]);
+        out[1] = Math.min(v1[1], v2[1]);
+        return out;
+      },
+
+      /**
+       * Return the maximum of two vector2's
+       *
+       * @param {vector2} out the receiving vector
+       * @param {vector2} v1 the first operand
+       * @param {vector2} v2 the second operand
+       * @return {vector2} out
+       */
+      max(out, v1, v2) {
+        out[0] = Math.max(v1[0], v2[0]);
+        out[1] = Math.max(v1[1], v2[1]);
+        return out;
+      },
+
+      /**
+       * Transforms the vector2 with a mat2d
+       *
+       * @param {vector2} out the receiving vector
+       * @param {vector2} v the vector to transform
+       * @param {mat2d} m matrix to transform with
+       * @return {vector2} out
+       */
+      transformMat2d(out, v, m) {
+        var x = v[0];
+        var y = v[1];
+        out[0] = m[0] * x + m[2] * y + m[4];
+        out[1] = m[1] * x + m[3] * y + m[5];
+        return out;
+      }
+
+    };
+
+    var defaultMatrix = [1, 0, 0, 1, 0, 0];
+
+    class Base$1 {
+      _initDefaultCfg() {}
+
+      constructor(cfg) {
+        this._initDefaultCfg();
+
+        mix(this, cfg);
+        var start;
+        var end;
+
+        if (this.plot) {
+          start = this.plot.bl;
+          end = this.plot.tr;
+          this.start = start;
+          this.end = end;
+        } else {
+          start = this.start;
+          end = this.end;
+        }
+
+        this.init(start, end);
+      }
+
+      _scale(s1, s2) {
+        var matrix = this.matrix;
+        var center = this.center;
+        Matrix.translate(matrix, matrix, [center.x, center.y]);
+        Matrix.scale(matrix, matrix, [s1, s2]);
+        Matrix.translate(matrix, matrix, [-center.x, -center.y]);
+      }
+
+      init(start, end) {
+        this.matrix = [].concat(defaultMatrix); // 设置中心点
+
+        this.center = {
+          x: (end.x - start.x) / 2 + start.x,
+          y: (end.y - start.y) / 2 + start.y
+        };
+
+        if (this.scale) {
+          this._scale(this.scale[0], this.scale[1]);
+        }
+      }
+
+      convertPoint(point) {
+        var {
+          x,
+          y
+        } = this._convertPoint(point);
+
+        if (!Matrix.isChanged(this.matrix)) {
+          return {
+            x,
+            y
+          };
+        }
+
+        var vector = [x, y];
+        Vector2.transformMat2d(vector, vector, this.matrix);
+        return {
+          x: vector[0],
+          y: vector[1]
+        };
+      }
+
+      invertPoint(point) {
+        return this._invertPoint(point);
+      }
+
+      _convertPoint(point) {
+        return point;
+      }
+
+      _invertPoint(point) {
+        return point;
+      }
+
+      reset(plot) {
+        this.plot = plot;
+        var {
+          bl,
+          tr
+        } = plot;
+        this.start = bl;
+        this.end = tr;
+        this.init(bl, tr);
+      }
+
+    }
+
+    class Cartesian extends Base$1 {
+      _initDefaultCfg() {
+        this.type = 'cartesian';
+        this.transposed = false;
+        this.isRect = true;
+      }
+
+      init(start, end) {
+        super.init(start, end);
+        this.x = {
+          start: start.x,
+          end: end.x
+        };
+        this.y = {
+          start: start.y,
+          end: end.y
+        };
+      }
+
+      _convertPoint(point) {
+        var self = this;
+        var transposed = self.transposed;
+        var xDim = transposed ? 'y' : 'x';
+        var yDim = transposed ? 'x' : 'y';
+        var x = self.x;
+        var y = self.y;
+        return {
+          x: x.start + (x.end - x.start) * point[xDim],
+          y: y.start + (y.end - y.start) * point[yDim]
+        };
+      }
+
+      _invertPoint(point) {
+        var self = this;
+        var transposed = self.transposed;
+        var xDim = transposed ? 'y' : 'x';
+        var yDim = transposed ? 'x' : 'y';
+        var x = self.x;
+        var y = self.y;
+        var rst = {};
+        rst[xDim] = (point.x - x.start) / (x.end - x.start);
+        rst[yDim] = (point.y - y.start) / (y.end - y.start);
+        return rst;
+      }
+
+    }
+
+    Base$1.Cartesian = Cartesian;
+    Base$1.Rect = Cartesian;
+
+    /**
+     * @fileOverview the Attribute base class
+     */
+
+    function toScaleString(scale, value) {
+      if (isString(value)) {
+        return value;
+      }
+
+      return scale.invert(scale.scale(value));
+    }
+    /**
+     * 所有视觉通道属性的基类
+     * @class Attr
+     */
+
+
+    class AttributeBase {
+      constructor(cfg) {
+        var _this = this;
+
+        /**
+         * 属性的类型
+         * @type {String}
+         */
+        this.type = 'base';
+        /**
+         * 属性的名称
+         * @type {String}
+         */
+
+        this.name = null;
+        /**
+         * 回调函数
+         * @type {Function}
+         */
+
+        this.method = null;
+        /**
+         * 备选的值数组
+         * @type {Array}
+         */
+
+        this.values = [];
+        /**
+         * 属性内部的度量
+         * @type {Array}
+         */
+
+        this.scales = [];
+        /**
+         * 是否通过线性取值, 如果未指定,则根据数值的类型判定
+         * @type {Boolean}
+         */
+
+        this.linear = null;
+        /**
+         * 当用户设置的 callback 返回 null 时, 应该返回默认 callback 中的值
+         */
+
+        var mixedCallback = null;
+        var defaultCallback = this.callback;
+
+        if (cfg.callback) {
+          var userCallback = cfg.callback;
+
+          mixedCallback = function mixedCallback() {
+            for (var _len = arguments.length, params = new Array(_len), _key = 0; _key < _len; _key++) {
+              params[_key] = arguments[_key];
+            }
+
+            var ret = userCallback(...params);
+
+            if (isNil(ret)) {
+              ret = defaultCallback.apply(_this, params);
+            }
+
+            return ret;
+          };
+        }
+
+        mix(this, cfg);
+
+        if (mixedCallback) {
+          mix(this, {
+            callback: mixedCallback
+          });
+        }
+      } // 获取属性值,将值映射到视觉通道
+
+
+      _getAttrValue(scale, value) {
+        var values = this.values;
+
+        if (scale.isCategory && !this.linear) {
+          var index = scale.translate(value);
+          return values[index % values.length];
+        }
+
+        var percent = scale.scale(value);
+        return this.getLinearValue(percent);
+      }
+      /**
+       * 如果进行线性映射,返回对应的映射值
+       * @protected
+       * @param  {Number} percent 百分比
+       * @return {*}  颜色值、形状、大小等
+       */
+
+
+      getLinearValue(percent) {
+        var values = this.values;
+        var steps = values.length - 1;
+        var step = Math.floor(steps * percent);
+        var leftPercent = steps * percent - step;
+        var start = values[step];
+        var end = step === steps ? start : values[step + 1];
+        var rstValue = start + (end - start) * leftPercent;
+        return rstValue;
+      }
+      /**
+       * 默认的回调函数
+       * @param {*} value 回调函数的值
+       * @type {Function}
+       * @return {Array} 返回映射后的值
+       */
+
+
+      callback(value) {
+        var self = this;
+        var scale = self.scales[0];
+        var rstValue = null;
+
+        if (scale.type === 'identity') {
+          rstValue = scale.value;
+        } else {
+          rstValue = self._getAttrValue(scale, value);
+        }
+
+        return rstValue;
+      }
+      /**
+       * 根据度量获取属性名
+       * @return {Array} dims of this Attribute
+       */
+
+
+      getNames() {
+        var scales = this.scales;
+        var names = this.names;
+        var length = Math.min(scales.length, names.length);
+        var rst = [];
+
+        for (var i = 0; i < length; i++) {
+          rst.push(names[i]);
+        }
+
+        return rst;
+      }
+      /**
+       * 根据度量获取维度名
+       * @return {Array} dims of this Attribute
+       */
+
+
+      getFields() {
+        var scales = this.scales;
+        var rst = [];
+        each(scales, function (scale) {
+          rst.push(scale.field);
+        });
+        return rst;
+      }
+      /**
+       * 根据名称获取度量
+       * @param  {String} name the name of scale
+       * @return {Scale} scale
+       */
+
+
+      getScale(name) {
+        var scales = this.scales;
+        var names = this.names;
+        var index = names.indexOf(name);
+        return scales[index];
+      }
+      /**
+       * 映射数据
+       * @param {*} param1...paramn 多个数值
+       * @return {Array} 映射的值组成的数组
+       */
+
+
+      mapping() {
+        var scales = this.scales;
+        var callback = this.callback;
+
+        for (var _len2 = arguments.length, params = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
+          params[_key2] = arguments[_key2];
+        }
+
+        var values = params;
+
+        if (callback) {
+          for (var i = 0, len = params.length; i < len; i++) {
+            params[i] = this._toOriginParam(params[i], scales[i]);
+          }
+
+          values = callback.apply(this, params);
+        }
+
+        values = [].concat(values);
+        return values;
+      } // 原始的参数
+
+
+      _toOriginParam(param, scale) {
+        var rst = param;
+
+        if (!scale.isLinear) {
+          if (isArray(param)) {
+            rst = [];
+
+            for (var i = 0, len = param.length; i < len; i++) {
+              rst.push(toScaleString(scale, param[i]));
+            }
+          } else {
+            rst = toScaleString(scale, param);
+          }
+        }
+
+        return rst;
+      }
+
+    }
+
+    class Position extends AttributeBase {
+      constructor(cfg) {
+        super(cfg);
+        this.names = ['x', 'y'];
+        this.type = 'position';
+      }
+
+      mapping(x, y) {
+        var scales = this.scales;
+        var coord = this.coord;
+        var scaleX = scales[0];
+        var scaleY = scales[1];
+        var rstX;
+        var rstY;
+        var obj;
+
+        if (isNil(x) || isNil(y)) {
+          return [];
+        }
+
+        if (isArray(y) && isArray(x)) {
+          rstX = [];
+          rstY = [];
+
+          for (var i = 0, j = 0, xLen = x.length, yLen = y.length; i < xLen && j < yLen; i++, j++) {
+            obj = coord.convertPoint({
+              x: scaleX.scale(x[i]),
+              y: scaleY.scale(y[j])
+            });
+            rstX.push(obj.x);
+            rstY.push(obj.y);
+          }
+        } else if (isArray(y)) {
+          x = scaleX.scale(x);
+          rstY = [];
+          each(y, function (yVal) {
+            yVal = scaleY.scale(yVal);
+            obj = coord.convertPoint({
+              x,
+              y: yVal
+            });
+
+            if (rstX && rstX !== obj.x) {
+              if (!isArray(rstX)) {
+                rstX = [rstX];
+              }
+
+              rstX.push(obj.x);
+            } else {
+              rstX = obj.x;
+            }
+
+            rstY.push(obj.y);
+          });
+        } else if (isArray(x)) {
+          y = scaleY.scale(y);
+          rstX = [];
+          each(x, function (xVal) {
+            xVal = scaleX.scale(xVal);
+            obj = coord.convertPoint({
+              x: xVal,
+              y
+            });
+
+            if (rstY && rstY !== obj.y) {
+              if (!isArray(rstY)) {
+                rstY = [rstY];
+              }
+
+              rstY.push(obj.y);
+            } else {
+              rstY = obj.y;
+            }
+
+            rstX.push(obj.x);
+          });
+        } else {
+          x = scaleX.scale(x);
+          y = scaleY.scale(y);
+          var point = coord.convertPoint({
+            x,
+            y
+          });
+          rstX = point.x;
+          rstY = point.y;
+        }
+
+        return [rstX, rstY];
+      }
+
+    }
+
+    class Shape extends AttributeBase {
+      constructor(cfg) {
+        super(cfg);
+        this.names = ['shape'];
+        this.type = 'shape';
+        this.gradient = null;
+      }
+      /**
+       * @override
+       */
+
+
+      getLinearValue(percent) {
+        var values = this.values;
+        var index = Math.round((values.length - 1) * percent);
+        return values[index];
+      }
+
+    }
+
+    class Size extends AttributeBase {
+      constructor(cfg) {
+        super(cfg);
+        this.names = ['size'];
+        this.type = 'size';
+        this.gradient = null;
+      }
+
+    }
+
+    function getValue(start, end, percent, index) {
+      var value = start[index] + (end[index] - start[index]) * percent;
+      return value;
+    } // convert to hex
+
+
+    function arr2hex(arr) {
+      return '#' + toRGBValue(arr[0]) + toRGBValue(arr[1]) + toRGBValue(arr[2]);
+    }
+
+    function toRGBValue(value) {
+      value = Math.round(value);
+      value = value.toString(16);
+
+      if (value.length === 1) {
+        value = '0' + value;
+      }
+
+      return value;
+    }
+
+    function calColor(colors, percent) {
+      var steps = colors.length - 1;
+      var step = Math.floor(steps * percent);
+      var left = steps * percent - step;
+      var start = colors[step];
+      var end = step === steps ? start : colors[step + 1];
+      var rgb = arr2hex([getValue(start, end, left, 0), getValue(start, end, left, 1), getValue(start, end, left, 2)]);
+      return rgb;
+    }
+
+    function hex2arr(str) {
+      var arr = [];
+      arr.push(parseInt(str.substr(1, 2), 16));
+      arr.push(parseInt(str.substr(3, 2), 16));
+      arr.push(parseInt(str.substr(5, 2), 16));
+      return arr;
+    }
+
+    var colorCache = {
+      black: '#000000',
+      blue: '#0000ff',
+      grey: '#808080',
+      green: '#008000',
+      orange: '#ffa500',
+      pink: '#ffc0cb',
+      purple: '#800080',
+      red: '#ff0000',
+      white: '#ffffff',
+      yellow: '#ffff00'
+    };
+    /**
+     * Returns a hexadecimal string representing this color in RGB space, such as #f7eaba.
+     * @param  {String} color color value
+     * @return {String} Returns a hexadecimal string
+     */
+
+    function toHex(color) {
+      if (colorCache[color]) {
+        return colorCache[color];
+      }
+
+      if (color[0] === '#') {
+        if (color.length === 7) {
+          return color;
+        }
+
+        var hex = color.replace(/^#?([a-f\d])([a-f\d])([a-f\d])$/i, function (m, r, g, b) {
+          return '#' + r + r + g + g + b + b;
+        }); // hex3 to hex6
+
+        colorCache[color] = hex;
+        return hex;
+      } // rgb/rgba to hex
+
+
+      var rst = color.match(/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?/i);
+      rst.shift();
+      rst = arr2hex(rst);
+      colorCache[color] = rst;
+      return rst;
+    }
+    /**
+     * handle the gradient color
+     * @param  {Array} colors the colors
+     * @return {String} return the color value
+     */
+
+
+    function gradient(colors) {
+      var points = [];
+
+      if (isString(colors)) {
+        colors = colors.split('-');
+      }
+
+      each(colors, function (color) {
+        if (color.indexOf('#') === -1) {
+          color = toHex(color);
+        }
+
+        points.push(hex2arr(color));
+      });
+      return function (percent) {
+        return calColor(points, percent);
+      };
+    }
+
+    class Color extends AttributeBase {
+      constructor(cfg) {
+        super(cfg);
+        this.names = ['color'];
+        this.type = 'color';
+        this.gradient = null;
+
+        if (isString(this.values)) {
+          this.linear = true;
+        }
+      }
+      /**
+       * @override
+       */
+
+
+      getLinearValue(percent) {
+        var gradient$1 = this.gradient;
+
+        if (!gradient$1) {
+          var values = this.values;
+          gradient$1 = gradient(values);
+          this.gradient = gradient$1;
+        }
+
+        return gradient$1(percent);
+      }
+
+    }
+
+
+
+    var Attr = /*#__PURE__*/Object.freeze({
+        __proto__: null,
+        Position: Position,
+        Shape: Shape,
+        Size: Size,
+        Color: Color
+    });
+
+    var Shape$1 = {};
+    var ShapeBase = {
+      _coord: null,
+
+      /**
+       * draw the shape
+       * @param {Object} cfg options
+       * @param {Object} container container to store the shapes
+       */
+      draw(cfg, container) {
+        if (this.drawShape) {
+          this.drawShape(cfg, container);
+        }
+      },
+
+      /**
+       * set the coordinate instance
+       * @param {Coord} coord coordinate instance
+       */
+      setCoord(coord) {
+        this._coord = coord;
+      },
+
+      /**
+       * convert the normalized value to the canvas position
+       * @param  {point} point the point to convert
+       * @return {point} point return the result
+       */
+      parsePoint(point) {
+        var coord = this._coord;
+
+        if (coord.isPolar) {
+          if (point.x === 1) point.x = 0.9999999;
+          if (point.y === 1) point.y = 0.9999999;
+        }
+
+        return coord.convertPoint(point);
+      },
+
+      /**
+       * convert the normalized value to the canvas position
+       * @param  {points} points the array that store the points
+       * @return {points} points return the result
+       */
+      parsePoints(points) {
+        if (!points) return false;
+        var self = this;
+        var rst = [];
+        points.forEach(function (point) {
+          rst.push(self.parsePoint(point));
+        });
+        return rst;
+      }
+
+    };
+    var ShapeFactoryBase = {
+      defaultShapeType: null,
+
+      setCoord(coord) {
+        this._coord = coord;
+      },
+
+      getShape(type) {
+        var self = this;
+
+        if (isArray(type)) {
+          type = type[0];
+        }
+
+        var shape = self[type] || self[self.defaultShapeType];
+        shape._coord = self._coord;
+        return shape;
+      },
+
+      getShapePoints(type, cfg) {
+        var shape = this.getShape(type);
+        var fn = shape.getPoints || shape.getShapePoints || this.getDefaultPoints;
+        var points = fn(cfg);
+        return points;
+      },
+
+      getDefaultPoints()
+      /* cfg */
+      {
+        return [];
+      },
+
+      drawShape(type, cfg, container) {
+        var shape = this.getShape(type);
+
+        if (!cfg.color) {
+          cfg.color = Global.colors[0];
+        }
+
+        return shape.draw(cfg, container);
+      }
+
+    };
+
+    Shape$1.registerFactory = function (factoryName, cfg) {
+      var className = upperFirst(factoryName);
+      var geomObj = mix({}, ShapeFactoryBase, cfg);
+      Shape$1[className] = geomObj;
+      geomObj.name = factoryName;
+      return geomObj;
+    };
+
+    Shape$1.registerShape = function (factoryName, shapeType, cfg) {
+      var className = upperFirst(factoryName);
+      var factory = Shape$1[className];
+      var shapeObj = mix({}, ShapeBase, cfg);
+      factory[shapeType] = shapeObj;
+      return shapeObj;
+    };
+
+    Shape$1.registShape = Shape$1.registerShape;
+
+    Shape$1.getShapeFactory = function (factoryName) {
+      var self = this;
+      factoryName = factoryName || 'point';
+      var className = upperFirst(factoryName);
+      return self[className];
+    };
+
+    function _mix$1(dist, obj) {
+      for (var key in obj) {
+        if (obj.hasOwnProperty(key) && key !== 'constructor' && obj[key] !== undefined) {
+          dist[key] = obj[key];
+        }
+      }
+    }
+
+    var mix$1 = function mix(dist, src1, src2, src3) {
+      if (src1) _mix$1(dist, src1);
+      if (src2) _mix$1(dist, src2);
+      if (src3) _mix$1(dist, src3);
+      return dist;
+    };
+
+    var mix_1 = mix$1;
+
+    var Adjust =
+    /*#__PURE__*/
+    function () {
+      var _proto = Adjust.prototype;
+
+      _proto._initDefaultCfg = function _initDefaultCfg() {
+        this.adjustNames = ['x', 'y']; // 调整的维度,默认,x,y都做调整
+      };
+
+      function Adjust(cfg) {
+        this._initDefaultCfg();
+
+        mix_1(this, cfg);
+      }
+      /**
+       * @override
+       */
+
+
+      _proto.processAdjust = function processAdjust()
+      /* dataArray */
+      {};
+
+      return Adjust;
+    }();
+
+    var base = Adjust;
+
+    function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
+
+    function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
+
+    function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
+    var GROUP_ATTRS = ['color', 'size', 'shape'];
+    var FIELD_ORIGIN = '_origin';
+    var FIELD_ORIGIN_Y = '_originY';
+
+    function parseFields(field) {
+      if (isArray(field)) {
+        return field;
+      }
+
+      if (isString(field)) {
+        return field.split('*');
+      }
+
+      return [field];
+    }
+    /**
+     * The parent class for Geometry
+     * @class Geom
+     */
+
+
+    class Geom extends Base {
+      getDefaultCfg() {
+        return {
+          /**
+           * geometry type
+           * @type {String}
+           */
+          type: null,
+
+          /**
+           * the data of geometry
+           * @type {Array}
+           */
+          data: null,
+
+          /**
+           * the attrs of geo,etry
+           * @type {Object}
+           */
+          attrs: {},
+          scales: {},
+
+          /**
+           * group for storing the shapes
+           * @type {Canvas}
+           */
+          container: null,
+
+          /**
+           * style options
+           * @type {Object}
+           */
+          styleOptions: null,
+          chart: null,
+          shapeType: '',
+
+          /**
+           * wether to generate key points for each shape
+           * @protected
+           * @type {Boolean}
+           */
+          generatePoints: false,
+          attrOptions: {},
+          sortable: false,
+          startOnZero: true,
+          visible: true,
+          connectNulls: false,
+          // 是否丢弃没有值的分组。
+          ignoreEmptyGroup: false,
+          // 是否已经初始化
+          isInit: false
+        };
+      }
+
+      init() {
+        var self = this;
+        var isInit = self.get('isInit');
+
+        if (isInit) {
+          return;
+        }
+
+        self._initAttrs();
+
+        self._processData();
+
+        self.set('isInit', true);
+      }
+
+      _getGroupScales() {
+        var self = this;
+        var scales = [];
+        each(GROUP_ATTRS, function (attrName) {
+          var attr = self.getAttr(attrName);
+
+          if (attr) {
+            var attrScales = attr.scales;
+            each(attrScales, function (scale) {
+              if (scale && scale.isCategory && scales.indexOf(scale) === -1) {
+                scales.push(scale);
+              }
+            });
+          }
+        });
+        return scales;
+      }
+
+      _groupData(data) {
+        var self = this;
+        var colDefs = self.get('colDefs');
+
+        var groupScales = self._getGroupScales();
+
+        if (groupScales.length) {
+          var appendConditions = {};
+          var names = [];
+          each(groupScales, function (scale) {
+            var field = scale.field;
+            names.push(field);
+
+            if (colDefs && colDefs[field] && colDefs[field].values) {
+              // users have defined
+              appendConditions[scale.field] = colDefs[field].values;
+            }
+          });
+          return group$1(data, names, appendConditions);
+        }
+
+        return [data];
+      }
+
+      _setAttrOptions(attrName, attrCfg) {
+        var options = this.get('attrOptions');
+        options[attrName] = attrCfg;
+        var attrs = this.get('attrs'); // 说明已经初始化过了
+
+        if (Object.keys(attrs).length) {
+          this._createAttr(attrName, attrCfg);
+        }
+      }
+
+      _createAttrOption(attrName, field, cfg, defaultValues) {
+        var attrCfg = {};
+        attrCfg.field = field;
+
+        if (cfg) {
+          if (isFunction(cfg)) {
+            attrCfg.callback = cfg;
+          } else {
+            attrCfg.values = cfg;
+          }
+        } else {
+          attrCfg.values = defaultValues;
+        }
+
+        this._setAttrOptions(attrName, attrCfg);
+      }
+
+      _createAttr(type, option) {
+        var self = this;
+        var attrs = self.get('attrs');
+        var coord = self.get('coord');
+        var className = upperFirst(type);
+        var fields = parseFields(option.field);
+
+        if (type === 'position') {
+          option.coord = coord;
+        }
+
+        var scales = [];
+
+        for (var i = 0, len = fields.length; i < len; i++) {
+          var field = fields[i];
+
+          var scale = self._createScale(field);
+
+          scales.push(scale);
+        }
+
+        if (type === 'position') {
+          var yScale = scales[1]; // 饼图的处理,但是还不知道为啥
+
+          if (coord.type === 'polar' && coord.transposed && self.hasAdjust('stack')) {
+            if (yScale.values.length) {
+              yScale.change({
+                nice: false,
+                min: 0,
+                max: Math.max.apply(null, yScale.values)
+              });
+            }
+          }
+        }
+
+        option.scales = scales;
+        var attr = new Attr[className](option);
+        attrs[type] = attr;
+        return attr;
+      }
+
+      _initAttrs() {
+        var self = this;
+        var attrOptions = self.get('attrOptions');
+
+        for (var type in attrOptions) {
+          if (attrOptions.hasOwnProperty(type)) {
+            this._createAttr(type, attrOptions[type]);
+          }
+        }
+      }
+
+      _createScale(field) {
+        var scales = this.get('scales');
+        var scale = scales[field];
+
+        if (!scale) {
+          scale = this.get('chart').createScale(field);
+          scales[field] = scale;
+        }
+
+        return scale;
+      }
+
+      _processData() {
+        var self = this;
+        var data = this.get('data');
+        var dataArray = [];
+
+        var groupedArray = this._groupData(data);
+
+        if (this.get('ignoreEmptyGroup')) {
+          var yScale = this.getYScale();
+          groupedArray = groupedArray.filter(function (group) {
+            return group.some(function (item) {
+              return typeof item[yScale.field] !== 'undefined';
+            });
+          });
+        }
+
+        for (var i = 0, len = groupedArray.length; i < len; i++) {
+          var subData = groupedArray[i];
+
+          var tempData = self._saveOrigin(subData);
+
+          if (this.hasAdjust('dodge')) {
+            self._numberic(tempData);
+          }
+
+          dataArray.push(tempData);
+        }
+
+        if (self.get('adjust')) {
+          self._adjustData(dataArray);
+        }
+
+        if (self.get('sortable')) {
+          self._sort(dataArray);
+        }
+
+        self.emit('afterprocessdata', {
+          dataArray
+        });
+        self.set('mappingData', dataArray);
+        self.set('dataArray', dataArray);
+        return dataArray;
+      }
+
+      _saveOrigin(data) {
+        var rst = [];
+
+        for (var i = 0, len = data.length; i < len; i++) {
+          var origin = data[i];
+          var obj = {};
+
+          for (var k in origin) {
+            obj[k] = origin[k];
+          }
+
+          obj[FIELD_ORIGIN] = origin;
+          rst.push(obj);
+        }
+
+        return rst;
+      }
+
+      _numberic(data) {
+        var positionAttr = this.getAttr('position');
+        var scales = positionAttr.scales;
+
+        for (var j = 0, len = data.length; j < len; j++) {
+          var obj = data[j];
+          var count = Math.min(2, scales.length);
+
+          for (var i = 0; i < count; i++) {
+            var scale = scales[i];
+
+            if (scale.isCategory) {
+              var field = scale.field;
+              obj[field] = scale.translate(obj[field]);
+            }
+          }
+        }
+      }
+
+      _adjustData(dataArray) {
+        var self = this;
+        var adjust = self.get('adjust');
+
+        if (adjust) {
+          var adjustType = upperFirst(adjust.type);
+
+          if (!base[adjustType]) {
+            throw new Error('not support such adjust : ' + adjust);
+          }
+
+          var xScale = self.getXScale();
+          var yScale = self.getYScale();
+          var cfg = mix({
+            xField: xScale.field,
+            yField: yScale.field
+          }, adjust);
+          var adjustObject = new base[adjustType](cfg);
+          adjustObject.processAdjust(dataArray);
+
+          if (adjustType === 'Stack') {
+            self._updateStackRange(yScale.field, yScale, dataArray);
+          }
+        }
+      }
+
+      _updateStackRange(field, scale, dataArray) {
+        var mergeArray = merge(dataArray);
+        var min = scale.min;
+        var max = scale.max;
+
+        for (var i = 0, len = mergeArray.length; i < len; i++) {
+          var obj = mergeArray[i];
+          var tmpMin = Math.min.apply(null, obj[field]);
+          var tmpMax = Math.max.apply(null, obj[field]);
+
+          if (tmpMin < min) {
+            min = tmpMin;
+          }
+
+          if (tmpMax > max) {
+            max = tmpMax;
+          }
+        }
+
+        if (min < scale.min || max > scale.max) {
+          scale.change({
+            min,
+            max
+          });
+        }
+      }
+
+      _sort(mappedArray) {
+        var self = this;
+        var xScale = self.getXScale();
+        var {
+          field,
+          type
+        } = xScale;
+
+        if (type !== 'identity' && xScale.values.length > 1) {
+          each(mappedArray, function (itemArr) {
+            itemArr.sort(function (obj1, obj2) {
+              if (type === 'timeCat') {
+                return toTimeStamp(obj1[FIELD_ORIGIN][field]) - toTimeStamp(obj2[FIELD_ORIGIN][field]);
+              }
+
+              return xScale.translate(obj1[FIELD_ORIGIN][field]) - xScale.translate(obj2[FIELD_ORIGIN][field]);
+            });
+          });
+        }
+
+        self.set('hasSorted', true);
+        self.set('dataArray', mappedArray);
+      }
+
+      paint() {
+        var self = this;
+        var dataArray = self.get('mappingData');
+        var mappedArray = [];
+        var shapeFactory = self.getShapeFactory();
+        shapeFactory.setCoord(self.get('coord'));
+
+        self._beforeMapping(dataArray);
+
+        for (var i = 0, len = dataArray.length; i < len; i++) {
+          var data = dataArray[i];
+
+          if (data.length) {
+            var mappedData = self._mapping(data);
+
+            mappedArray.push(mappedData);
+            self.draw(mappedData, shapeFactory);
+          }
+        }
+
+        self.set('dataArray', mappedArray);
+      }
+
+      getShapeFactory() {
+        var shapeFactory = this.get('shapeFactory');
+
+        if (!shapeFactory) {
+          var shapeType = this.get('shapeType');
+          shapeFactory = Shape$1.getShapeFactory(shapeType);
+          this.set('shapeFactory', shapeFactory);
+        }
+
+        return shapeFactory;
+      }
+
+      _mapping(data) {
+        var self = this;
+        var attrs = self.get('attrs');
+        var yField = self.getYScale().field; // 用来缓存转换的值,减少mapping耗时
+
+        var mappedCache = {};
+        var mappedData = new Array(data.length);
+
+        for (var k in attrs) {
+          if (attrs.hasOwnProperty(k)) {
+            var attr = attrs[k];
+            var names = attr.names;
+            var scales = attr.scales;
+
+            for (var i = 0, len = data.length; i < len; i++) {
+              var record = data[i];
+
+              var mappedRecord = _objectSpread(_objectSpread({}, record), mappedData[i]);
+
+              mappedRecord[FIELD_ORIGIN_Y] = record[yField]; // 获取视觉属性对应的value值
+              // 位置的缓存命中率低,还是每次单独计算
+
+              if (attr.type === 'position') {
+                var values = self._getAttrValues(attr, record);
+
+                for (var j = 0, _len = values.length; j < _len; j++) {
+                  var val = values[j];
+                  var name = names[j];
+                  mappedRecord[name] = isArray(val) && val.length === 1 ? val[0] : val;
+                }
+              } else {
+                // 除了position其他都只有一项
+                var _name = names[0];
+                var field = scales[0].field;
+                var value = record[field];
+                var key = "".concat(_name).concat(value);
+                var _values = mappedCache[key];
+
+                if (!_values) {
+                  _values = self._getAttrValues(attr, record);
+                  mappedCache[key] = _values;
+                }
+
+                mappedRecord[_name] = _values[0];
+              } // 设置新数组
+
+
+              mappedData[i] = mappedRecord;
+            }
+          }
+        }
+
+        return mappedData;
+      }
+
+      _getAttrValues(attr, record) {
+        var scales = attr.scales;
+        var params = [];
+
+        for (var i = 0, len = scales.length; i < len; i++) {
+          var scale = scales[i];
+          var field = scale.field;
+
+          if (scale.type === 'identity') {
+            params.push(scale.value);
+          } else {
+            params.push(record[field]);
+          }
+        }
+
+        var values = attr.mapping(...params);
+        return values;
+      }
+
+      getAttrValue(attrName, record) {
+        var attr = this.getAttr(attrName);
+        var rst = null;
+
+        if (attr) {
+          var values = this._getAttrValues(attr, record);
+
+          rst = values[0];
+        }
+
+        return rst;
+      }
+
+      _beforeMapping(dataArray) {
+        var self = this;
+
+        if (self.get('generatePoints')) {
+          self._generatePoints(dataArray);
+        }
+      }
+
+      isInCircle() {
+        var coord = this.get('coord');
+        return coord && coord.isPolar;
+      }
+
+      getCallbackCfg(fields, cfg, origin) {
+        if (!fields) {
+          return cfg;
+        }
+
+        var tmpCfg = {};
+        var params = fields.map(function (field) {
+          return origin[field];
+        });
+        each(cfg, function (v, k) {
+          if (isFunction(v)) {
+            tmpCfg[k] = v.apply(null, params);
+          } else {
+            tmpCfg[k] = v;
+          }
+        });
+        return tmpCfg;
+      }
+
+      getDrawCfg(obj) {
+        var self = this;
+        var isInCircle = self.isInCircle();
+        var cfg = {
+          origin: obj,
+          x: obj.x,
+          y: obj.y,
+          color: obj.color,
+          size: obj.size,
+          shape: obj.shape,
+          isInCircle,
+          opacity: obj.opacity
+        };
+        var styleOptions = self.get('styleOptions');
+
+        if (styleOptions && styleOptions.style) {
+          cfg.style = self.getCallbackCfg(styleOptions.fields, styleOptions.style, obj[FIELD_ORIGIN]);
+        }
+
+        if (self.get('generatePoints')) {
+          cfg.points = obj.points;
+          cfg.nextPoints = obj.nextPoints;
+        }
+
+        if (isInCircle) {
+          cfg.center = self.get('coord').center;
+        }
+
+        return cfg;
+      }
+
+      draw(data, shapeFactory) {
+        var self = this;
+        var container = self.get('container');
+        var yScale = self.getYScale();
+        each(data, function (obj, index) {
+          if (yScale && isNil(obj._origin[yScale.field])) {
+            return;
+          }
+
+          obj.index = index;
+          var cfg = self.getDrawCfg(obj);
+          var shape = obj.shape;
+          self.drawShape(shape, obj, cfg, container, shapeFactory);
+        });
+      }
+
+      drawShape(shape, shapeData, cfg, container, shapeFactory) {
+        var gShape = shapeFactory.drawShape(shape, cfg, container);
+
+        if (gShape) {
+          each([].concat(gShape), function (s) {
+            s.set('origin', shapeData);
+          });
+        }
+      }
+
+      _generatePoints(dataArray) {
+        var self = this;
+        var shapeFactory = self.getShapeFactory();
+        var shapeAttr = self.getAttr('shape');
+        each(dataArray, function (data) {
+          for (var i = 0, len = data.length; i < len; i++) {
+            var obj = data[i];
+            var cfg = self.createShapePointsCfg(obj);
+            var shape = shapeAttr ? self._getAttrValues(shapeAttr, obj) : null;
+            var points = shapeFactory.getShapePoints(shape, cfg);
+            obj.points = points;
+          }
+        }); // 添加nextPoints
+
+        each(dataArray, function (data, index) {
+          var nextData = dataArray[index + 1];
+
+          if (nextData) {
+            data[0].nextPoints = nextData[0].points;
+          }
+        });
+      }
+      /**
+       * get the info of each shape
+       * @protected
+       * @param  {Object} obj the data item
+       * @return {Object} cfg return the result
+       */
+
+
+      createShapePointsCfg(obj) {
+        var xScale = this.getXScale();
+        var yScale = this.getYScale();
+
+        var x = this._normalizeValues(obj[xScale.field], xScale);
+
+        var y;
+
+        if (yScale) {
+          y = this._normalizeValues(obj[yScale.field], yScale);
+        } else {
+          y = obj.y ? obj.y : 0.1;
+        }
+
+        return {
+          x,
+          y,
+          y0: yScale ? yScale.scale(this.getYMinValue()) : undefined
+        };
+      }
+
+      getYMinValue() {
+        var yScale = this.getYScale();
+        var {
+          min,
+          max
+        } = yScale;
+        var value;
+
+        if (this.get('startOnZero')) {
+          if (max <= 0 && min <= 0) {
+            value = max;
+          } else {
+            value = min >= 0 ? min : 0;
+          }
+        } else {
+          value = min;
+        }
+
+        return value;
+      }
+
+      _normalizeValues(values, scale) {
+        var rst = [];
+
+        if (isArray(values)) {
+          for (var i = 0, len = values.length; i < len; i++) {
+            var v = values[i];
+            rst.push(scale.scale(v));
+          }
+        } else {
+          rst = scale.scale(values);
+        }
+
+        return rst;
+      }
+
+      getAttr(name) {
+        return this.get('attrs')[name];
+      }
+
+      getXScale() {
+        return this.getAttr('position').scales[0];
+      }
+
+      getYScale() {
+        return this.getAttr('position').scales[1];
+      }
+
+      hasAdjust(adjust) {
+        return this.get('adjust') && this.get('adjust').type === adjust;
+      }
+
+      _getSnap(scale, item, arr) {
+        var i = 0;
+        var values;
+        var yField = this.getYScale().field; // 叠加的维度
+
+        if (this.hasAdjust('stack') && scale.field === yField) {
+          values = [];
+          arr.forEach(function (obj) {
+            values.push(obj[FIELD_ORIGIN_Y]);
+          });
+
+          for (var len = values.length; i < len; i++) {
+            if (values[0][0] > item) {
+              break;
+            }
+
+            if (values[values.length - 1][1] <= item) {
+              i = values.length - 1;
+              break;
+            }
+
+            if (values[i][0] <= item && values[i][1] > item) {
+              break;
+            }
+          }
+        } else {
+          values = scale.values;
+          values.sort(function (a, b) {
+            return a - b;
+          });
+
+          for (var _len2 = values.length; i < _len2; i++) {
+            // 如果只有1个点直接返回第1个点
+            if (_len2 <= 1) {
+              break;
+            } // 第1个点和第2个点之间
+
+
+            if ((values[0] + values[1]) / 2 > item) {
+              break;
+            } // 中间的点
+
+
+            if ((values[i - 1] + values[i]) / 2 <= item && (values[i + 1] + values[i]) / 2 > item) {
+              break;
+            } // 最后2个点
+
+
+            if ((values[values.length - 2] + values[values.length - 1]) / 2 <= item) {
+              i = values.length - 1;
+              break;
+            }
+          }
+        }
+
+        var result = values[i];
+        return result;
+      }
+
+      getSnapRecords(point) {
+        var self = this;
+        var coord = self.get('coord');
+        var xScale = self.getXScale();
+        var yScale = self.getYScale();
+        var xfield = xScale.field;
+        var dataArray = self.get('dataArray');
+
+        if (!this.get('hasSorted')) {
+          this._sort(dataArray);
+        }
+
+        var rst = [];
+        var invertPoint = coord.invertPoint(point);
+        var invertPointX = invertPoint.x;
+
+        if (self.isInCircle() && !coord.transposed && invertPointX > (1 + xScale.rangeMax()) / 2) {
+          invertPointX = xScale.rangeMin();
+        }
+
+        var xValue = xScale.invert(invertPointX);
+
+        if (!xScale.isCategory) {
+          xValue = self._getSnap(xScale, xValue);
+        }
+
+        var tmp = [];
+        dataArray.forEach(function (data) {
+          data.forEach(function (obj) {
+            var originValue = isNil(obj[FIELD_ORIGIN]) ? obj[xfield] : obj[FIELD_ORIGIN][xfield];
+
+            if (self._isEqual(originValue, xValue, xScale)) {
+              tmp.push(obj);
+            }
+          });
+        }); // special for pie chart
+
+        if (this.hasAdjust('stack') && coord.isPolar && coord.transposed) {
+          if (invertPointX >= 0 && invertPointX <= 1) {
+            var yValue = yScale.invert(invertPoint.y);
+            yValue = self._getSnap(yScale, yValue, tmp);
+            tmp.forEach(function (obj) {
+              if (isArray(yValue) ? obj[FIELD_ORIGIN_Y].toString() === yValue.toString() : obj[FIELD_ORIGIN_Y] === yValue) {
+                rst.push(obj);
+              }
+            });
+          }
+        } else {
+          rst = tmp;
+        }
+
+        return rst;
+      }
+
+      getRecords(value) {
+        var _this = this;
+
+        var xScale = this.getXScale();
+        var dataArray = this.get('dataArray');
+        var xfield = xScale.field;
+        return dataArray.map(function (data) {
+          for (var len = data.length, i = len - 1; i >= 0; i--) {
+            var obj = data[i];
+            var originValue = isNil(obj[FIELD_ORIGIN]) ? obj[xfield] : obj[FIELD_ORIGIN][xfield];
+
+            if (_this._isEqual(originValue, value, xScale)) {
+              return obj;
+            }
+          }
+
+          return null;
+        });
+      }
+
+      _isEqual(originValue, value, scale) {
+        if (scale.type === 'timeCat') {
+          return toTimeStamp(originValue) === value;
+        }
+
+        return value === originValue;
+      }
+
+      position(field) {
+        this._setAttrOptions('position', {
+          field
+        });
+
+        return this;
+      }
+
+      color(field, values) {
+        this._createAttrOption('color', field, values, Global.colors);
+
+        return this;
+      }
+
+      size(field, values) {
+        this._createAttrOption('size', field, values, Global.sizes);
+
+        return this;
+      }
+
+      shape(field, values) {
+        var type = this.get('type');
+        var shapes = Global.shapes[type] || [];
+
+        this._createAttrOption('shape', field, values, shapes);
+
+        return this;
+      }
+
+      style(field, cfg) {
+        var styleOptions = this.get('styleOptions');
+
+        if (!styleOptions) {
+          styleOptions = {};
+          this.set('styleOptions', styleOptions);
+        }
+
+        if (isObject(field)) {
+          cfg = field;
+          field = null;
+        }
+
+        var fields;
+
+        if (field) {
+          fields = parseFields(field);
+        }
+
+        styleOptions.fields = fields;
+        styleOptions.style = cfg;
+        return this;
+      }
+
+      adjust(type) {
+        if (isString(type)) {
+          type = {
+            type
+          };
+        }
+
+        this.set('adjust', type);
+        return this;
+      }
+
+      animate(cfg) {
+        this.set('animateCfg', cfg);
+        return this;
+      }
+
+      changeData(data) {
+        this.set('data', data); // 改变数据后,情况度量,因为需要重新实例化
+
+        this.set('scales', {});
+        if (!this.get('isInit')) return;
+        this.set('isInit', false);
+        this.init();
+      }
+
+      clearInner() {
+        var container = this.get('container');
+
+        if (container) {
+          container.clear(); // container.setMatrix([ 1, 0, 0, 1, 0, 0 ]);
+        }
+      }
+
+      reset() {
+        this.set('isInit', false);
+        this.set('attrs', {});
+        this.set('attrOptions', {});
+        this.set('adjust', null);
+        this.clearInner();
+      }
+
+      clear() {
+        this.clearInner();
+      }
+
+      destroy() {
+        this.set('isInit', false);
+        this.clear();
+        super.destroy();
+      }
+
+      _display(visible) {
+        this.set('visible', visible);
+        var container = this.get('container');
+        var canvas = container.get('canvas');
+        container.set('visible', visible);
+        canvas.draw();
+      }
+
+      show() {
+        this._display(true);
+      }
+
+      hide() {
+        this._display(false);
+      }
+
+    }
+
+    var methodCache = {};
+    /**
+     * 获取计算 ticks 的方法
+     * @param key 键值
+     * @returns 计算 ticks 的方法
+     */
+    function getTickMethod(key) {
+        return methodCache[key];
+    }
+    /**
+     * 注册计算 ticks 的方法
+     * @param key 键值
+     * @param method 方法
+     */
+    function registerTickMethod(key, method) {
+        methodCache[key] = method;
+    }
+
+    var Scale = /** @class */ (function () {
+        function Scale(cfg) {
+            /**
+             * 度量的类型
+             */
+            this.type = 'base';
+            /**
+             * 是否分类类型的度量
+             */
+            this.isCategory = false;
+            /**
+             * 是否线性度量,有linear, time 度量
+             */
+            this.isLinear = false;
+            /**
+             * 是否连续类型的度量,linear,time,log, pow, quantile, quantize 都支持
+             */
+            this.isContinuous = false;
+            /**
+             * 是否是常量的度量,传入和传出一致
+             */
+            this.isIdentity = false;
+            this.values = [];
+            this.range = [0, 1];
+            this.ticks = [];
+            this.__cfg__ = cfg;
+            this.initCfg();
+            this.init();
+        }
+        // 对于原始值的必要转换,如分类、时间字段需转换成数值,用transform/map命名可能更好
+        Scale.prototype.translate = function (v) {
+            return v;
+        };
+        /** 重新初始化 */
+        Scale.prototype.change = function (cfg) {
+            // 覆盖配置项,而不替代
+            mix(this.__cfg__, cfg);
+            this.init();
+        };
+        Scale.prototype.clone = function () {
+            return this.constructor(this.__cfg__);
+        };
+        /** 获取坐标轴需要的ticks */
+        Scale.prototype.getTicks = function () {
+            var _this = this;
+            return map(this.ticks, function (tick, idx) {
+                if (isObject(tick)) {
+                    // 仅当符合Tick类型时才有意义
+                    return tick;
+                }
+                return {
+                    text: _this.getText(tick, idx),
+                    tickValue: tick,
+                    value: _this.scale(tick), // scaled
+                };
+            });
+        };
+        /** 获取Tick的格式化结果 */
+        Scale.prototype.getText = function (value, key) {
+            var formatter = this.formatter;
+            var res = formatter ? formatter(value, key) : value;
+            if (isNil(res) || !isFunction(res.toString)) {
+                return '';
+            }
+            return res.toString();
+        };
+        // 获取配置项中的值,当前 scale 上的值可能会被修改
+        Scale.prototype.getConfig = function (key) {
+            return this.__cfg__[key];
+        };
+        // scale初始化
+        Scale.prototype.init = function () {
+            mix(this, this.__cfg__);
+            this.setDomain();
+            if (isEmpty(this.getConfig('ticks'))) {
+                this.ticks = this.calculateTicks();
+            }
+        };
+        // 子类上覆盖某些属性,不能直接在类上声明,否则会被覆盖
+        Scale.prototype.initCfg = function () { };
+        Scale.prototype.setDomain = function () { };
+        Scale.prototype.calculateTicks = function () {
+            var tickMethod = this.tickMethod;
+            var ticks = [];
+            if (isString(tickMethod)) {
+                var method = getTickMethod(tickMethod);
+                if (!method) {
+                    throw new Error('There is no method to to calculate ticks!');
+                }
+                ticks = method(this);
+            }
+            else if (isFunction(tickMethod)) {
+                ticks = tickMethod(this);
+            }
+            return ticks;
+        };
+        // range 的最小值
+        Scale.prototype.rangeMin = function () {
+            return this.range[0];
+        };
+        // range 的最大值
+        Scale.prototype.rangeMax = function () {
+            return this.range[1];
+        };
+        /** 定义域转 0~1 */
+        Scale.prototype.calcPercent = function (value, min, max) {
+            if (isNumber(value)) {
+                return (value - min) / (max - min);
+            }
+            return NaN;
+        };
+        /** 0~1转定义域 */
+        Scale.prototype.calcValue = function (percent, min, max) {
+            return min + percent * (max - min);
+        };
+        return Scale;
+    }());
+
+    /**
+     * 分类度量
+     * @class
+     */
+    var Category = /** @class */ (function (_super) {
+        __extends(Category, _super);
+        function Category() {
+            var _this = _super !== null && _super.apply(this, arguments) || this;
+            _this.type = 'cat';
+            _this.isCategory = true;
+            return _this;
+        }
+        Category.prototype.buildIndexMap = function () {
+            if (!this.translateIndexMap) {
+                this.translateIndexMap = new Map();
+                // 重新构建缓存
+                for (var i = 0; i < this.values.length; i++) {
+                    this.translateIndexMap.set(this.values[i], i);
+                }
+            }
+        };
+        Category.prototype.translate = function (value) {
+            // 按需构建 map
+            this.buildIndexMap();
+            // 找得到
+            var idx = this.translateIndexMap.get(value);
+            if (idx === undefined) {
+                idx = isNumber(value) ? value : NaN;
+            }
+            return idx;
+        };
+        Category.prototype.scale = function (value) {
+            var order = this.translate(value);
+            // 分类数据允许 0.5 范围内调整
+            // if (order < this.min - 0.5 || order > this.max + 0.5) {
+            //   return NaN;
+            // }
+            var percent = this.calcPercent(order, this.min, this.max);
+            return this.calcValue(percent, this.rangeMin(), this.rangeMax());
+        };
+        Category.prototype.invert = function (scaledValue) {
+            var domainRange = this.max - this.min;
+            var percent = this.calcPercent(scaledValue, this.rangeMin(), this.rangeMax());
+            var idx = Math.round(domainRange * percent) + this.min;
+            if (idx < this.min || idx > this.max) {
+                return NaN;
+            }
+            return this.values[idx];
+        };
+        Category.prototype.getText = function (value) {
+            var args = [];
+            for (var _i = 1; _i < arguments.length; _i++) {
+                args[_i - 1] = arguments[_i];
+            }
+            var v = value;
+            // value为index
+            if (isNumber(value) && !this.values.includes(value)) {
+                v = this.values[v];
+            }
+            return _super.prototype.getText.apply(this, __spreadArray([v], args, false));
+        };
+        // 复写属性
+        Category.prototype.initCfg = function () {
+            this.tickMethod = 'cat';
+        };
+        // 设置 min, max
+        Category.prototype.setDomain = function () {
+            // 用户有可能设置 min
+            if (isNil(this.getConfig('min'))) {
+                this.min = 0;
+            }
+            if (isNil(this.getConfig('max'))) {
+                var size = this.values.length;
+                this.max = size > 1 ? size - 1 : size;
+            }
+            // scale.init 的时候清除缓存
+            if (this.translateIndexMap) {
+                this.translateIndexMap = undefined;
+            }
+        };
+        return Category;
+    }(Scale));
+
+    var token = /d{1,4}|M{1,4}|YY(?:YY)?|S{1,3}|Do|ZZ|Z|([HhMsDm])\1?|[aA]|"[^"]*"|'[^']*'/g;
+    var twoDigitsOptional = "[1-9]\\d?";
+    var twoDigits = "\\d\\d";
+    var threeDigits = "\\d{3}";
+    var fourDigits = "\\d{4}";
+    var word = "[^\\s]+";
+    var literal = /\[([^]*?)\]/gm;
+    function shorten(arr, sLen) {
+        var newArr = [];
+        for (var i = 0, len = arr.length; i < len; i++) {
+            newArr.push(arr[i].substr(0, sLen));
+        }
+        return newArr;
+    }
+    var monthUpdate = function (arrName) { return function (v, i18n) {
+        var lowerCaseArr = i18n[arrName].map(function (v) { return v.toLowerCase(); });
+        var index = lowerCaseArr.indexOf(v.toLowerCase());
+        if (index > -1) {
+            return index;
+        }
+        return null;
+    }; };
+    function assign(origObj) {
+        var args = [];
+        for (var _i = 1; _i < arguments.length; _i++) {
+            args[_i - 1] = arguments[_i];
+        }
+        for (var _a = 0, args_1 = args; _a < args_1.length; _a++) {
+            var obj = args_1[_a];
+            for (var key in obj) {
+                // @ts-ignore ex
+                origObj[key] = obj[key];
+            }
+        }
+        return origObj;
+    }
+    var dayNames = [
+        "Sunday",
+        "Monday",
+        "Tuesday",
+        "Wednesday",
+        "Thursday",
+        "Friday",
+        "Saturday"
+    ];
+    var monthNames = [
+        "January",
+        "February",
+        "March",
+        "April",
+        "May",
+        "June",
+        "July",
+        "August",
+        "September",
+        "October",
+        "November",
+        "December"
+    ];
+    var monthNamesShort = shorten(monthNames, 3);
+    var dayNamesShort = shorten(dayNames, 3);
+    var defaultI18n = {
+        dayNamesShort: dayNamesShort,
+        dayNames: dayNames,
+        monthNamesShort: monthNamesShort,
+        monthNames: monthNames,
+        amPm: ["am", "pm"],
+        DoFn: function (dayOfMonth) {
+            return (dayOfMonth +
+                ["th", "st", "nd", "rd"][dayOfMonth % 10 > 3
+                    ? 0
+                    : ((dayOfMonth - (dayOfMonth % 10) !== 10 ? 1 : 0) * dayOfMonth) % 10]);
+        }
+    };
+    var globalI18n = assign({}, defaultI18n);
+    var setGlobalDateI18n = function (i18n) {
+        return (globalI18n = assign(globalI18n, i18n));
+    };
+    var regexEscape = function (str) {
+        return str.replace(/[|\\{()[^$+*?.-]/g, "\\$&");
+    };
+    var pad = function (val, len) {
+        if (len === void 0) { len = 2; }
+        val = String(val);
+        while (val.length < len) {
+            val = "0" + val;
+        }
+        return val;
+    };
+    var formatFlags = {
+        D: function (dateObj) { return String(dateObj.getDate()); },
+        DD: function (dateObj) { return pad(dateObj.getDate()); },
+        Do: function (dateObj, i18n) {
+            return i18n.DoFn(dateObj.getDate());
+        },
+        d: function (dateObj) { return String(dateObj.getDay()); },
+        dd: function (dateObj) { return pad(dateObj.getDay()); },
+        ddd: function (dateObj, i18n) {
+            return i18n.dayNamesShort[dateObj.getDay()];
+        },
+        dddd: function (dateObj, i18n) {
+            return i18n.dayNames[dateObj.getDay()];
+        },
+        M: function (dateObj) { return String(dateObj.getMonth() + 1); },
+        MM: function (dateObj) { return pad(dateObj.getMonth() + 1); },
+        MMM: function (dateObj, i18n) {
+            return i18n.monthNamesShort[dateObj.getMonth()];
+        },
+        MMMM: function (dateObj, i18n) {
+            return i18n.monthNames[dateObj.getMonth()];
+        },
+        YY: function (dateObj) {
+            return pad(String(dateObj.getFullYear()), 4).substr(2);
+        },
+        YYYY: function (dateObj) { return pad(dateObj.getFullYear(), 4); },
+        h: function (dateObj) { return String(dateObj.getHours() % 12 || 12); },
+        hh: function (dateObj) { return pad(dateObj.getHours() % 12 || 12); },
+        H: function (dateObj) { return String(dateObj.getHours()); },
+        HH: function (dateObj) { return pad(dateObj.getHours()); },
+        m: function (dateObj) { return String(dateObj.getMinutes()); },
+        mm: function (dateObj) { return pad(dateObj.getMinutes()); },
+        s: function (dateObj) { return String(dateObj.getSeconds()); },
+        ss: function (dateObj) { return pad(dateObj.getSeconds()); },
+        S: function (dateObj) {
+            return String(Math.round(dateObj.getMilliseconds() / 100));
+        },
+        SS: function (dateObj) {
+            return pad(Math.round(dateObj.getMilliseconds() / 10), 2);
+        },
+        SSS: function (dateObj) { return pad(dateObj.getMilliseconds(), 3); },
+        a: function (dateObj, i18n) {
+            return dateObj.getHours() < 12 ? i18n.amPm[0] : i18n.amPm[1];
+        },
+        A: function (dateObj, i18n) {
+            return dateObj.getHours() < 12
+                ? i18n.amPm[0].toUpperCase()
+                : i18n.amPm[1].toUpperCase();
+        },
+        ZZ: function (dateObj) {
+            var offset = dateObj.getTimezoneOffset();
+            return ((offset > 0 ? "-" : "+") +
+                pad(Math.floor(Math.abs(offset) / 60) * 100 + (Math.abs(offset) % 60), 4));
+        },
+        Z: function (dateObj) {
+            var offset = dateObj.getTimezoneOffset();
+            return ((offset > 0 ? "-" : "+") +
+                pad(Math.floor(Math.abs(offset) / 60), 2) +
+                ":" +
+                pad(Math.abs(offset) % 60, 2));
+        }
+    };
+    var monthParse = function (v) { return +v - 1; };
+    var emptyDigits = [null, twoDigitsOptional];
+    var emptyWord = [null, word];
+    var amPm = [
+        "isPm",
+        word,
+        function (v, i18n) {
+            var val = v.toLowerCase();
+            if (val === i18n.amPm[0]) {
+                return 0;
+            }
+            else if (val === i18n.amPm[1]) {
+                return 1;
+            }
+            return null;
+        }
+    ];
+    var timezoneOffset = [
+        "timezoneOffset",
+        "[^\\s]*?[\\+\\-]\\d\\d:?\\d\\d|[^\\s]*?Z?",
+        function (v) {
+            var parts = (v + "").match(/([+-]|\d\d)/gi);
+            if (parts) {
+                var minutes = +parts[1] * 60 + parseInt(parts[2], 10);
+                return parts[0] === "+" ? minutes : -minutes;
+            }
+            return 0;
+        }
+    ];
+    var parseFlags = {
+        D: ["day", twoDigitsOptional],
+        DD: ["day", twoDigits],
+        Do: ["day", twoDigitsOptional + word, function (v) { return parseInt(v, 10); }],
+        M: ["month", twoDigitsOptional, monthParse],
+        MM: ["month", twoDigits, monthParse],
+        YY: [
+            "year",
+            twoDigits,
+            function (v) {
+                var now = new Date();
+                var cent = +("" + now.getFullYear()).substr(0, 2);
+                return +("" + (+v > 68 ? cent - 1 : cent) + v);
+            }
+        ],
+        h: ["hour", twoDigitsOptional, undefined, "isPm"],
+        hh: ["hour", twoDigits, undefined, "isPm"],
+        H: ["hour", twoDigitsOptional],
+        HH: ["hour", twoDigits],
+        m: ["minute", twoDigitsOptional],
+        mm: ["minute", twoDigits],
+        s: ["second", twoDigitsOptional],
+        ss: ["second", twoDigits],
+        YYYY: ["year", fourDigits],
+        S: ["millisecond", "\\d", function (v) { return +v * 100; }],
+        SS: ["millisecond", twoDigits, function (v) { return +v * 10; }],
+        SSS: ["millisecond", threeDigits],
+        d: emptyDigits,
+        dd: emptyDigits,
+        ddd: emptyWord,
+        dddd: emptyWord,
+        MMM: ["month", word, monthUpdate("monthNamesShort")],
+        MMMM: ["month", word, monthUpdate("monthNames")],
+        a: amPm,
+        A: amPm,
+        ZZ: timezoneOffset,
+        Z: timezoneOffset
+    };
+    // Some common format strings
+    var globalMasks = {
+        default: "ddd MMM DD YYYY HH:mm:ss",
+        shortDate: "M/D/YY",
+        mediumDate: "MMM D, YYYY",
+        longDate: "MMMM D, YYYY",
+        fullDate: "dddd, MMMM D, YYYY",
+        isoDate: "YYYY-MM-DD",
+        isoDateTime: "YYYY-MM-DDTHH:mm:ssZ",
+        shortTime: "HH:mm",
+        mediumTime: "HH:mm:ss",
+        longTime: "HH:mm:ss.SSS"
+    };
+    var setGlobalDateMasks = function (masks) { return assign(globalMasks, masks); };
+    /***
+     * Format a date
+     * @method format
+     * @param {Date|number} dateObj
+     * @param {string} mask Format of the date, i.e. 'mm-dd-yy' or 'shortDate'
+     * @returns {string} Formatted date string
+     */
+    var format = function (dateObj, mask, i18n) {
+        if (mask === void 0) { mask = globalMasks["default"]; }
+        if (i18n === void 0) { i18n = {}; }
+        if (typeof dateObj === "number") {
+            dateObj = new Date(dateObj);
+        }
+        if (Object.prototype.toString.call(dateObj) !== "[object Date]" ||
+            isNaN(dateObj.getTime())) {
+            throw new Error("Invalid Date pass to format");
+        }
+        mask = globalMasks[mask] || mask;
+        var literals = [];
+        // Make literals inactive by replacing them with @@@
+        mask = mask.replace(literal, function ($0, $1) {
+            literals.push($1);
+            return "@@@";
+        });
+        var combinedI18nSettings = assign(assign({}, globalI18n), i18n);
+        // Apply formatting rules
+        mask = mask.replace(token, function ($0) {
+            return formatFlags[$0](dateObj, combinedI18nSettings);
+        });
+        // Inline literal values back into the formatted value
+        return mask.replace(/@@@/g, function () { return literals.shift(); });
+    };
+    /**
+     * Parse a date string into a Javascript Date object /
+     * @method parse
+     * @param {string} dateStr Date string
+     * @param {string} format Date parse format
+     * @param {i18n} I18nSettingsOptional Full or subset of I18N settings
+     * @returns {Date|null} Returns Date object. Returns null what date string is invalid or doesn't match format
+     */
+    function parse(dateStr, format, i18n) {
+        if (i18n === void 0) { i18n = {}; }
+        if (typeof format !== "string") {
+            throw new Error("Invalid format in fecha parse");
+        }
+        // Check to see if the format is actually a mask
+        format = globalMasks[format] || format;
+        // Avoid regular expression denial of service, fail early for really long strings
+        // https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS
+        if (dateStr.length > 1000) {
+            return null;
+        }
+        // Default to the beginning of the year.
+        var today = new Date();
+        var dateInfo = {
+            year: today.getFullYear(),
+            month: 0,
+            day: 1,
+            hour: 0,
+            minute: 0,
+            second: 0,
+            millisecond: 0,
+            isPm: null,
+            timezoneOffset: null
+        };
+        var parseInfo = [];
+        var literals = [];
+        // Replace all the literals with @@@. Hopefully a string that won't exist in the format
+        var newFormat = format.replace(literal, function ($0, $1) {
+            literals.push(regexEscape($1));
+            return "@@@";
+        });
+        var specifiedFields = {};
+        var requiredFields = {};
+        // Change every token that we find into the correct regex
+        newFormat = regexEscape(newFormat).replace(token, function ($0) {
+            var info = parseFlags[$0];
+            var field = info[0], regex = info[1], requiredField = info[3];
+            // Check if the person has specified the same field twice. This will lead to confusing results.
+            if (specifiedFields[field]) {
+                throw new Error("Invalid format. " + field + " specified twice in format");
+            }
+            specifiedFields[field] = true;
+            // Check if there are any required fields. For instance, 12 hour time requires AM/PM specified
+            if (requiredField) {
+                requiredFields[requiredField] = true;
+            }
+            parseInfo.push(info);
+            return "(" + regex + ")";
+        });
+        // Check all the required fields are present
+        Object.keys(requiredFields).forEach(function (field) {
+            if (!specifiedFields[field]) {
+                throw new Error("Invalid format. " + field + " is required in specified format");
+            }
+        });
+        // Add back all the literals after
+        newFormat = newFormat.replace(/@@@/g, function () { return literals.shift(); });
+        // Check if the date string matches the format. If it doesn't return null
+        var matches = dateStr.match(new RegExp(newFormat, "i"));
+        if (!matches) {
+            return null;
+        }
+        var combinedI18nSettings = assign(assign({}, globalI18n), i18n);
+        // For each match, call the parser function for that date part
+        for (var i = 1; i < matches.length; i++) {
+            var _a = parseInfo[i - 1], field = _a[0], parser = _a[2];
+            var value = parser
+                ? parser(matches[i], combinedI18nSettings)
+                : +matches[i];
+            // If the parser can't make sense of the value, return null
+            if (value == null) {
+                return null;
+            }
+            dateInfo[field] = value;
+        }
+        if (dateInfo.isPm === 1 && dateInfo.hour != null && +dateInfo.hour !== 12) {
+            dateInfo.hour = +dateInfo.hour + 12;
+        }
+        else if (dateInfo.isPm === 0 && +dateInfo.hour === 12) {
+            dateInfo.hour = 0;
+        }
+        var dateWithoutTZ = new Date(dateInfo.year, dateInfo.month, dateInfo.day, dateInfo.hour, dateInfo.minute, dateInfo.second, dateInfo.millisecond);
+        var validateFields = [
+            ["month", "getMonth"],
+            ["day", "getDate"],
+            ["hour", "getHours"],
+            ["minute", "getMinutes"],
+            ["second", "getSeconds"]
+        ];
+        for (var i = 0, len = validateFields.length; i < len; i++) {
+            // Check to make sure the date field is within the allowed range. Javascript dates allows values
+            // outside the allowed range. If the values don't match the value was invalid
+            if (specifiedFields[validateFields[i][0]] &&
+                dateInfo[validateFields[i][0]] !== dateWithoutTZ[validateFields[i][1]]()) {
+                return null;
+            }
+        }
+        if (dateInfo.timezoneOffset == null) {
+            return dateWithoutTZ;
+        }
+        return new Date(Date.UTC(dateInfo.year, dateInfo.month, dateInfo.day, dateInfo.hour, dateInfo.minute - dateInfo.timezoneOffset, dateInfo.second, dateInfo.millisecond));
+    }
+    var fecha = {
+        format: format,
+        parse: parse,
+        defaultI18n: defaultI18n,
+        setGlobalDateI18n: setGlobalDateI18n,
+        setGlobalDateMasks: setGlobalDateMasks
+    };
+
+    var fecha1 = /*#__PURE__*/Object.freeze({
+        __proto__: null,
+        'default': fecha,
+        assign: assign,
+        format: format,
+        parse: parse,
+        defaultI18n: defaultI18n,
+        setGlobalDateI18n: setGlobalDateI18n,
+        setGlobalDateMasks: setGlobalDateMasks
+    });
+
+    /**
+     * 二分右侧查找
+     * https://github.com/d3/d3-array/blob/master/src/bisector.js
+     */
+    function bisector (getter) {
+        /**
+         * x: 目标值
+         * lo: 起始位置
+         * hi: 结束位置
+         */
+        return function (a, x, _lo, _hi) {
+            var lo = isNil(_lo) ? 0 : _lo;
+            var hi = isNil(_hi) ? a.length : _hi;
+            while (lo < hi) {
+                var mid = (lo + hi) >>> 1;
+                if (getter(a[mid]) > x) {
+                    hi = mid;
+                }
+                else {
+                    lo = mid + 1;
+                }
+            }
+            return lo;
+        };
+    }
+
+    var FORMAT_METHOD = 'format';
+    function timeFormat(time, mask) {
+        var method = fecha1[FORMAT_METHOD] || fecha[FORMAT_METHOD];
+        return method(time, mask);
+    }
+    /**
+     * 转换成时间戳
+     * @param value 时间值
+     */
+    function toTimeStamp$1(value) {
+        if (isString(value)) {
+            if (value.indexOf('T') > 0) {
+                value = new Date(value).getTime();
+            }
+            else {
+                // new Date('2010/01/10') 和 new Date('2010-01-10') 的差别在于:
+                // 如果仅有年月日时,前者是带有时区的: Fri Jan 10 2020 02:40:13 GMT+0800 (中国标准时间)
+                // 后者会格式化成 Sun Jan 10 2010 08:00:00 GMT+0800 (中国标准时间)
+                value = new Date(value.replace(/-/gi, '/')).getTime();
+            }
+        }
+        if (isDate(value)) {
+            value = value.getTime();
+        }
+        return value;
+    }
+    var SECOND = 1000;
+    var MINUTE = 60 * SECOND;
+    var HOUR = 60 * MINUTE;
+    var DAY = 24 * HOUR;
+    var MONTH = DAY * 31;
+    var YEAR = DAY * 365;
+    var intervals = [
+        ['HH:mm:ss', SECOND],
+        ['HH:mm:ss', SECOND * 10],
+        ['HH:mm:ss', SECOND * 30],
+        ['HH:mm', MINUTE],
+        ['HH:mm', MINUTE * 10],
+        ['HH:mm', MINUTE * 30],
+        ['HH', HOUR],
+        ['HH', HOUR * 6],
+        ['HH', HOUR * 12],
+        ['YYYY-MM-DD', DAY],
+        ['YYYY-MM-DD', DAY * 4],
+        ['YYYY-WW', DAY * 7],
+        ['YYYY-MM', MONTH],
+        ['YYYY-MM', MONTH * 4],
+        ['YYYY-MM', MONTH * 6],
+        ['YYYY', DAY * 380], // 借鉴echarts,保证每个周期累加时不会碰到恰巧不够的问题
+    ];
+    function getTickInterval(min, max, tickCount) {
+        var target = (max - min) / tickCount;
+        var idx = bisector(function (o) { return o[1]; })(intervals, target) - 1;
+        var interval = intervals[idx];
+        if (idx < 0) {
+            interval = intervals[0];
+        }
+        else if (idx >= intervals.length) {
+            interval = last(intervals);
+        }
+        return interval;
+    }
+
+    /**
+     * 时间分类度量
+     * @class
+     */
+    var TimeCat = /** @class */ (function (_super) {
+        __extends(TimeCat, _super);
+        function TimeCat() {
+            var _this = _super !== null && _super.apply(this, arguments) || this;
+            _this.type = 'timeCat';
+            return _this;
+        }
+        /**
+         * @override
+         */
+        TimeCat.prototype.translate = function (value) {
+            value = toTimeStamp$1(value);
+            var index = this.values.indexOf(value);
+            if (index === -1) {
+                if (isNumber(value) && value < this.values.length) {
+                    index = value;
+                }
+                else {
+                    index = NaN;
+                }
+            }
+            return index;
+        };
+        /**
+         * 由于时间类型数据需要转换一下,所以复写 getText
+         * @override
+         */
+        TimeCat.prototype.getText = function (value, tickIndex) {
+            var index = this.translate(value);
+            if (index > -1) {
+                var result = this.values[index];
+                var formatter = this.formatter;
+                result = formatter ? formatter(result, tickIndex) : timeFormat(result, this.mask);
+                return result;
+            }
+            return value;
+        };
+        TimeCat.prototype.initCfg = function () {
+            this.tickMethod = 'time-cat';
+            this.mask = 'YYYY-MM-DD';
+            this.tickCount = 7; // 一般时间数据会显示 7, 14, 30 天的数字
+        };
+        TimeCat.prototype.setDomain = function () {
+            var values = this.values;
+            // 针对时间分类类型,会将时间统一转换为时间戳
+            each(values, function (v, i) {
+                values[i] = toTimeStamp$1(v);
+            });
+            values.sort(function (v1, v2) {
+                return v1 - v2;
+            });
+            _super.prototype.setDomain.call(this);
+        };
+        return TimeCat;
+    }(Category));
+
+    /**
+     * 连续度量的基类
+     * @class
+     */
+    var Continuous = /** @class */ (function (_super) {
+        __extends(Continuous, _super);
+        function Continuous() {
+            var _this = _super !== null && _super.apply(this, arguments) || this;
+            _this.isContinuous = true;
+            return _this;
+        }
+        Continuous.prototype.scale = function (value) {
+            if (isNil(value)) {
+                return NaN;
+            }
+            var rangeMin = this.rangeMin();
+            var rangeMax = this.rangeMax();
+            var max = this.max;
+            var min = this.min;
+            if (max === min) {
+                return rangeMin;
+            }
+            var percent = this.getScalePercent(value);
+            return rangeMin + percent * (rangeMax - rangeMin);
+        };
+        Continuous.prototype.init = function () {
+            _super.prototype.init.call(this);
+            // init 完成后保证 min, max 包含 ticks 的范围
+            var ticks = this.ticks;
+            var firstTick = head(ticks);
+            var lastTick = last(ticks);
+            if (firstTick < this.min) {
+                this.min = firstTick;
+            }
+            if (lastTick > this.max) {
+                this.max = lastTick;
+            }
+            // strict-limit 方式
+            if (!isNil(this.minLimit)) {
+                this.min = firstTick;
+            }
+            if (!isNil(this.maxLimit)) {
+                this.max = lastTick;
+            }
+        };
+        Continuous.prototype.setDomain = function () {
+            var _a = getRange(this.values), min = _a.min, max = _a.max;
+            if (isNil(this.min)) {
+                this.min = min;
+            }
+            if (isNil(this.max)) {
+                this.max = max;
+            }
+            if (this.min > this.max) {
+                this.min = min;
+                this.max = max;
+            }
+        };
+        Continuous.prototype.calculateTicks = function () {
+            var _this = this;
+            var ticks = _super.prototype.calculateTicks.call(this);
+            if (!this.nice) {
+                ticks = filter(ticks, function (tick) {
+                    return tick >= _this.min && tick <= _this.max;
+                });
+            }
+            return ticks;
+        };
+        // 计算原始值值占的百分比
+        Continuous.prototype.getScalePercent = function (value) {
+            var max = this.max;
+            var min = this.min;
+            return (value - min) / (max - min);
+        };
+        Continuous.prototype.getInvertPercent = function (value) {
+            return (value - this.rangeMin()) / (this.rangeMax() - this.rangeMin());
+        };
+        return Continuous;
+    }(Scale));
+
+    /**
+     * 线性度量
+     * @class
+     */
+    var Linear = /** @class */ (function (_super) {
+        __extends(Linear, _super);
+        function Linear() {
+            var _this = _super !== null && _super.apply(this, arguments) || this;
+            _this.type = 'linear';
+            _this.isLinear = true;
+            return _this;
+        }
+        Linear.prototype.invert = function (value) {
+            var percent = this.getInvertPercent(value);
+            return this.min + percent * (this.max - this.min);
+        };
+        Linear.prototype.initCfg = function () {
+            this.tickMethod = 'wilkinson-extended';
+            this.nice = false;
+        };
+        return Linear;
+    }(Continuous));
+
+    // 求以a为次幂,结果为b的基数,如 x^^a = b;求x
+    // 虽然数学上 b 不支持负数,但是这里需要支持 负数
+    function calBase(a, b) {
+        var e = Math.E;
+        var value;
+        if (b >= 0) {
+            value = Math.pow(e, Math.log(b) / a); // 使用换底公式求底
+        }
+        else {
+            value = Math.pow(e, Math.log(-b) / a) * -1; // 使用换底公式求底
+        }
+        return value;
+    }
+    function log(a, b) {
+        if (a === 1) {
+            return 1;
+        }
+        return Math.log(b) / Math.log(a);
+    }
+    function getLogPositiveMin(values, base, max) {
+        if (isNil(max)) {
+            max = Math.max.apply(null, values);
+        }
+        var positiveMin = max;
+        each(values, function (value) {
+            if (value > 0 && value < positiveMin) {
+                positiveMin = value;
+            }
+        });
+        if (positiveMin === max) {
+            positiveMin = max / base;
+        }
+        if (positiveMin > 1) {
+            positiveMin = 1;
+        }
+        return positiveMin;
+    }
+
+    /**
+     * Log 度量,处理非均匀分布
+     */
+    var Log = /** @class */ (function (_super) {
+        __extends(Log, _super);
+        function Log() {
+            var _this = _super !== null && _super.apply(this, arguments) || this;
+            _this.type = 'log';
+            return _this;
+        }
+        /**
+         * @override
+         */
+        Log.prototype.invert = function (value) {
+            var base = this.base;
+            var max = log(base, this.max);
+            var rangeMin = this.rangeMin();
+            var range = this.rangeMax() - rangeMin;
+            var min;
+            var positiveMin = this.positiveMin;
+            if (positiveMin) {
+                if (value === 0) {
+                    return 0;
+                }
+                min = log(base, positiveMin / base);
+                var appendPercent = (1 / (max - min)) * range; // 0 到 positiveMin的占比
+                if (value < appendPercent) {
+                    // 落到 0 - positiveMin 之间
+                    return (value / appendPercent) * positiveMin;
+                }
+            }
+            else {
+                min = log(base, this.min);
+            }
+            var percent = (value - rangeMin) / range;
+            var tmp = percent * (max - min) + min;
+            return Math.pow(base, tmp);
+        };
+        Log.prototype.initCfg = function () {
+            this.tickMethod = 'log';
+            this.base = 10;
+            this.tickCount = 6;
+            this.nice = true;
+        };
+        // 设置
+        Log.prototype.setDomain = function () {
+            _super.prototype.setDomain.call(this);
+            var min = this.min;
+            if (min < 0) {
+                throw new Error('When you use log scale, the minimum value must be greater than zero!');
+            }
+            if (min === 0) {
+                this.positiveMin = getLogPositiveMin(this.values, this.base, this.max);
+            }
+        };
+        // 根据当前值获取占比
+        Log.prototype.getScalePercent = function (value) {
+            var max = this.max;
+            var min = this.min;
+            if (max === min) {
+                return 0;
+            }
+            // 如果值小于等于0,则按照0处理
+            if (value <= 0) {
+                return 0;
+            }
+            var base = this.base;
+            var positiveMin = this.positiveMin;
+            // 如果min == 0, 则根据比0大的最小值,计算比例关系。这个最小值作为坐标轴上的第二个tick,第一个是0但是不显示
+            if (positiveMin) {
+                min = (positiveMin * 1) / base;
+            }
+            var percent;
+            // 如果数值小于次小值,那么就计算 value / 次小值 占整体的比例
+            if (value < positiveMin) {
+                percent = value / positiveMin / (log(base, max) - log(base, min));
+            }
+            else {
+                percent = (log(base, value) - log(base, min)) / (log(base, max) - log(base, min));
+            }
+            return percent;
+        };
+        return Log;
+    }(Continuous));
+
+    /**
+     * Pow 度量,处理非均匀分布
+     */
+    var Pow = /** @class */ (function (_super) {
+        __extends(Pow, _super);
+        function Pow() {
+            var _this = _super !== null && _super.apply(this, arguments) || this;
+            _this.type = 'pow';
+            return _this;
+        }
+        /**
+         * @override
+         */
+        Pow.prototype.invert = function (value) {
+            var percent = this.getInvertPercent(value);
+            var exponent = this.exponent;
+            var max = calBase(exponent, this.max);
+            var min = calBase(exponent, this.min);
+            var tmp = percent * (max - min) + min;
+            var factor = tmp >= 0 ? 1 : -1;
+            return Math.pow(tmp, exponent) * factor;
+        };
+        Pow.prototype.initCfg = function () {
+            this.tickMethod = 'pow';
+            this.exponent = 2;
+            this.tickCount = 5;
+            this.nice = true;
+        };
+        // 获取度量计算时,value占的定义域百分比
+        Pow.prototype.getScalePercent = function (value) {
+            var max = this.max;
+            var min = this.min;
+            if (max === min) {
+                return 0;
+            }
+            var exponent = this.exponent;
+            var percent = (calBase(exponent, value) - calBase(exponent, min)) / (calBase(exponent, max) - calBase(exponent, min));
+            return percent;
+        };
+        return Pow;
+    }(Continuous));
+
+    /**
+     * 时间度量
+     * @class
+     */
+    var Time = /** @class */ (function (_super) {
+        __extends(Time, _super);
+        function Time() {
+            var _this = _super !== null && _super.apply(this, arguments) || this;
+            _this.type = 'time';
+            return _this;
+        }
+        /**
+         * @override
+         */
+        Time.prototype.getText = function (value, index) {
+            var numberValue = this.translate(value);
+            var formatter = this.formatter;
+            return formatter ? formatter(numberValue, index) : timeFormat(numberValue, this.mask);
+        };
+        /**
+         * @override
+         */
+        Time.prototype.scale = function (value) {
+            var v = value;
+            if (isString(v) || isDate(v)) {
+                v = this.translate(v);
+            }
+            return _super.prototype.scale.call(this, v);
+        };
+        /**
+         * 将时间转换成数字
+         * @override
+         */
+        Time.prototype.translate = function (v) {
+            return toTimeStamp$1(v);
+        };
+        Time.prototype.initCfg = function () {
+            this.tickMethod = 'time-pretty';
+            this.mask = 'YYYY-MM-DD';
+            this.tickCount = 7;
+            this.nice = false;
+        };
+        Time.prototype.setDomain = function () {
+            var values = this.values;
+            // 是否设置了 min, max,而不是直接取 this.min, this.max
+            var minConfig = this.getConfig('min');
+            var maxConfig = this.getConfig('max');
+            // 如果设置了 min,max 则转换成时间戳
+            if (!isNil(minConfig) || !isNumber(minConfig)) {
+                this.min = this.translate(this.min);
+            }
+            if (!isNil(maxConfig) || !isNumber(maxConfig)) {
+                this.max = this.translate(this.max);
+            }
+            // 没有设置 min, max 时
+            if (values && values.length) {
+                // 重新计算最大最小值
+                var timeStamps_1 = [];
+                var min_1 = Infinity; // 最小值
+                var secondMin_1 = min_1; // 次小值
+                var max_1 = 0;
+                // 使用一个循环,计算min,max,secondMin
+                each(values, function (v) {
+                    var timeStamp = toTimeStamp$1(v);
+                    if (isNaN(timeStamp)) {
+                        throw new TypeError("Invalid Time: " + v + " in time scale!");
+                    }
+                    if (min_1 > timeStamp) {
+                        secondMin_1 = min_1;
+                        min_1 = timeStamp;
+                    }
+                    else if (secondMin_1 > timeStamp) {
+                        secondMin_1 = timeStamp;
+                    }
+                    if (max_1 < timeStamp) {
+                        max_1 = timeStamp;
+                    }
+                    timeStamps_1.push(timeStamp);
+                });
+                // 存在多个值时,设置最小间距
+                if (values.length > 1) {
+                    this.minTickInterval = secondMin_1 - min_1;
+                }
+                if (isNil(minConfig)) {
+                    this.min = min_1;
+                }
+                if (isNil(maxConfig)) {
+                    this.max = max_1;
+                }
+            }
+        };
+        return Time;
+    }(Linear));
+
+    /**
+     * 分段度量
+     */
+    var Quantize = /** @class */ (function (_super) {
+        __extends(Quantize, _super);
+        function Quantize() {
+            var _this = _super !== null && _super.apply(this, arguments) || this;
+            _this.type = 'quantize';
+            return _this;
+        }
+        Quantize.prototype.invert = function (value) {
+            var ticks = this.ticks;
+            var length = ticks.length;
+            var percent = this.getInvertPercent(value);
+            var minIndex = Math.floor(percent * (length - 1));
+            // 最后一个
+            if (minIndex >= length - 1) {
+                return last(ticks);
+            }
+            // 超出左边界, 则取第一个
+            if (minIndex < 0) {
+                return head(ticks);
+            }
+            var minTick = ticks[minIndex];
+            var nextTick = ticks[minIndex + 1];
+            // 比当前值小的 tick 在度量上的占比
+            var minIndexPercent = minIndex / (length - 1);
+            var maxIndexPercent = (minIndex + 1) / (length - 1);
+            return minTick + (percent - minIndexPercent) / (maxIndexPercent - minIndexPercent) * (nextTick - minTick);
+        };
+        Quantize.prototype.initCfg = function () {
+            this.tickMethod = 'r-pretty';
+            this.tickCount = 5;
+            this.nice = true;
+        };
+        Quantize.prototype.calculateTicks = function () {
+            var ticks = _super.prototype.calculateTicks.call(this);
+            if (!this.nice) { // 如果 nice = false ,补充 min, max
+                if (last(ticks) !== this.max) {
+                    ticks.push(this.max);
+                }
+                if (head(ticks) !== this.min) {
+                    ticks.unshift(this.min);
+                }
+            }
+            return ticks;
+        };
+        // 计算当前值在刻度中的占比
+        Quantize.prototype.getScalePercent = function (value) {
+            var ticks = this.ticks;
+            // 超出左边界
+            if (value < head(ticks)) {
+                return 0;
+            }
+            // 超出右边界
+            if (value > last(ticks)) {
+                return 1;
+            }
+            var minIndex = 0;
+            each(ticks, function (tick, index) {
+                if (value >= tick) {
+                    minIndex = index;
+                }
+                else {
+                    return false;
+                }
+            });
+            return minIndex / (ticks.length - 1);
+        };
+        return Quantize;
+    }(Continuous));
+
+    var Quantile = /** @class */ (function (_super) {
+        __extends(Quantile, _super);
+        function Quantile() {
+            var _this = _super !== null && _super.apply(this, arguments) || this;
+            _this.type = 'quantile';
+            return _this;
+        }
+        Quantile.prototype.initCfg = function () {
+            this.tickMethod = 'quantile';
+            this.tickCount = 5;
+            this.nice = true;
+        };
+        return Quantile;
+    }(Quantize));
+
+    var map$2 = {};
+    function getClass(key) {
+        return map$2[key];
+    }
+    function registerClass(key, cls) {
+        if (getClass(key)) {
+            throw new Error("type '" + key + "' existed.");
+        }
+        map$2[key] = cls;
+    }
+
+    /**
+     * identity scale原则上是定义域和值域一致,scale/invert方法也是一致的
+     * 参考R的实现:https://github.com/r-lib/scales/blob/master/R/pal-identity.r
+     * 参考d3的实现(做了下转型):https://github.com/d3/d3-scale/blob/master/src/identity.js
+     */
+    var Identity = /** @class */ (function (_super) {
+        __extends(Identity, _super);
+        function Identity() {
+            var _this = _super !== null && _super.apply(this, arguments) || this;
+            _this.type = 'identity';
+            _this.isIdentity = true;
+            return _this;
+        }
+        Identity.prototype.calculateTicks = function () {
+            return this.values;
+        };
+        Identity.prototype.scale = function (value) {
+            // 如果传入的值不等于 identity 的值,则直接返回,用于一维图时的 dodge
+            if (this.values[0] !== value && isNumber(value)) {
+                return value;
+            }
+            return this.range[0];
+        };
+        Identity.prototype.invert = function (value) {
+            var range = this.range;
+            if (value < range[0] || value > range[1]) {
+                return NaN;
+            }
+            return this.values[0];
+        };
+        return Identity;
+    }(Scale));
+
+    // 为了解决 js 运算的精度问题
+    function prettyNumber(n) {
+        return Math.abs(n) < 1e-15 ? n : parseFloat(n.toFixed(15));
+    }
+
+    var DEFAULT_Q = [1, 5, 2, 2.5, 4, 3];
+    var eps = Number.EPSILON * 100;
+    function mod$1(n, m) {
+        return ((n % m) + m) % m;
+    }
+    function round(n) {
+        return Math.round(n * 1e12) / 1e12;
+    }
+    function simplicity(q, Q, j, lmin, lmax, lstep) {
+        var n = size(Q);
+        var i = indexOf$1(Q, q);
+        var v = 0;
+        var m = mod$1(lmin, lstep);
+        if ((m < eps || lstep - m < eps) && lmin <= 0 && lmax >= 0) {
+            v = 1;
+        }
+        return 1 - i / (n - 1) - j + v;
+    }
+    function simplicityMax(q, Q, j) {
+        var n = size(Q);
+        var i = indexOf$1(Q, q);
+        var v = 1;
+        return 1 - i / (n - 1) - j + v;
+    }
+    function density(k, m, dMin, dMax, lMin, lMax) {
+        var r = (k - 1) / (lMax - lMin);
+        var rt = (m - 1) / (Math.max(lMax, dMax) - Math.min(dMin, lMin));
+        return 2 - Math.max(r / rt, rt / r);
+    }
+    function densityMax(k, m) {
+        if (k >= m) {
+            return 2 - (k - 1) / (m - 1);
+        }
+        return 1;
+    }
+    function coverage(dMin, dMax, lMin, lMax) {
+        var range = dMax - dMin;
+        return 1 - (0.5 * (Math.pow((dMax - lMax), 2) + Math.pow((dMin - lMin), 2))) / Math.pow((0.1 * range), 2);
+    }
+    function coverageMax(dMin, dMax, span) {
+        var range = dMax - dMin;
+        if (span > range) {
+            var half = (span - range) / 2;
+            return 1 - Math.pow(half, 2) / Math.pow((0.1 * range), 2);
+        }
+        return 1;
+    }
+    function legibility() {
+        return 1;
+    }
+    /**
+     * An Extension of Wilkinson's Algorithm for Position Tick Labels on Axes
+     * https://www.yuque.com/preview/yuque/0/2019/pdf/185317/1546999150858-45c3b9c2-4e86-4223-bf1a-8a732e8195ed.pdf
+     * @param dMin 最小值
+     * @param dMax 最大值
+     * @param m tick个数
+     * @param onlyLoose 是否允许扩展min、max,不绝对强制,例如[3, 97]
+     * @param Q nice numbers集合
+     * @param w 四个优化组件的权重
+     */
+    function extended(dMin, dMax, n, onlyLoose, Q, w) {
+        if (n === void 0) { n = 5; }
+        if (onlyLoose === void 0) { onlyLoose = true; }
+        if (Q === void 0) { Q = DEFAULT_Q; }
+        if (w === void 0) { w = [0.25, 0.2, 0.5, 0.05]; }
+        // 处理小于 0 和小数的 tickCount
+        var m = n < 0 ? 0 : Math.round(n);
+        // nan 也会导致异常
+        if (Number.isNaN(dMin) || Number.isNaN(dMax) || typeof dMin !== 'number' || typeof dMax !== 'number' || !m) {
+            return {
+                min: 0,
+                max: 0,
+                ticks: [],
+            };
+        }
+        // js 极大值极小值问题,差值小于 1e-15 会导致计算出错
+        if (dMax - dMin < 1e-15 || m === 1) {
+            return {
+                min: dMin,
+                max: dMax,
+                ticks: [dMin],
+            };
+        }
+        var best = {
+            score: -2,
+            lmin: 0,
+            lmax: 0,
+            lstep: 0,
+        };
+        var j = 1;
+        while (j < Infinity) {
+            for (var i = 0; i < Q.length; i += 1) {
+                var q = Q[i];
+                var sm = simplicityMax(q, Q, j);
+                if (w[0] * sm + w[1] + w[2] + w[3] < best.score) {
+                    j = Infinity;
+                    break;
+                }
+                var k = 2;
+                while (k < Infinity) {
+                    var dm = densityMax(k, m);
+                    if (w[0] * sm + w[1] + w[2] * dm + w[3] < best.score) {
+                        break;
+                    }
+                    var delta = (dMax - dMin) / (k + 1) / j / q;
+                    var z = Math.ceil(Math.log10(delta));
+                    while (z < Infinity) {
+                        var step = j * q * Math.pow(10, z);
+                        var cm = coverageMax(dMin, dMax, step * (k - 1));
+                        if (w[0] * sm + w[1] * cm + w[2] * dm + w[3] < best.score) {
+                            break;
+                        }
+                        var minStart = Math.floor(dMax / step) * j - (k - 1) * j;
+                        var maxStart = Math.ceil(dMin / step) * j;
+                        if (minStart <= maxStart) {
+                            var count = maxStart - minStart;
+                            for (var i_1 = 0; i_1 <= count; i_1 += 1) {
+                                var start = minStart + i_1;
+                                var lMin = start * (step / j);
+                                var lMax = lMin + step * (k - 1);
+                                var lStep = step;
+                                var s = simplicity(q, Q, j, lMin, lMax, lStep);
+                                var c = coverage(dMin, dMax, lMin, lMax);
+                                var g = density(k, m, dMin, dMax, lMin, lMax);
+                                var l = legibility();
+                                var score = w[0] * s + w[1] * c + w[2] * g + w[3] * l;
+                                if (score > best.score && (!onlyLoose || (lMin <= dMin && lMax >= dMax))) {
+                                    best.lmin = lMin;
+                                    best.lmax = lMax;
+                                    best.lstep = lStep;
+                                    best.score = score;
+                                }
+                            }
+                        }
+                        z += 1;
+                    }
+                    k += 1;
+                }
+            }
+            j += 1;
+        }
+        // 处理精度问题,保证这三个数没有精度问题
+        var lmax = prettyNumber(best.lmax);
+        var lmin = prettyNumber(best.lmin);
+        var lstep = prettyNumber(best.lstep);
+        // 加 round 是为处理 extended(0.94, 1, 5)
+        // 保证生成的 tickCount 没有精度问题
+        var tickCount = Math.floor(round((lmax - lmin) / lstep)) + 1;
+        var ticks = new Array(tickCount);
+        // 少用乘法:防止出现 -1.2 + 1.2 * 3 = 2.3999999999999995 的情况
+        ticks[0] = prettyNumber(lmin);
+        for (var i = 1; i < tickCount; i++) {
+            ticks[i] = prettyNumber(ticks[i - 1] + lstep);
+        }
+        return {
+            min: Math.min(dMin, head(ticks)),
+            max: Math.max(dMax, last(ticks)),
+            ticks: ticks,
+        };
+    }
+
+    /**
+     * 计算分类 ticks
+     * @param cfg 度量的配置项
+     * @returns 计算后的 ticks
+     */
+    function calculateCatTicks(cfg) {
+        var values = cfg.values, tickInterval = cfg.tickInterval, tickCount = cfg.tickCount;
+        var ticks = values;
+        if (isNumber(tickInterval)) {
+            return filter(ticks, function (__, i) { return i % tickInterval === 0; });
+        }
+        var min = cfg.min, max = cfg.max;
+        if (isNil(min)) {
+            min = 0;
+        }
+        if (isNil(max)) {
+            max = values.length - 1;
+        }
+        if (isNumber(tickCount) && tickCount < max - min) {
+            // 简单过滤,部分情况下小数的倍数也可以是整数
+            // tslint:disable-next-line: no-shadowed-variable
+            var ticks_1 = extended(min, max, tickCount, false, [1, 2, 5, 3, 4, 7, 6, 8, 9]).ticks;
+            var valid = filter(ticks_1, function (tick) { return tick >= min && tick <= max; });
+            return valid.map(function (index) { return values[index]; });
+        }
+        return values.slice(min, max + 1);
+    }
+
+    function d3Linear(cfg) {
+        var min = cfg.min, max = cfg.max, nice = cfg.nice, tickCount = cfg.tickCount;
+        var linear = new D3Linear();
+        linear.domain([min, max]);
+        if (nice) {
+            linear.nice(tickCount);
+        }
+        return linear.ticks(tickCount);
+    }
+    var DEFAULT_COUNT = 5;
+    var e10 = Math.sqrt(50);
+    var e5 = Math.sqrt(10);
+    var e2 = Math.sqrt(2);
+    // https://github.com/d3/d3-scale
+    var D3Linear = /** @class */ (function () {
+        function D3Linear() {
+            this._domain = [0, 1];
+        }
+        D3Linear.prototype.domain = function (domain) {
+            if (domain) {
+                this._domain = Array.from(domain, Number);
+                return this;
+            }
+            return this._domain.slice();
+        };
+        D3Linear.prototype.nice = function (count) {
+            var _a, _b;
+            if (count === void 0) { count = DEFAULT_COUNT; }
+            var d = this._domain.slice();
+            var i0 = 0;
+            var i1 = this._domain.length - 1;
+            var start = this._domain[i0];
+            var stop = this._domain[i1];
+            var step;
+            if (stop < start) {
+                _a = [stop, start], start = _a[0], stop = _a[1];
+                _b = [i1, i0], i0 = _b[0], i1 = _b[1];
+            }
+            step = tickIncrement(start, stop, count);
+            if (step > 0) {
+                start = Math.floor(start / step) * step;
+                stop = Math.ceil(stop / step) * step;
+                step = tickIncrement(start, stop, count);
+            }
+            else if (step < 0) {
+                start = Math.ceil(start * step) / step;
+                stop = Math.floor(stop * step) / step;
+                step = tickIncrement(start, stop, count);
+            }
+            if (step > 0) {
+                d[i0] = Math.floor(start / step) * step;
+                d[i1] = Math.ceil(stop / step) * step;
+                this.domain(d);
+            }
+            else if (step < 0) {
+                d[i0] = Math.ceil(start * step) / step;
+                d[i1] = Math.floor(stop * step) / step;
+                this.domain(d);
+            }
+            return this;
+        };
+        D3Linear.prototype.ticks = function (count) {
+            if (count === void 0) { count = DEFAULT_COUNT; }
+            return d3ArrayTicks(this._domain[0], this._domain[this._domain.length - 1], count || DEFAULT_COUNT);
+        };
+        return D3Linear;
+    }());
+    function d3ArrayTicks(start, stop, count) {
+        var reverse;
+        var i = -1;
+        var n;
+        var ticks;
+        var step;
+        (stop = +stop), (start = +start), (count = +count);
+        if (start === stop && count > 0) {
+            return [start];
+        }
+        // tslint:disable-next-line
+        if ((reverse = stop < start)) {
+            (n = start), (start = stop), (stop = n);
+        }
+        // tslint:disable-next-line
+        if ((step = tickIncrement(start, stop, count)) === 0 || !isFinite(step)) {
+            return [];
+        }
+        if (step > 0) {
+            start = Math.ceil(start / step);
+            stop = Math.floor(stop / step);
+            ticks = new Array((n = Math.ceil(stop - start + 1)));
+            while (++i < n) {
+                ticks[i] = (start + i) * step;
+            }
+        }
+        else {
+            start = Math.floor(start * step);
+            stop = Math.ceil(stop * step);
+            ticks = new Array((n = Math.ceil(start - stop + 1)));
+            while (++i < n) {
+                ticks[i] = (start - i) / step;
+            }
+        }
+        if (reverse) {
+            ticks.reverse();
+        }
+        return ticks;
+    }
+    function tickIncrement(start, stop, count) {
+        var step = (stop - start) / Math.max(0, count);
+        var power = Math.floor(Math.log(step) / Math.LN10);
+        var error = step / Math.pow(10, power);
+        return power >= 0
+            ? (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1) * Math.pow(10, power)
+            : -Math.pow(10, -power) / (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1);
+    }
+
+    function snapMultiple(v, base, snapType) {
+        var div;
+        if (snapType === 'ceil') {
+            div = Math.ceil(v / base);
+        }
+        else if (snapType === 'floor') {
+            div = Math.floor(v / base);
+        }
+        else {
+            div = Math.round(v / base);
+        }
+        return div * base;
+    }
+    function intervalTicks(min, max, interval) {
+        // 变成 interval 的倍数
+        var minTick = snapMultiple(min, interval, 'floor');
+        var maxTick = snapMultiple(max, interval, 'ceil');
+        // 统一小数位数
+        minTick = fixedBase(minTick, interval);
+        maxTick = fixedBase(maxTick, interval);
+        var ticks = [];
+        for (var i = minTick; i <= maxTick; i = i + interval) {
+            var tickValue = fixedBase(i, interval); // 防止浮点数加法出现问题
+            ticks.push(tickValue);
+        }
+        return {
+            min: minTick,
+            max: maxTick,
+            ticks: ticks
+        };
+    }
+
+    /**
+     * 按照给定的 minLimit/maxLimit/tickCount 均匀计算出刻度 ticks
+     *
+     * @param cfg Scale 配置项
+     * @return ticks
+     */
+    function strictLimit(cfg, defaultMin, defaultMax) {
+        var _a;
+        var minLimit = cfg.minLimit, maxLimit = cfg.maxLimit, min = cfg.min, max = cfg.max, _b = cfg.tickCount, tickCount = _b === void 0 ? 5 : _b;
+        var tickMin = isNil(minLimit) ? (isNil(defaultMin) ? min : defaultMin) : minLimit;
+        var tickMax = isNil(maxLimit) ? (isNil(defaultMax) ? max : defaultMax) : maxLimit;
+        if (tickMin > tickMax) {
+            _a = [tickMin, tickMax], tickMax = _a[0], tickMin = _a[1];
+        }
+        if (tickCount <= 2) {
+            return [tickMin, tickMax];
+        }
+        var step = (tickMax - tickMin) / (tickCount - 1);
+        var ticks = [];
+        for (var i = 0; i < tickCount; i++) {
+            ticks.push(tickMin + step * i);
+        }
+        return ticks;
+    }
+
+    function d3LinearTickMethod(cfg) {
+        var min = cfg.min, max = cfg.max, tickInterval = cfg.tickInterval, minLimit = cfg.minLimit, maxLimit = cfg.maxLimit;
+        var ticks = d3Linear(cfg);
+        if (!isNil(minLimit) || !isNil(maxLimit)) {
+            return strictLimit(cfg, head(ticks), last(ticks));
+        }
+        if (tickInterval) {
+            return intervalTicks(min, max, tickInterval).ticks;
+        }
+        return ticks;
+    }
+
+    /**
+     * 计算线性的 ticks,使用 wilkinson extended 方法
+     * @param cfg 度量的配置项
+     * @returns 计算后的 ticks
+     */
+    function linear(cfg) {
+        var min = cfg.min, max = cfg.max, tickCount = cfg.tickCount, nice = cfg.nice, tickInterval = cfg.tickInterval, minLimit = cfg.minLimit, maxLimit = cfg.maxLimit;
+        var ticks = extended(min, max, tickCount, nice).ticks;
+        if (!isNil(minLimit) || !isNil(maxLimit)) {
+            return strictLimit(cfg, head(ticks), last(ticks));
+        }
+        if (tickInterval) {
+            return intervalTicks(min, max, tickInterval).ticks;
+        }
+        return ticks;
+    }
+
+    /**
+     * 计算 log 的 ticks,考虑 min = 0 的场景
+     * @param cfg 度量的配置项
+     * @returns 计算后的 ticks
+     */
+    function calculateLogTicks(cfg) {
+        var base = cfg.base, tickCount = cfg.tickCount, min = cfg.min, max = cfg.max, values = cfg.values;
+        var minTick;
+        var maxTick = log(base, max);
+        if (min > 0) {
+            minTick = Math.floor(log(base, min));
+        }
+        else {
+            var positiveMin = getLogPositiveMin(values, base, max);
+            minTick = Math.floor(log(base, positiveMin));
+        }
+        var count = maxTick - minTick;
+        var avg = Math.ceil(count / tickCount);
+        var ticks = [];
+        for (var i = minTick; i < maxTick + avg; i = i + avg) {
+            ticks.push(Math.pow(base, i));
+        }
+        if (min <= 0) {
+            // 最小值 <= 0 时显示 0
+            ticks.unshift(0);
+        }
+        return ticks;
+    }
+
+    function pretty(min, max, m) {
+        if (m === void 0) { m = 5; }
+        if (min === max) {
+            return {
+                max: max,
+                min: min,
+                ticks: [min],
+            };
+        }
+        var n = m < 0 ? 0 : Math.round(m);
+        if (n === 0)
+            return { max: max, min: min, ticks: [] };
+        /*
+          R pretty:
+          https://svn.r-project.org/R/trunk/src/appl/pretty.c
+          https://www.rdocumentation.org/packages/base/versions/3.5.2/topics/pretty
+          */
+        var h = 1.5; // high.u.bias
+        var h5 = 0.5 + 1.5 * h; // u5.bias
+        // 反正我也不会调参,跳过所有判断步骤
+        var d = max - min;
+        var c = d / n;
+        // 当d非常小的时候触发,但似乎没什么用
+        // const min_n = Math.floor(n / 3);
+        // const shrink_sml = Math.pow(2, 5);
+        // if (Math.log10(d) < -2) {
+        //   c = (_.max([ Math.abs(max), Math.abs(min) ]) * shrink_sml) / min_n;
+        // }
+        var base = Math.pow(10, Math.floor(Math.log10(c)));
+        var unit = base;
+        if (2 * base - c < h * (c - unit)) {
+            unit = 2 * base;
+            if (5 * base - c < h5 * (c - unit)) {
+                unit = 5 * base;
+                if (10 * base - c < h * (c - unit)) {
+                    unit = 10 * base;
+                }
+            }
+        }
+        var nu = Math.ceil(max / unit);
+        var ns = Math.floor(min / unit);
+        var hi = Math.max(nu * unit, max);
+        var lo = Math.min(ns * unit, min);
+        var size = Math.floor((hi - lo) / unit) + 1;
+        var ticks = new Array(size);
+        for (var i = 0; i < size; i++) {
+            ticks[i] = prettyNumber(lo + i * unit);
+        }
+        return {
+            min: lo,
+            max: hi,
+            ticks: ticks,
+        };
+    }
+
+    /**
+     * 计算 Pow 的 ticks
+     * @param cfg 度量的配置项
+     * @returns 计算后的 ticks
+     */
+    function calculatePowTicks(cfg) {
+        var exponent = cfg.exponent, tickCount = cfg.tickCount;
+        var max = Math.ceil(calBase(exponent, cfg.max));
+        var min = Math.floor(calBase(exponent, cfg.min));
+        var ticks = pretty(min, max, tickCount).ticks;
+        return ticks.map(function (tick) {
+            var factor = tick >= 0 ? 1 : -1;
+            return Math.pow(tick, exponent) * factor;
+        });
+    }
+
+    /**
+     * 计算几分位 https://github.com/simple-statistics/simple-statistics/blob/master/src/quantile_sorted.js
+     * @param x  数组
+     * @param p  百分比
+     */
+    function quantileSorted(x, p) {
+        var idx = x.length * p;
+        /*if (x.length === 0) { // 当前场景这些条件不可能命中
+          throw new Error('quantile requires at least one value.');
+        } else if (p < 0 || p > 1) {
+          throw new Error('quantiles must be between 0 and 1');
+        } else */
+        if (p === 1) {
+            // If p is 1, directly return the last element
+            return x[x.length - 1];
+        }
+        else if (p === 0) {
+            // If p is 0, directly return the first element
+            return x[0];
+        }
+        else if (idx % 1 !== 0) {
+            // If p is not integer, return the next element in array
+            return x[Math.ceil(idx) - 1];
+        }
+        else if (x.length % 2 === 0) {
+            // If the list has even-length, we'll take the average of this number
+            // and the next value, if there is one
+            return (x[idx - 1] + x[idx]) / 2;
+        }
+        else {
+            // Finally, in the simple case of an integer value
+            // with an odd-length list, return the x value at the index.
+            return x[idx];
+        }
+    }
+    function calculateTicks(cfg) {
+        var tickCount = cfg.tickCount, values = cfg.values;
+        if (!values || !values.length) {
+            return [];
+        }
+        var sorted = values.slice().sort(function (a, b) {
+            return a - b;
+        });
+        var ticks = [];
+        for (var i = 0; i < tickCount; i++) {
+            var p = i / (tickCount - 1);
+            ticks.push(quantileSorted(sorted, p));
+        }
+        return ticks;
+    }
+
+    /**
+     * 计算线性的 ticks,使用 R's pretty 方法
+     * @param cfg 度量的配置项
+     * @returns 计算后的 ticks
+     */
+    function linearPretty(cfg) {
+        var min = cfg.min, max = cfg.max, tickCount = cfg.tickCount, tickInterval = cfg.tickInterval, minLimit = cfg.minLimit, maxLimit = cfg.maxLimit;
+        var ticks = pretty(min, max, tickCount).ticks;
+        if (!isNil(minLimit) || !isNil(maxLimit)) {
+            return strictLimit(cfg, head(ticks), last(ticks));
+        }
+        if (tickInterval) {
+            return intervalTicks(min, max, tickInterval).ticks;
+        }
+        return ticks;
+    }
+
+    function calculateTimeTicks(cfg) {
+        var min = cfg.min, max = cfg.max, minTickInterval = cfg.minTickInterval;
+        var tickInterval = cfg.tickInterval;
+        var tickCount = cfg.tickCount;
+        // 指定 tickInterval 后 tickCount 不生效,需要重新计算
+        if (tickInterval) {
+            tickCount = Math.ceil((max - min) / tickInterval);
+        }
+        else {
+            tickInterval = getTickInterval(min, max, tickCount)[1];
+            var count = (max - min) / tickInterval;
+            var ratio = count / tickCount;
+            if (ratio > 1) {
+                tickInterval = tickInterval * Math.ceil(ratio);
+            }
+            // 如果设置了最小间距,则使用最小间距
+            if (minTickInterval && tickInterval < minTickInterval) {
+                tickInterval = minTickInterval;
+            }
+        }
+        var ticks = [];
+        for (var i = min; i < max + tickInterval; i += tickInterval) {
+            ticks.push(i);
+        }
+        return ticks;
+    }
+
+    /**
+     * 计算时间分类的 ticks, 保头,保尾
+     * @param cfg 度量的配置项
+     * @returns 计算后的 ticks
+     */
+    function calculateTimeCatTicks(cfg) {
+        var ticks = calculateCatTicks(cfg);
+        var lastValue = last(cfg.values);
+        if (lastValue !== last(ticks)) {
+            ticks.push(lastValue);
+        }
+        return ticks;
+    }
+
+    function getYear(date) {
+        return new Date(date).getFullYear();
+    }
+    function createYear(year) {
+        return new Date(year, 0, 1).getTime();
+    }
+    function getMonth(date) {
+        return new Date(date).getMonth();
+    }
+    function diffMonth(min, max) {
+        var minYear = getYear(min);
+        var maxYear = getYear(max);
+        var minMonth = getMonth(min);
+        var maxMonth = getMonth(max);
+        return (maxYear - minYear) * 12 + ((maxMonth - minMonth) % 12);
+    }
+    function creatMonth(year, month) {
+        return new Date(year, month, 1).getTime();
+    }
+    function diffDay(min, max) {
+        return Math.ceil((max - min) / DAY);
+    }
+    function diffHour(min, max) {
+        return Math.ceil((max - min) / HOUR);
+    }
+    function diffMinus(min, max) {
+        return Math.ceil((max - min) / (60 * 1000));
+    }
+    /**
+     * 计算 time 的 ticks,对 month, year 进行 pretty 处理
+     * @param cfg 度量的配置项
+     * @returns 计算后的 ticks
+     */
+    function timePretty(cfg) {
+        var min = cfg.min, max = cfg.max, minTickInterval = cfg.minTickInterval, tickCount = cfg.tickCount;
+        var tickInterval = cfg.tickInterval;
+        var ticks = [];
+        // 指定 tickInterval 后 tickCount 不生效,需要重新计算
+        if (!tickInterval) {
+            tickInterval = (max - min) / tickCount;
+            // 如果设置了最小间距,则使用最小间距
+            if (minTickInterval && tickInterval < minTickInterval) {
+                tickInterval = minTickInterval;
+            }
+        }
+        var minYear = getYear(min);
+        // 如果间距大于 1 年,则将开始日期从整年开始
+        if (tickInterval > YEAR) {
+            var maxYear = getYear(max);
+            var yearInterval = Math.ceil(tickInterval / YEAR);
+            for (var i = minYear; i <= maxYear + yearInterval; i = i + yearInterval) {
+                ticks.push(createYear(i));
+            }
+        }
+        else if (tickInterval > MONTH) {
+            // 大于月时
+            var monthInterval = Math.ceil(tickInterval / MONTH);
+            var mmMoth = getMonth(min);
+            var dMonths = diffMonth(min, max);
+            for (var i = 0; i <= dMonths + monthInterval; i = i + monthInterval) {
+                ticks.push(creatMonth(minYear, i + mmMoth));
+            }
+        }
+        else if (tickInterval > DAY) {
+            // 大于天
+            var date = new Date(min);
+            var year = date.getFullYear();
+            var month = date.getMonth();
+            var mday = date.getDate();
+            var day = Math.ceil(tickInterval / DAY);
+            var ddays = diffDay(min, max);
+            for (var i = 0; i < ddays + day; i = i + day) {
+                ticks.push(new Date(year, month, mday + i).getTime());
+            }
+        }
+        else if (tickInterval > HOUR) {
+            // 大于小时
+            var date = new Date(min);
+            var year = date.getFullYear();
+            var month = date.getMonth();
+            var day = date.getDate();
+            var hour = date.getHours();
+            var hours = Math.ceil(tickInterval / HOUR);
+            var dHours = diffHour(min, max);
+            for (var i = 0; i <= dHours + hours; i = i + hours) {
+                ticks.push(new Date(year, month, day, hour + i).getTime());
+            }
+        }
+        else if (tickInterval > MINUTE) {
+            // 大于分钟
+            var dMinus = diffMinus(min, max);
+            var minutes = Math.ceil(tickInterval / MINUTE);
+            for (var i = 0; i <= dMinus + minutes; i = i + minutes) {
+                ticks.push(min + i * MINUTE);
+            }
+        }
+        else {
+            // 小于分钟
+            var interval = tickInterval;
+            if (interval < SECOND) {
+                interval = SECOND;
+            }
+            var minSecond = Math.floor(min / SECOND) * SECOND;
+            var dSeconds = Math.ceil((max - min) / SECOND);
+            var seconds = Math.ceil(interval / SECOND);
+            for (var i = 0; i < dSeconds + seconds; i = i + seconds) {
+                ticks.push(minSecond + i * SECOND);
+            }
+        }
+        // 最好是能从算法能解决这个问题,但是如果指定了 tickInterval,计算 ticks,也只能这么算,所以
+        // 打印警告提示
+        if (ticks.length >= 512) {
+            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!");
+        }
+        return ticks;
+    }
+
+    registerTickMethod('cat', calculateCatTicks);
+    registerTickMethod('time-cat', calculateTimeCatTicks);
+    registerTickMethod('wilkinson-extended', linear);
+    registerTickMethod('r-pretty', linearPretty);
+    registerTickMethod('time', calculateTimeTicks);
+    registerTickMethod('time-pretty', timePretty);
+    registerTickMethod('log', calculateLogTicks);
+    registerTickMethod('pow', calculatePowTicks);
+    registerTickMethod('quantile', calculateTicks);
+    registerTickMethod('d3-linear', d3LinearTickMethod);
+
+    registerClass('cat', Category);
+    registerClass('category', Category);
+    registerClass('identity', Identity);
+    registerClass('linear', Linear);
+    registerClass('log', Log);
+    registerClass('pow', Pow);
+    registerClass('time', Time);
+    registerClass('timeCat', TimeCat);
+    registerClass('quantize', Quantize);
+    registerClass('quantile', Quantile);
+
+    // cat平均算法,保头保尾
+    var CatTick = (function (cfg) {
+      var {
+        values,
+        tickCount
+      } = cfg;
+
+      if (!tickCount) {
+        return values;
+      }
+
+      if (values.length <= 1) {
+        return values;
+      } // 获取间隔步长, 最小是1
+
+
+      var step = parseInt(values.length / (tickCount - 1)) || 1;
+      var ticks = []; // 按间隔数取对应节点
+
+      for (var index = 0; index < values.length; index = index + step) {
+        ticks.push(values[index]);
+      }
+
+      var last = values[values.length - 1]; // 如果最后一个tick不等于原数据的最后一个
+
+      if (ticks[ticks.length - 1] !== last) {
+        if (ticks.length >= tickCount) {
+          // 如果当前的tick个数满足要求
+          ticks[ticks.length - 1] = last;
+        } else {
+          // 不满足tickCount则直接加入最后一个
+          ticks.push(last);
+        }
+      }
+
+      return ticks;
+    });
+
+    // 认为是nice的刻度
+    var SNAP_COUNT_ARRAY = [1, 1.2, 1.5, 2, 2.2, 2.4, 2.5, 3, 4, 5, 6, 7.5, 8, 10];
+    var DEFAULT_COUNT$1 = 5; // 默认刻度值
+
+    var LinearTick = (function (cfg) {
+      var {
+        tickCount,
+        tickInterval
+      } = cfg || {};
+      var {
+        min,
+        max
+      } = cfg || {};
+      min = isNaN(min) ? 0 : min;
+      max = isNaN(max) ? 0 : max;
+      var count = tickCount && tickCount >= 2 ? tickCount : DEFAULT_COUNT$1; // 计算interval, 优先取tickInterval
+
+      var interval = tickInterval || getBestInterval({
+        tickCount: count,
+        max,
+        min
+      }); // 通过interval计算最小tick
+
+      var minTick = Math.floor(min / interval) * interval; // 如果指定了tickInterval, count 需要根据指定的tickInterval来算计
+
+      if (tickInterval) {
+        var intervalCount = Math.abs(Math.ceil((max - minTick) / tickInterval)) + 1; // tickCount 作为最小 count 处理
+
+        count = Math.max(count, intervalCount);
+      }
+
+      var ticks = [];
+      var tickLength = 0;
+      var fixedLength = getFixedLength(interval);
+
+      while (tickLength < count) {
+        ticks.push(toFixed(minTick + tickLength * interval, fixedLength));
+        tickLength++;
+      }
+
+      return ticks;
+    });
+    var DECIMAL_LENGTH = 12;
+
+    function getFactor(number) {
+      // 取正数
+      number = Math.abs(number);
+      var factor = 1;
+
+      if (number === 0) {
+        return factor;
+      } // 小于1,逐渐放大
+
+
+      if (number < 1) {
+        var count = 0;
+
+        while (number < 1) {
+          factor = factor / 10;
+          number = number * 10;
+          count++;
+        } // 浮点数计算出现问题
+
+
+        if (factor.toString().length > DECIMAL_LENGTH) {
+          factor = parseFloat(factor.toFixed(count));
+        }
+
+        return factor;
+      } // 大于10逐渐缩小
+
+
+      while (number > 10) {
+        factor = factor * 10;
+        number = number / 10;
+      }
+
+      return factor;
+    } // 获取最佳匹配刻度
+
+
+    function getBestInterval(_ref) {
+      var {
+        tickCount,
+        min,
+        max
+      } = _ref;
+
+      // 如果最大最小相等,则直接按1处理
+      if (min === max) {
+        return 1 * getFactor(max);
+      } // 1.计算平均刻度间隔
+
+
+      var avgInterval = (max - min) / (tickCount - 1); // 2.数据标准归一化 映射到[1-10]区间
+
+      var factor = getFactor(avgInterval);
+      var calInterval = avgInterval / factor;
+      var calMax = max / factor;
+      var calMin = min / factor; // 根据平均值推算最逼近刻度值
+
+      var similarityIndex = 0;
+
+      for (var index = 0; index < SNAP_COUNT_ARRAY.length; index++) {
+        var item = SNAP_COUNT_ARRAY[index];
+
+        if (calInterval <= item) {
+          similarityIndex = index;
+          break;
+        }
+      }
+
+      var similarityInterval = getInterval(similarityIndex, tickCount, calMin, calMax); // 小数点位数还原到数据的位数, 因为similarityIndex有可能是小数,所以需要保留similarityIndex自己的小数位数
+
+      var fixedLength = getFixedLength(similarityInterval) + getFixedLength(factor);
+      return toFixed(similarityInterval * factor, fixedLength);
+    }
+
+    function getInterval(startIndex, tickCount, min, max) {
+      var verify = false;
+      var interval = SNAP_COUNT_ARRAY[startIndex]; // 刻度值校验,如果不满足,循环下去
+
+      for (var i = startIndex; i < SNAP_COUNT_ARRAY.length; i++) {
+        if (intervalIsVerify({
+          interval: SNAP_COUNT_ARRAY[i],
+          tickCount,
+          max,
+          min
+        })) {
+          // 有符合条件的interval
+          interval = SNAP_COUNT_ARRAY[i];
+          verify = true;
+          break;
+        }
+      } // 如果不满足, 依次缩小10倍,再计算
+
+
+      if (!verify) {
+        return 10 * getInterval(0, tickCount, min / 10, max / 10);
+      }
+
+      return interval;
+    } // 刻度是否满足展示需求
+
+
+    function intervalIsVerify(_ref2) {
+      var {
+        interval,
+        tickCount,
+        max,
+        min
+      } = _ref2;
+      var minTick = Math.floor(min / interval) * interval;
+
+      if (minTick + (tickCount - 1) * interval >= max) {
+        return true;
+      }
+
+      return false;
+    } // 计算小数点应该保留的位数
+
+
+    function getFixedLength(num) {
+      var str = num.toString();
+      var index = str.indexOf('.');
+      var indexOfExp = str.indexOf('e-');
+      var length = indexOfExp >= 0 ? parseInt(str.substr(indexOfExp + 2), 10) : str.substr(index + 1).length;
+
+      if (length > 20) {
+        // 最多保留20位小数
+        length = 20;
+      }
+
+      return length;
+    } // @antv/util fixedbase不支持科学计数法的判断,需要提mr
+
+
+    function toFixed(v, length) {
+      return parseFloat(v.toFixed(length));
+    }
+
+    var Linear$1 = getClass('linear');
+    var Identity$1 = getClass('identity');
+    var Category$1 = getClass('category');
+    var TimeCat$1 = getClass('timeCat'); // 覆盖0.3.x的 cat 方法
+
+    registerTickMethod('cat', CatTick);
+    registerTickMethod('time-cat', CatTick); // 覆盖linear 度量的tick算法
+
+    registerTickMethod('wilkinson-extended', LinearTick);
+    Scale.Linear = Linear$1;
+    Scale.Identity = Identity$1;
+    Scale.Category = Category$1;
+    Scale.Cat = Category$1;
+    Scale.TimeCat = TimeCat$1;
+
+    function isFullCircle(coord) {
+      if (!coord.isPolar) {
+        return false;
+      }
+
+      var startAngle = coord.startAngle;
+      var endAngle = coord.endAngle;
+
+      if (!isNil(startAngle) && !isNil(endAngle) && endAngle - startAngle < Math.PI * 2) {
+        return false;
+      }
+
+      return true;
+    }
+
+    function clearObj(obj) {
+      Object.keys(obj).forEach(function (key) {
+        delete obj[key];
+      });
+    }
+
+    class ScaleController {
+      constructor(cfg) {
+        // defs 列定义
+        this.defs = {}; // 已经实例化的scale
+
+        this.scales = {};
+        mix(this, cfg);
+      }
+
+      setFieldDef(field, cfg) {
+        var {
+          defs
+        } = this;
+
+        if (isObject(field)) {
+          mix(defs, field);
+        } else {
+          defs[field] = cfg;
+        } // 因为可能同时变更多个scale,所以要把所有已实例化的scale都更新下
+
+
+        this.updateScales();
+      }
+
+      _getDef(field) {
+        var defs = this.defs;
+        var def = null;
+
+        if (Global.scales[field] || defs[field]) {
+          def = mix({}, Global.scales[field]);
+          each(defs[field], function (v, k) {
+            if (isNil(v)) {
+              delete def[k];
+            } else {
+              def[k] = v;
+            }
+          });
+        }
+
+        return def;
+      }
+
+      _getDefaultType(field, data, def) {
+        if (def && def.type) {
+          return def.type;
+        }
+
+        var type = 'linear';
+        var value = firstValue$1(data, field);
+
+        if (isArray(value)) {
+          value = value[0];
+        }
+
+        if (isString(value)) {
+          type = 'cat';
+        }
+
+        return type;
+      }
+
+      _getScaleDef(type, field, data, def) {
+        var values;
+
+        if (def && def.values) {
+          values = def.values;
+        } else {
+          values = values$1(data, field);
+        }
+
+        var cfg = {
+          field,
+          values
+        };
+
+        if (type !== 'cat' && type !== 'timeCat') {
+          if (!def || !(def.min && def.max)) {
+            var {
+              min,
+              max
+            } = getRange$1(values);
+            cfg.min = min;
+            cfg.max = max;
+            cfg.nice = true;
+          }
+        } else {
+          cfg.isRounding = false; // used for tickCount calculation
+        }
+
+        return cfg;
+      } // 调整range,为了让图形居中
+
+
+      _adjustRange(type, cfg) {
+        var {
+          range,
+          values
+        } = cfg; // 如果是线性, 或者有自定义range都不处理
+
+        if (type === 'linear' || range || !values) {
+          return cfg;
+        }
+
+        var count = values.length; // 单只有一条数据时,在中间显示
+
+        if (count === 1) {
+          cfg.range = [0.5, 1];
+        } else {
+          var {
+            chart
+          } = this;
+          var coord = chart.get('coord');
+          var widthRatio = Global.widthRatio.multiplePie;
+          var offset = 0;
+
+          if (isFullCircle(coord)) {
+            if (!coord.transposed) {
+              cfg.range = [0, 1 - 1 / count];
+            } else {
+              offset = 1 / count * widthRatio;
+              cfg.range = [offset / 2, 1 - offset / 2];
+            }
+          } else {
+            // 为了让图形居中,所以才设置range
+            offset = 1 / count * 0.5; // 这里可能用0.25会更合理
+
+            cfg.range = [offset, 1 - offset];
+          }
+        }
+
+        return cfg;
+      }
+
+      _getScaleCfg(field, data) {
+        var self = this;
+
+        var def = self._getDef(field);
+
+        if (!data || !data.length) {
+          if (def && def.type) {
+            def.field = field;
+            return {
+              type: def.type,
+              cfg: def
+            };
+          }
+
+          return {
+            type: 'identity',
+            cfg: {
+              value: field,
+              field: field.toString(),
+              values: [field]
+            }
+          };
+        }
+
+        var firstObj = data[0];
+        var firstValue = firstObj[field];
+
+        if (firstValue === null) {
+          firstValue = firstValue$1(data, field);
+        }
+
+        if (isNumber(field) || isNil(firstValue) && !def) {
+          return {
+            type: 'identity',
+            cfg: {
+              value: field,
+              field: field.toString(),
+              values: [field]
+            }
+          };
+        }
+
+        var type = self._getDefaultType(field, data, def);
+
+        var cfg = self._getScaleDef(type, field, data, def);
+
+        def && mix(cfg, def);
+        cfg = this._adjustRange(type, cfg);
+        return {
+          type,
+          cfg
+        };
+      }
+
+      createScale(field, data) {
+        var {
+          scales
+        } = this;
+
+        var {
+          type,
+          cfg
+        } = this._getScaleCfg(field, data);
+
+        var scale = scales[field]; // 如果已经存在,且类型相等时直接返回
+
+        if (scale && scale.type === type) {
+          scale.change(cfg);
+          return scale;
+        }
+
+        var Scale = getClass(type);
+        var newScale = new Scale(cfg);
+        scales[field] = newScale;
+        return newScale;
+      }
+
+      _updateScale(scale) {
+        var {
+          field
+        } = scale; // 因为每个field的数据都会不同
+
+        var data = this.chart._getScaleData(field);
+
+        var {
+          cfg
+        } = this._getScaleCfg(field, data);
+
+        scale.change(cfg);
+      }
+
+      updateScales() {
+        var _this = this;
+
+        var {
+          scales
+        } = this; // 修改完列定义后,需要更新已经实例化的scale
+        // 如果是还没有实例化的,在geom初始化的时候会被实例化,所以这里可以不用更新
+
+        each(scales, function (scale) {
+          _this._updateScale(scale);
+        });
+      } // 调整scale从0开始
+
+
+      adjustStartZero(scale) {
+        var {
+          defs
+        } = this;
+        var {
+          field,
+          min,
+          max
+        } = scale; // 如果有定义,则不处理
+
+        if (defs[field] && defs[field].min) {
+          return;
+        }
+
+        if (min > 0) {
+          scale.change({
+            min: 0
+          });
+        } else if (max < 0) {
+          scale.change({
+            max: 0
+          });
+        }
+      }
+
+      clear() {
+        // this.defs = {};
+        // this.scales = {};
+        clearObj(this.defs);
+        clearObj(this.scales);
+        this.data = null;
+      }
+
+    }
+
+    class Abastract {
+      _initDefaultCfg() {
+        /**
+         * ticks
+         * @type {Array}
+         */
+        this.ticks = [];
+        /**
+         * the configuration for tickLine
+         * @type {Object}
+         */
+
+        this.tickLine = {};
+        /**
+         * the direction of ticks, 1 means clockwise
+         * @type {Number}
+         */
+
+        this.offsetFactor = 1;
+        /**
+         * the top container
+         * @type {container}
+         */
+
+        this.frontContainer = null;
+        /**
+         * the back container
+         * @type {[type]}
+         */
+
+        this.backContainer = null;
+        /**
+         * points for draw grid line
+         * @type {Array}
+         */
+
+        this.gridPoints = [];
+      }
+
+      constructor(cfg) {
+        this._initDefaultCfg();
+
+        mix(this, cfg);
+        this.draw();
+      }
+
+      draw() {
+        var {
+          line,
+          tickLine,
+          label,
+          grid
+        } = this;
+        grid && this.drawGrid(grid); // draw the grid lines
+
+        tickLine && this.drawTicks(tickLine); // draw the tickLine
+
+        line && this.drawLine(line); // draw axis line
+
+        label && this.drawLabels(); // draw ticks
+      }
+
+      drawTicks(tickCfg) {
+        var self = this;
+        var ticks = self.ticks;
+        var length = tickCfg.length;
+        var container = self.getContainer(tickCfg.top);
+        each(ticks, function (tick) {
+          var start = self.getOffsetPoint(tick.value);
+          var end = self.getSidePoint(start, length);
+          var shape = container.addShape('line', {
+            className: 'axis-tick',
+            attrs: mix({
+              x1: start.x,
+              y1: start.y,
+              x2: end.x,
+              y2: end.y
+            }, tickCfg)
+          });
+          shape._id = self._id + '-ticks';
+        });
+      }
+
+      drawLabels() {
+        var self = this;
+        var labelOffset = self.labelOffset;
+        var labels = self.labels;
+        each(labels, function (labelShape) {
+          var container = self.getContainer(labelShape.get('top'));
+          var start = self.getOffsetPoint(labelShape.get('value'));
+          var {
+            x,
+            y
+          } = self.getSidePoint(start, labelOffset);
+          labelShape.attr(mix({
+            x,
+            y
+          }, self.getTextAlignInfo(start, labelOffset), labelShape.get('textStyle')));
+          labelShape._id = self._id + '-' + labelShape.attr('text');
+          container.add(labelShape);
+        });
+      }
+
+      drawLine() {}
+
+      drawGrid(grid) {
+        var self = this;
+        var {
+          gridPoints,
+          ticks
+        } = self;
+        var gridCfg = grid;
+        var count = gridPoints.length;
+        each(gridPoints, function (subPoints, index) {
+          if (isFunction(grid)) {
+            var tick = ticks[index] || {};
+            var executedGrid = grid(tick.text, index, count);
+            gridCfg = executedGrid ? mix({}, Global._defaultAxis.grid, executedGrid) : null;
+          }
+
+          if (gridCfg) {
+            var type = gridCfg.type; // has two types: 'line' and 'arc'
+
+            var points = subPoints.points;
+            var container = self.getContainer(gridCfg.top);
+            var shape;
+
+            if (type === 'arc') {
+              var {
+                center,
+                startAngle,
+                endAngle
+              } = self;
+              var radius = Vector2.length([points[0].x - center.x, points[0].y - center.y]);
+              shape = container.addShape('Arc', {
+                className: 'axis-grid',
+                attrs: mix({
+                  x: center.x,
+                  y: center.y,
+                  startAngle,
+                  endAngle,
+                  r: radius
+                }, gridCfg)
+              });
+            } else {
+              shape = container.addShape('Polyline', {
+                className: 'axis-grid',
+                attrs: mix({
+                  points
+                }, gridCfg)
+              });
+            }
+
+            shape._id = subPoints._id;
+          }
+        });
+      }
+
+      getOffsetPoint() {}
+
+      getAxisVector() {}
+
+      getOffsetVector(point, offset) {
+        var self = this;
+        var axisVector = self.getAxisVector(point);
+        var normal = Vector2.normalize([], axisVector);
+        var factor = self.offsetFactor;
+        var verticalVector = [normal[1] * -1 * factor, normal[0] * factor];
+        return Vector2.scale([], verticalVector, offset);
+      }
+
+      getSidePoint(point, offset) {
+        var self = this;
+        var offsetVector = self.getOffsetVector(point, offset);
+        return {
+          x: point.x + offsetVector[0],
+          y: point.y + offsetVector[1]
+        };
+      }
+
+      getTextAlignInfo(point, offset) {
+        var self = this;
+        var offsetVector = self.getOffsetVector(point, offset);
+        var align;
+        var baseLine;
+
+        if (offsetVector[0] > 0) {
+          align = 'left';
+        } else if (offsetVector[0] < 0) {
+          align = 'right';
+        } else {
+          align = 'center';
+        }
+
+        if (offsetVector[1] > 0) {
+          baseLine = 'top';
+        } else if (offsetVector[1] < 0) {
+          baseLine = 'bottom';
+        } else {
+          baseLine = 'middle';
+        }
+
+        return {
+          textAlign: align,
+          textBaseline: baseLine
+        };
+      }
+
+      getContainer(isTop) {
+        var {
+          frontContainer,
+          backContainer
+        } = this;
+        return isTop ? frontContainer : backContainer;
+      }
+
+    }
+
+    class Line extends Abastract {
+      _initDefaultCfg() {
+        super._initDefaultCfg();
+
+        this.start = null;
+        this.end = null;
+      }
+
+      getOffsetPoint(value) {
+        var {
+          start,
+          end
+        } = this;
+        return {
+          x: start.x + (end.x - start.x) * value,
+          y: start.y + (end.y - start.y) * value
+        };
+      }
+
+      getAxisVector() {
+        var {
+          start,
+          end
+        } = this;
+        return [end.x - start.x, end.y - start.y];
+      }
+
+      drawLine(lineCfg) {
+        var container = this.getContainer(lineCfg.top);
+        var {
+          start,
+          end
+        } = this;
+        container.addShape('line', {
+          className: 'axis-line',
+          attrs: mix({
+            x1: start.x,
+            y1: start.y,
+            x2: end.x,
+            y2: end.y
+          }, lineCfg)
+        });
+      }
+
+    }
+
+    Abastract.Line = Line;
+
+    function _defineProperty$1(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
+
+    var calcDirection = function calcDirection(start, end) {
+      var xDistance = end.x - start.x;
+      var yDistance = end.y - start.y; // x 的距离大于y 说明是横向,否则就是纵向
+
+      if (Math.abs(xDistance) > Math.abs(yDistance)) {
+        return xDistance > 0 ? 'right' : 'left';
+      }
+
+      return yDistance > 0 ? 'down' : 'up';
+    }; // 计算2点之间的距离
+
+
+    var calcDistance = function calcDistance(point1, point2) {
+      var xDistance = Math.abs(point2.x - point1.x);
+      var yDistance = Math.abs(point2.y - point1.y);
+      return Math.sqrt(xDistance * xDistance + yDistance * yDistance);
+    };
+
+    var getCenter = function getCenter(point1, point2) {
+      var x = point1.x + (point2.x - point1.x) / 2;
+      var y = point1.y + (point2.y - point1.y) / 2;
+      return {
+        x,
+        y
+      };
+    };
+
+    var convertPoints = function convertPoints(ev, canvas) {
+      var touches = ev.touches; // 认为是mouse事件
+
+      if (!touches) {
+        var point = getRelativePosition({
+          x: ev.clientX,
+          y: ev.clientY
+        }, canvas);
+        return [point];
+      }
+
+      var points = [];
+      var len = touches.length;
+
+      for (var i = 0; i < len; i++) {
+        var touch = touches[i]; // x, y: 相对canvas原点的位置,clientX, clientY 相对于可视窗口的位置
+
+        var {
+          x,
+          y,
+          clientX,
+          clientY
+        } = touch;
+
+        var _point = void 0; // 小程序环境会有x,y
+
+
+        if (isNumber(x) || isNumber(y)) {
+          _point = {
+            x,
+            y
+          };
+        } else {
+          // 浏览器环境再计算下canvas的相对位置
+          _point = getRelativePosition({
+            x: clientX,
+            y: clientY
+          }, canvas);
+        }
+
+        points.push(_point);
+      }
+
+      return points;
+    };
+
+    var PRESS_DELAY = 250;
+
+    class EventController {
+      constructor(_ref) {
+        var _this = this;
+
+        var {
+          canvas,
+          el
+        } = _ref;
+
+        _defineProperty$1(this, "_click", function (ev) {
+          var points = convertPoints(ev, _this.canvas);
+          ev.points = points;
+
+          _this.emitEvent('click', ev);
+        });
+
+        _defineProperty$1(this, "_start", function (ev) {
+          var points = convertPoints(ev, _this.canvas);
+
+          if (!points) {
+            return;
+          }
+
+          ev.points = points;
+
+          _this.emitEvent('touchstart', ev); // 防止上次的内容没有清理掉,重新reset下
+
+
+          _this.reset(); // 记录touch start 的时间
+
+
+          _this.startTime = Date.now(); // 记录touch start 的点
+
+          _this.startPoints = points;
+
+          if (points.length > 1) {
+            _this.startDistance = calcDistance(points[0], points[1]);
+            _this.center = getCenter(points[0], points[1]);
+          } else {
+            // 如果touchstart后停顿250ms, 则也触发press事件
+            _this.pressTimeout = setTimeout(function () {
+              // 这里固定触发press事件
+              var eventType = 'press';
+              var direction = 'none';
+              ev.direction = direction;
+
+              _this.emitStart(eventType, ev);
+
+              _this.emitEvent(eventType, ev);
+
+              _this.eventType = eventType;
+              _this.direction = direction;
+            }, PRESS_DELAY);
+          }
+        });
+
+        _defineProperty$1(this, "_move", function (ev) {
+          var points = convertPoints(ev, _this.canvas);
+          if (!points) return;
+
+          _this.clearPressTimeout();
+
+          ev.points = points;
+
+          _this.emitEvent('touchmove', ev);
+
+          var startPoints = _this.startPoints;
+          if (!startPoints) return; // 多指触控
+
+          if (points.length > 1) {
+            // touchstart的距离
+            var startDistance = _this.startDistance;
+            var currentDistance = calcDistance(points[0], points[1]);
+            ev.zoom = currentDistance / startDistance;
+            ev.center = _this.center; // 触发缩放事件
+
+            _this.emitStart('pinch', ev);
+
+            _this.emitEvent('pinch', ev);
+          } else {
+            var deltaX = points[0].x - startPoints[0].x;
+            var deltaY = points[0].y - startPoints[0].y;
+            var direction = _this.direction || calcDirection(startPoints[0], points[0]);
+            _this.direction = direction; // 获取press或者pan的事件类型
+            // press 按住滑动, pan表示平移
+            // 如果start后立刻move,则触发pan, 如果有停顿,则触发press
+
+            var eventType = _this.getEventType(points);
+
+            ev.direction = direction;
+            ev.deltaX = deltaX;
+            ev.deltaY = deltaY;
+
+            _this.emitStart(eventType, ev);
+
+            _this.emitEvent(eventType, ev); // 记录最后2次move的时间和坐标,为了给swipe事件用
+
+
+            var prevMoveTime = _this.lastMoveTime;
+            var now = Date.now(); // 最后2次的时间间隔一定要大于0,否则swipe没发计算
+
+            if (now - prevMoveTime > 0) {
+              _this.prevMoveTime = prevMoveTime;
+              _this.prevMovePoints = _this.lastMovePoints;
+              _this.lastMoveTime = now;
+              _this.lastMovePoints = points;
+            }
+          }
+        });
+
+        _defineProperty$1(this, "_end", function (ev) {
+          _this.emitEnd(ev);
+
+          _this.emitEvent('touchend', ev); // swipe事件处理, 在touchend之后触发
+
+
+          var lastMoveTime = _this.lastMoveTime;
+          var now = Date.now(); // 做这个判断是为了最后一次touchmove后到end前,还有一个停顿的过程
+          // 100 是拍的一个值,理论这个值会很短,一般不卡顿的话在10ms以内
+
+          if (now - lastMoveTime < 100) {
+            var prevMoveTime = _this.prevMoveTime || _this.startTime;
+            var intervalTime = lastMoveTime - prevMoveTime; // 时间间隔一定要大于0, 否则计算没意义
+
+            if (intervalTime > 0) {
+              var prevMovePoints = _this.prevMovePoints || _this.startPoints;
+              var lastMovePoints = _this.lastMovePoints; // move速率
+
+              var velocity = calcDistance(prevMovePoints[0], lastMovePoints[0]) / intervalTime; // 0.3 是参考hammerjs的设置
+
+              if (velocity > 0.3) {
+                ev.velocity = velocity;
+                ev.direction = calcDirection(prevMovePoints[0], lastMovePoints[0]);
+
+                _this.emitEvent('swipe', ev);
+              }
+            }
+          }
+
+          _this.reset();
+
+          var touches = ev.touches; // 当多指只释放了1指时也会触发end, 这时重新触发一次start
+
+          if (touches && touches.length > 0) {
+            _this._start(ev);
+          }
+        });
+
+        _defineProperty$1(this, "_cancel", function (ev) {
+          _this.emitEvent('touchcancel', ev);
+
+          _this.reset();
+        });
+
+        // canvasEl
+        this.canvas = canvas;
+        this.delegateEvent(el); // 用来记录当前触发的事件
+
+        this.processEvent = {};
+      }
+
+      delegateEvent(canvasEl) {
+        // 代理这几个事件
+        canvasEl.addEventListener('click', this._click);
+        canvasEl.addEventListener('touchstart', this._start);
+        canvasEl.addEventListener('touchmove', this._move);
+        canvasEl.addEventListener('touchend', this._end);
+        canvasEl.addEventListener('touchcancel', this._cancel);
+      }
+
+      emitEvent(type, ev) {
+        var canvas = this.canvas;
+        canvas.emit(type, ev);
+      }
+
+      getEventType(points) {
+        var {
+          eventType,
+          canvas,
+          startTime,
+          startPoints
+        } = this;
+
+        if (eventType) {
+          return eventType;
+        }
+
+        var type;
+        var panEventListeners = canvas.__events.pan; // 如果没有pan事件的监听,默认都是press
+
+        if (!panEventListeners || !panEventListeners.length) {
+          type = 'press';
+        } else {
+          // 如果有pan事件的处理,press则需要停顿250ms, 且移动距离小于10
+          var now = Date.now();
+
+          if (now - startTime > PRESS_DELAY && calcDistance(startPoints[0], points[0]) < 10) {
+            type = 'press';
+          } else {
+            type = 'pan';
+          }
+        }
+
+        this.eventType = type;
+        return type;
+      }
+
+      enable(eventType) {
+        this.processEvent[eventType] = true;
+      } // 是否进行中的事件
+
+
+      isProcess(eventType) {
+        return this.processEvent[eventType];
+      } // 触发start事件
+
+
+      emitStart(type, ev) {
+        if (this.isProcess(type)) {
+          return;
+        }
+
+        this.enable(type);
+        this.emitEvent("".concat(type, "start"), ev);
+      } // 触发end事件
+
+
+      emitEnd(ev) {
+        var _this2 = this;
+
+        var processEvent = this.processEvent;
+        Object.keys(processEvent).forEach(function (type) {
+          _this2.emitEvent("".concat(type, "end"), ev);
+
+          delete processEvent[type];
+        });
+      }
+
+      clearPressTimeout() {
+        if (this.pressTimeout) {
+          clearTimeout(this.pressTimeout);
+          this.pressTimeout = 0;
+        }
+      }
+
+      reset() {
+        this.clearPressTimeout();
+        this.startTime = 0;
+        this.startPoints = null;
+        this.startDistance = 0;
+        this.direction = null;
+        this.eventType = null;
+        this.pinch = false;
+        this.prevMoveTime = 0;
+        this.prevMovePoints = null;
+        this.lastMoveTime = 0;
+        this.lastMovePoints = null;
+      }
+
+    }
+
+    class CanvasElement extends EventEmit {
+      constructor(ctx) {
+        super();
+        this.context = ctx; // canvas实际的宽高 (width/height) * pixelRatio
+
+        this.width = 0;
+        this.height = 0;
+        this.style = {};
+        this.currentStyle = {}; // 用来标识是CanvasElement实例
+
+        this.isCanvasElement = true;
+      }
+
+      getContext()
+      /* type */
+      {
+        return this.context;
+      }
+
+      getBoundingClientRect() {
+        var width = this.width;
+        var height = this.height; // 默认都处理成可视窗口的顶部位置
+
+        return {
+          top: 0,
+          right: width,
+          bottom: height,
+          left: 0
+        };
+      }
+
+      addEventListener(type, listener) {
+        this.on(type, listener);
+      }
+
+      removeEventListener(type, listener) {
+        this.off(type, listener);
+      }
+
+      dispatchEvent(type, e) {
+        this.emit(type, e);
+      }
+
+    }
+
+    function supportEventListener(canvas) {
+      if (!canvas) {
+        return false;
+      } // 非 HTMLCanvasElement
+
+
+      if (canvas.nodeType !== 1 || !canvas.nodeName || canvas.nodeName.toLowerCase() !== 'canvas') {
+        return false;
+      } // 微信小程序canvas.getContext('2d')时也是CanvasRenderingContext2D
+      // 也会有ctx.canvas, 而且nodeType也是1,所以还要在看下是否支持addEventListener
+
+
+      var support = false;
+
+      try {
+        canvas.addEventListener('eventTest', function () {
+          support = true;
+        });
+        canvas.dispatchEvent(new Event('eventTest'));
+      } catch (error) {
+        support = false;
+      }
+
+      return support;
+    }
+
+    var CanvasElement$1 = {
+      create(ctx) {
+        if (!ctx) {
+          return null;
+        }
+
+        if (supportEventListener(ctx.canvas)) {
+          return ctx.canvas;
+        }
+
+        return new CanvasElement(ctx);
+      }
+
+    };
+
+    function _mod(n, m) {
+      return (n % m + m) % m;
+    }
+
+    function _addStop(steps, gradient) {
+      each(steps, function (item) {
+        item = item.split(':');
+        gradient.addColorStop(Number(item[0]), item[1]);
+      });
+    } // the string format: 'l(0) 0:#ffffff 0.5:#7ec2f3 1:#1890ff'
+
+
+    function _parseLineGradient(color, shape, context) {
+      var arr = color.split(' ');
+      var angle = arr[0].slice(2, arr[0].length - 1);
+      angle = _mod(parseFloat(angle) * Math.PI / 180, Math.PI * 2);
+      var steps = arr.slice(1);
+      var {
+        minX,
+        minY,
+        maxX,
+        maxY
+      } = shape.getBBox();
+      var start;
+      var end;
+
+      if (angle >= 0 && angle < 0.5 * Math.PI) {
+        start = {
+          x: minX,
+          y: minY
+        };
+        end = {
+          x: maxX,
+          y: maxY
+        };
+      } else if (0.5 * Math.PI <= angle && angle < Math.PI) {
+        start = {
+          x: maxX,
+          y: minY
+        };
+        end = {
+          x: minX,
+          y: maxY
+        };
+      } else if (Math.PI <= angle && angle < 1.5 * Math.PI) {
+        start = {
+          x: maxX,
+          y: maxY
+        };
+        end = {
+          x: minX,
+          y: minY
+        };
+      } else {
+        start = {
+          x: minX,
+          y: maxY
+        };
+        end = {
+          x: maxX,
+          y: minY
+        };
+      }
+
+      var tanTheta = Math.tan(angle);
+      var tanTheta2 = tanTheta * tanTheta;
+      var x = (end.x - start.x + tanTheta * (end.y - start.y)) / (tanTheta2 + 1) + start.x;
+      var y = tanTheta * (end.x - start.x + tanTheta * (end.y - start.y)) / (tanTheta2 + 1) + start.y;
+      var gradient = context.createLinearGradient(start.x, start.y, x, y);
+
+      _addStop(steps, gradient);
+
+      return gradient;
+    } // the string format: 'r(0.5, 0.5, 0.1) 0:#ffffff 1:#1890ff'
+
+
+    function _parseRadialGradient(color, shape, context) {
+      var arr = color.split(' ');
+      var circleCfg = arr[0].slice(2, arr[0].length - 1);
+      circleCfg = circleCfg.split(',');
+      var fx = parseFloat(circleCfg[0]);
+      var fy = parseFloat(circleCfg[1]);
+      var fr = parseFloat(circleCfg[2]);
+      var steps = arr.slice(1); // if radius is 0, no gradient, stroke with the last color
+
+      if (fr === 0) {
+        var _color = steps[steps.length - 1];
+        return _color.split(':')[1];
+      }
+
+      var {
+        width,
+        height,
+        minX,
+        minY
+      } = shape.getBBox();
+      var r = Math.sqrt(width * width + height * height) / 2;
+      var gradient = context.createRadialGradient(minX + width * fx, minY + height * fy, fr * r, minX + width / 2, minY + height / 2, r);
+
+      _addStop(steps, gradient);
+
+      return gradient;
+    }
+
+    function parseStyle(color, shape, context) {
+      if (color[1] === '(') {
+        try {
+          var firstCode = color[0];
+
+          if (firstCode === 'l') {
+            return _parseLineGradient(color, shape, context);
+          } else if (firstCode === 'r') {
+            return _parseRadialGradient(color, shape, context);
+          }
+        } catch (ev) {
+          console.error('error in parsing gradient string, please check if there are any extra whitespaces.');
+          console.error(ev);
+        }
+      }
+
+      return color;
+    }
+
+    var ALIAS_ATTRS_MAP = {
+      stroke: 'strokeStyle',
+      fill: 'fillStyle',
+      opacity: 'globalAlpha'
+    };
+    var SHAPE_ATTRS = ['fillStyle', 'font', 'globalAlpha', 'lineCap', 'lineWidth', 'lineJoin', 'miterLimit', 'shadowBlur', 'shadowColor', 'shadowOffsetX', 'shadowOffsetY', 'strokeStyle', 'textAlign', 'textBaseline', 'lineDash', 'shadow' // 兼容支付宝小程序
+    ];
+    var CLIP_SHAPES = ['circle', 'sector', 'polygon', 'rect', 'polyline'];
+
+    class Element$1 {
+      _initProperties() {
+        this._attrs = {
+          zIndex: 0,
+          visible: true,
+          destroyed: false
+        };
+      }
+
+      constructor(cfg) {
+        this._initProperties();
+
+        mix(this._attrs, cfg);
+        var attrs = this._attrs.attrs;
+
+        if (attrs) {
+          this.initAttrs(attrs);
+        }
+
+        this.initTransform();
+      }
+
+      get(name) {
+        return this._attrs[name];
+      }
+
+      set(name, value) {
+        this._attrs[name] = value;
+      }
+
+      isGroup() {
+        return this.get('isGroup');
+      }
+
+      isShape() {
+        return this.get('isShape');
+      }
+
+      initAttrs(attrs) {
+        this.attr(mix(this.getDefaultAttrs(), attrs));
+      }
+
+      getDefaultAttrs() {
+        return {};
+      }
+
+      _setAttr(name, value) {
+        var attrs = this._attrs.attrs;
+
+        if (name === 'clip') {
+          value = this._setAttrClip(value);
+        } else {
+          var alias = ALIAS_ATTRS_MAP[name];
+
+          if (alias) {
+            attrs[alias] = value;
+          }
+        }
+
+        attrs[name] = value;
+      }
+
+      _getAttr(name) {
+        return this._attrs.attrs[name];
+      } // _afterAttrsSet() {}
+
+
+      _setAttrClip(clip) {
+        if (clip && CLIP_SHAPES.indexOf(clip._attrs.type) > -1) {
+          if (clip.get('canvas') === null) {
+            clip = Object.assign({}, clip);
+          }
+
+          clip.set('parent', this.get('parent'));
+          clip.set('context', this.get('context'));
+          return clip;
+        }
+
+        return null;
+      }
+
+      attr(name, value) {
+        var self = this;
+        if (self.get('destroyed')) return null;
+        var argumentsLen = arguments.length;
+
+        if (argumentsLen === 0) {
+          return self._attrs.attrs;
+        }
+
+        if (isObject(name)) {
+          this._attrs.bbox = null;
+
+          for (var k in name) {
+            self._setAttr(k, name[k]);
+          }
+
+          if (self._afterAttrsSet) {
+            self._afterAttrsSet();
+          }
+
+          return self;
+        }
+
+        if (argumentsLen === 2) {
+          this._attrs.bbox = null;
+
+          self._setAttr(name, value);
+
+          if (self._afterAttrsSet) {
+            self._afterAttrsSet();
+          }
+
+          return self;
+        }
+
+        return self._getAttr(name);
+      }
+
+      getParent() {
+        return this.get('parent');
+      }
+
+      draw(context) {
+        if (this.get('destroyed')) {
+          return;
+        }
+
+        if (this.get('visible')) {
+          this.setContext(context);
+          this.drawInner(context);
+          this.restoreContext(context);
+        }
+      }
+
+      setContext(context) {
+        var clip = this._attrs.attrs.clip;
+        context.save();
+
+        if (clip) {
+          clip.resetTransform(context);
+          clip.createPath(context);
+          context.clip();
+        }
+
+        this.resetContext(context);
+        this.resetTransform(context);
+      }
+
+      restoreContext(context) {
+        context.restore();
+      }
+
+      resetContext(context) {
+        var elAttrs = this._attrs.attrs;
+
+        if (!this._attrs.isGroup) {
+          for (var k in elAttrs) {
+            if (SHAPE_ATTRS.indexOf(k) > -1) {
+              var v = elAttrs[k];
+
+              if (k === 'fillStyle' || k === 'strokeStyle') {
+                v = parseStyle(v, this, context);
+              }
+
+              if (k === 'lineDash' && context.setLineDash && isArray(v)) {
+                context.setLineDash(v);
+              } else {
+                context[k] = v;
+              }
+            }
+          }
+        }
+      }
+
+      hasFill() {
+        return this.get('canFill') && this._attrs.attrs.fillStyle;
+      }
+
+      hasStroke() {
+        return this.get('canStroke') && this._attrs.attrs.strokeStyle;
+      }
+
+      drawInner()
+      /* context */
+      {}
+
+      show() {
+        this.set('visible', true);
+        return this;
+      }
+
+      hide() {
+        this.set('visible', false);
+        return this;
+      }
+
+      isVisible() {
+        return this.get('visible');
+      }
+
+      _removeFromParent() {
+        var parent = this.get('parent');
+
+        if (parent) {
+          var children = parent.get('children');
+          remove$1(children, this);
+        }
+
+        return this;
+      }
+
+      remove(destroy) {
+        if (destroy) {
+          this.destroy();
+        } else {
+          this._removeFromParent();
+        }
+      }
+
+      destroy() {
+        var destroyed = this.get('destroyed');
+
+        if (destroyed) {
+          return null;
+        }
+
+        this._removeFromParent();
+
+        this._attrs = {};
+        this.set('destroyed', true);
+      }
+
+      getBBox() {
+        return {
+          minX: 0,
+          maxX: 0,
+          minY: 0,
+          maxY: 0,
+          width: 0,
+          height: 0
+        };
+      }
+
+      initTransform() {
+        var attrs = this._attrs.attrs || {};
+
+        if (!attrs.matrix) {
+          attrs.matrix = [1, 0, 0, 1, 0, 0];
+        }
+
+        this._attrs.attrs = attrs;
+      }
+
+      getMatrix() {
+        return this._attrs.attrs.matrix;
+      }
+
+      setMatrix(m) {
+        this._attrs.attrs.matrix = [m[0], m[1], m[2], m[3], m[4], m[5]];
+      }
+
+      transform(actions) {
+        var matrix = this._attrs.attrs.matrix;
+        this._attrs.attrs.matrix = Matrix.transform(matrix, actions);
+        return this;
+      }
+
+      setTransform(actions) {
+        this._attrs.attrs.matrix = [1, 0, 0, 1, 0, 0];
+        return this.transform(actions);
+      }
+
+      translate(x, y) {
+        var matrix = this._attrs.attrs.matrix;
+        Matrix.translate(matrix, matrix, [x, y]);
+      }
+
+      rotate(rad) {
+        var matrix = this._attrs.attrs.matrix;
+        Matrix.rotate(matrix, matrix, rad);
+      }
+
+      scale(sx, sy) {
+        var matrix = this._attrs.attrs.matrix;
+        Matrix.scale(matrix, matrix, [sx, sy]);
+      }
+
+      moveTo(x, y) {
+        var cx = this._attrs.x || 0;
+        var cy = this._attrs.y || 0;
+        this.translate(x - cx, y - cy);
+        this.set('x', x);
+        this.set('y', y);
+      }
+
+      apply(v) {
+        var m = this._attrs.attrs.matrix;
+        Vector2.transformMat2d(v, v, m);
+        return this;
+      }
+
+      resetTransform(context) {
+        var mo = this._attrs.attrs.matrix;
+
+        if (Matrix.isChanged(mo)) {
+          context.transform(mo[0], mo[1], mo[2], mo[3], mo[4], mo[5]);
+        }
+      }
+
+      isDestroyed() {
+        return this.get('destroyed');
+      }
+
+    }
+
+    class Shape$2 extends Element$1 {
+      _initProperties() {
+        this._attrs = {
+          zIndex: 0,
+          visible: true,
+          destroyed: false,
+          isShape: true,
+          attrs: {}
+        };
+      }
+
+      getType() {
+        return this._attrs.type;
+      }
+
+      drawInner(context) {
+        var self = this;
+        var attrs = self.get('attrs');
+        self.createPath(context);
+        var originOpacity = context.globalAlpha;
+
+        if (self.hasFill()) {
+          var fillOpacity = attrs.fillOpacity;
+
+          if (!isNil(fillOpacity) && fillOpacity !== 1) {
+            context.globalAlpha = fillOpacity;
+            context.fill();
+            context.globalAlpha = originOpacity;
+          } else {
+            context.fill();
+          }
+        }
+
+        if (self.hasStroke()) {
+          var lineWidth = attrs.lineWidth;
+
+          if (lineWidth > 0) {
+            var strokeOpacity = attrs.strokeOpacity;
+
+            if (!isNil(strokeOpacity) && strokeOpacity !== 1) {
+              context.globalAlpha = strokeOpacity;
+            }
+
+            context.stroke();
+          }
+        }
+      }
+
+      getBBox() {
+        var bbox = this._attrs.bbox;
+
+        if (!bbox) {
+          bbox = this.calculateBox();
+
+          if (bbox) {
+            bbox.x = bbox.minX;
+            bbox.y = bbox.minY;
+            bbox.width = bbox.maxX - bbox.minX;
+            bbox.height = bbox.maxY - bbox.minY;
+          }
+
+          this._attrs.bbox = bbox;
+        }
+
+        return bbox;
+      }
+
+      calculateBox() {
+        return null;
+      }
+
+      createPath() {}
+
+    }
+
+    var SHAPE_MAP = {};
+    var INDEX = '_INDEX';
+
+    function getComparer(compare) {
+      return function (left, right) {
+        var result = compare(left, right);
+        return result === 0 ? left[INDEX] - right[INDEX] : result;
+      };
+    }
+
+    var Container = {
+      getGroupClass() {},
+
+      getChildren() {
+        return this.get('children');
+      },
+
+      addShape(type) {
+        var cfg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
+        var canvas = this.get('canvas');
+        var shapeType = SHAPE_MAP[type];
+
+        if (!shapeType) {
+          shapeType = upperFirst(type);
+          SHAPE_MAP[type] = shapeType;
+        }
+
+        cfg.canvas = canvas;
+
+        if (shapeType === 'Text' && canvas && canvas.get('fontFamily')) {
+          cfg.attrs.fontFamily = cfg.attrs.fontFamily || canvas.get('fontFamily');
+        }
+
+        var shape = new Shape$2[shapeType](cfg);
+        this.add(shape);
+        return shape;
+      },
+
+      addGroup(cfg) {
+        var canvas = this.get('canvas');
+        var groupClass = this.getGroupClass();
+        cfg = mix({}, cfg);
+        cfg.canvas = canvas;
+        cfg.parent = this;
+        var rst = new groupClass(cfg);
+        this.add(rst);
+        return rst;
+      },
+
+      contain(item) {
+        var children = this.get('children');
+        return children.indexOf(item) > -1;
+      },
+
+      sort() {
+        var children = this.get('children');
+
+        for (var i = 0, len = children.length; i < len; i++) {
+          var child = children[i];
+          child[INDEX] = i;
+        }
+
+        children.sort(getComparer(function (obj1, obj2) {
+          return obj1.get('zIndex') - obj2.get('zIndex');
+        }));
+        return this;
+      },
+
+      drawInner(context) {
+        var children = this.get('children');
+
+        for (var i = 0, len = children.length; i < len; i++) {
+          var child = children[i];
+          child.draw(context);
+        }
+
+        return this;
+      },
+
+      clear() {
+        var children = this.get('children');
+
+        while (children.length !== 0) {
+          children[children.length - 1].remove(true);
+        }
+
+        return this;
+      },
+
+      add(items) {
+        var self = this;
+        var children = self.get('children');
+
+        if (!isArray(items)) {
+          items = [items];
+        }
+
+        for (var i = 0, len = items.length; i < len; i++) {
+          var item = items[i];
+          var parent = item.get('parent');
+
+          if (parent) {
+            var descendants = parent.get('children');
+            remove$1(descendants, item);
+          }
+
+          self._setEvn(item);
+
+          children.push(item);
+        }
+
+        return self;
+      },
+
+      _setEvn(item) {
+        var self = this;
+        item._attrs.parent = self;
+        item._attrs.context = self._attrs.context;
+        item._attrs.canvas = self._attrs.canvas;
+        var clip = item._attrs.attrs.clip;
+
+        if (clip) {
+          clip.set('parent', self);
+          clip.set('context', self.get('context'));
+        }
+
+        if (item._attrs.isGroup) {
+          var children = item._attrs.children;
+
+          for (var i = 0, len = children.length; i < len; i++) {
+            item._setEvn(children[i]);
+          }
+        }
+      }
+
+    };
+
+    class Group extends Element$1 {
+      _initProperties() {
+        this._attrs = {
+          zIndex: 0,
+          visible: true,
+          destroyed: false,
+          isGroup: true,
+          children: []
+        };
+      }
+
+      getBBox() {
+        var self = this;
+        var minX = Infinity;
+        var maxX = -Infinity;
+        var minY = Infinity;
+        var maxY = -Infinity;
+        var children = self.get('children');
+
+        for (var i = 0, length = children.length; i < length; i++) {
+          var child = children[i];
+
+          if (child.get('visible')) {
+            var box = child.getBBox();
+
+            if (!box) {
+              continue;
+            }
+
+            var leftTop = [box.minX, box.minY];
+            var leftBottom = [box.minX, box.maxY];
+            var rightTop = [box.maxX, box.minY];
+            var rightBottom = [box.maxX, box.maxY];
+            var matrix = child.attr('matrix');
+            Vector2.transformMat2d(leftTop, leftTop, matrix);
+            Vector2.transformMat2d(leftBottom, leftBottom, matrix);
+            Vector2.transformMat2d(rightTop, rightTop, matrix);
+            Vector2.transformMat2d(rightBottom, rightBottom, matrix);
+            minX = Math.min(leftTop[0], leftBottom[0], rightTop[0], rightBottom[0], minX);
+            maxX = Math.max(leftTop[0], leftBottom[0], rightTop[0], rightBottom[0], maxX);
+            minY = Math.min(leftTop[1], leftBottom[1], rightTop[1], rightBottom[1], minY);
+            maxY = Math.max(leftTop[1], leftBottom[1], rightTop[1], rightBottom[1], maxY);
+          }
+        }
+
+        return {
+          minX,
+          minY,
+          maxX,
+          maxY,
+          x: minX,
+          y: minY,
+          width: maxX - minX,
+          height: maxY - minY
+        };
+      }
+
+      destroy() {
+        if (this.get('destroyed')) {
+          return;
+        }
+
+        this.clear();
+        super.destroy();
+      }
+
+    }
+
+    mix(Group.prototype, Container, {
+      getGroupClass() {
+        return Group;
+      }
+
+    });
+
+    var requestAnimationFrame$1 = typeof window === 'object' && window.requestAnimationFrame ? window.requestAnimationFrame : function (fn) {
+      return setTimeout(fn, 16);
+    };
+
+    class Canvas extends EventEmit {
+      get(name) {
+        return this._attrs[name];
+      }
+
+      set(name, value) {
+        this._attrs[name] = value;
+      }
+
+      constructor(cfg) {
+        super();
+        this._attrs = mix({
+          type: 'canvas',
+          children: []
+        }, cfg);
+
+        this._initPixelRatio();
+
+        this._initCanvas();
+      }
+
+      _initPixelRatio() {
+        var pixelRatio = this.get('pixelRatio');
+
+        if (!pixelRatio) {
+          this.set('pixelRatio', getPixelRatio());
+        }
+      }
+
+      beforeDraw() {
+        var context = this._attrs.context;
+        var el = this._attrs.el;
+        context && context.clearRect && context.clearRect(0, 0, el.width, el.height);
+      }
+
+      _initCanvas() {
+        var self = this;
+        var el = self.get('el');
+        var context = self.get('context');
+
+        if (!el && !context) {
+          throw new Error('Please specify the id, el or context of the chart!');
+        }
+
+        var canvas;
+
+        if (el) {
+          // DOMElement or String
+          canvas = isString(el) ? getDomById(el) : el;
+        } else {
+          // 说明没有指定el
+          canvas = CanvasElement$1.create(context);
+        }
+
+        if (context && canvas && !canvas.getContext) {
+          canvas.getContext = function () {
+            return context;
+          };
+        }
+
+        var width = self.get('width');
+
+        if (!width) {
+          width = getWidth(canvas);
+        }
+
+        var height = self.get('height');
+
+        if (!height) {
+          height = getHeight(canvas);
+        }
+
+        self.set('canvas', this);
+        self.set('el', canvas);
+        self.set('context', context || canvas.getContext('2d'));
+        self.changeSize(width, height); // 初始化事件控制器
+
+        var eventController = new EventController({
+          canvas: this,
+          el: canvas
+        });
+        self.set('eventController', eventController);
+      }
+
+      changeSize(width, height) {
+        var pixelRatio = this.get('pixelRatio');
+        var canvasDOM = this.get('el'); // HTMLCanvasElement or canvasElement
+        // 浏览器环境设置style样式
+
+        if (canvasDOM.style) {
+          canvasDOM.style.width = width + 'px';
+          canvasDOM.style.height = height + 'px';
+        }
+
+        if (isCanvasElement(canvasDOM)) {
+          canvasDOM.width = width * pixelRatio;
+          canvasDOM.height = height * pixelRatio;
+
+          if (pixelRatio !== 1) {
+            var ctx = this.get('context');
+            ctx.scale(pixelRatio, pixelRatio);
+          }
+        }
+
+        this.set('width', width);
+        this.set('height', height);
+      }
+
+      getWidth() {
+        var pixelRatio = this.get('pixelRatio');
+        var width = this.get('width');
+        return width * pixelRatio;
+      }
+
+      getHeight() {
+        var pixelRatio = this.get('pixelRatio');
+        var height = this.get('height');
+        return height * pixelRatio;
+      }
+
+      getPointByClient(clientX, clientY) {
+        var el = this.get('el');
+        var bbox = el.getBoundingClientRect();
+        var width = bbox.right - bbox.left;
+        var height = bbox.bottom - bbox.top;
+        return {
+          x: (clientX - bbox.left) * (el.width / width),
+          y: (clientY - bbox.top) * (el.height / height)
+        };
+      }
+
+      _beginDraw() {
+        this._attrs.toDraw = true;
+      }
+
+      _endDraw() {
+        this._attrs.toDraw = false;
+      }
+
+      draw() {
+        var self = this;
+
+        function drawInner() {
+          self.set('animateHandler', requestAnimationFrame$1(function () {
+            self.set('animateHandler', undefined);
+
+            if (self.get('toDraw')) {
+              drawInner();
+            }
+          }));
+          self.beforeDraw();
+
+          try {
+            var context = self._attrs.context;
+            self.drawInner(context); // 支付宝,微信小程序,需要调context.draw才能完成绘制, 所以这里直接判断是否有.draw方法
+
+            if (context.draw) {
+              context.draw();
+            }
+          } catch (ev) {
+            console.warn('error in draw canvas, detail as:');
+            console.warn(ev);
+
+            self._endDraw();
+          }
+
+          self._endDraw();
+        }
+
+        if (self.get('destroyed')) {
+          return;
+        }
+
+        if (self.get('animateHandler')) {
+          this._beginDraw();
+        } else {
+          drawInner();
+        }
+      }
+
+      destroy() {
+        if (this.get('destroyed')) {
+          return;
+        } // 需要清理 canvas 画布内容,否则会导致 spa 应用 ios 下 canvas 白屏
+        // https://stackoverflow.com/questions/52532614/total-canvas-memory-use-exceeds-the-maximum-limit-safari-12
+        // https://github.com/antvis/F2/issues/630
+
+
+        var el = this.get('el');
+        el.width = 0;
+        el.height = 0;
+        this.clear();
+        this._attrs = {};
+        this.set('destroyed', true);
+      }
+
+      isDestroyed() {
+        return this.get('destroyed');
+      }
+
+    }
+
+    mix(Canvas.prototype, Container, {
+      getGroupClass() {
+        return Group;
+      }
+
+    });
+
+    function parseRadius$1(radius, width, height) {
+      radius = parsePadding(radius); // 都为0
+
+      if (!radius[0] && !radius[1] && !radius[2] && !radius[3]) {
+        return radius;
+      }
+
+      var minWidth = Math.max(radius[0] + radius[1], radius[2] + radius[3]);
+      var minHeight = Math.max(radius[0] + radius[3], radius[1] + radius[2]);
+      var scale = Math.min(width / minWidth, height / minHeight);
+
+      if (scale < 1) {
+        return radius.map(function (r) {
+          return r * scale;
+        });
+      }
+
+      return radius;
+    }
+
+    class Rect extends Shape$2 {
+      _initProperties() {
+        super._initProperties();
+
+        this._attrs.canFill = true;
+        this._attrs.canStroke = true;
+        this._attrs.type = 'rect';
+      }
+
+      getDefaultAttrs() {
+        return {
+          x: 0,
+          y: 0,
+          width: 0,
+          height: 0,
+          radius: 0,
+          lineWidth: 0
+        };
+      }
+
+      createPath(context) {
+        var self = this;
+        var attrs = self.get('attrs');
+        var {
+          x,
+          y,
+          width,
+          height,
+          radius
+        } = attrs;
+        context.beginPath();
+
+        if (!radius || !(width * height)) {
+          context.rect(x, y, width, height);
+        } else {
+          radius = parseRadius$1(radius, width, height);
+          context.moveTo(x + radius[0], y);
+          context.lineTo(x + width - radius[1], y);
+          context.arc(x + width - radius[1], y + radius[1], radius[1], -Math.PI / 2, 0, false);
+          context.lineTo(x + width, y + height - radius[2]);
+          context.arc(x + width - radius[2], y + height - radius[2], radius[2], 0, Math.PI / 2, false);
+          context.lineTo(x + radius[3], y + height);
+          context.arc(x + radius[3], y + height - radius[3], radius[3], Math.PI / 2, Math.PI, false);
+          context.lineTo(x, y + radius[0]);
+          context.arc(x + radius[0], y + radius[0], radius[0], Math.PI, Math.PI * 3 / 2, false);
+          context.closePath();
+        }
+      }
+
+      calculateBox() {
+        var attrs = this.get('attrs');
+        var {
+          x,
+          y,
+          width,
+          height
+        } = attrs;
+        return {
+          minX: x,
+          minY: y,
+          maxX: x + width,
+          maxY: y + height
+        };
+      }
+
+    }
+
+    Shape$2.Rect = Rect;
+
+    class ImageShape extends Shape$2 {
+      _initProperties() {
+        super._initProperties();
+
+        this._attrs.canFill = false;
+        this._attrs.canStroke = false;
+        this._attrs.loading = false;
+        this._attrs.image = null;
+        this._attrs.type = 'image';
+      }
+
+      getDefaultAttrs() {
+        return {
+          x: 0,
+          y: 0,
+          width: 0,
+          height: 0
+        };
+      }
+
+      createPath(context) {
+        var _this = this;
+
+        var attrs = this.get('attrs');
+        var {
+          src
+        } = attrs;
+
+        if (this.get('loading')) {
+          return;
+        }
+
+        var image = this.get('image');
+
+        if (image) {
+          this.drawImage(context, image);
+        } else {
+          if (src && Image) {
+            this.set('loading', true);
+
+            var _image = new Image();
+
+            _image.src = src; // 设置跨域
+
+            _image.crossOrigin = 'Anonymous';
+
+            _image.onload = function () {
+              _this.set('loading', false);
+
+              _this.set('image', _image);
+
+              _this.drawImage(context, _image);
+            };
+          }
+        }
+      }
+
+      drawImage(context, image) {
+        var attrs = this.get('attrs');
+        var {
+          x,
+          y,
+          width,
+          height,
+          sx,
+          sy,
+          swidth,
+          sheight
+        } = attrs;
+
+        if (!isNil(sx) && !isNil(sy) && !isNil(swidth) && !isNil(sheight)) {
+          context.drawImage(image, sx, sy, swidth, sheight, x, y, width, height);
+        } else {
+          context.drawImage(image, x, y, width, height);
+        }
+      }
+
+      calculateBox() {
+        var attrs = this.get('attrs');
+        var {
+          x,
+          y,
+          width,
+          height
+        } = attrs; // 和rect一样
+
+        return {
+          minX: x,
+          minY: y,
+          maxX: x + width,
+          maxY: y + height
+        };
+      }
+
+    }
+
+    Shape$2.Image = ImageShape;
+
+    class Circle extends Shape$2 {
+      _initProperties() {
+        super._initProperties();
+
+        this._attrs.canFill = true;
+        this._attrs.canStroke = true;
+        this._attrs.type = 'circle';
+      }
+
+      getDefaultAttrs() {
+        return {
+          x: 0,
+          y: 0,
+          r: 0,
+          lineWidth: 0
+        };
+      }
+
+      createPath(context) {
+        var attrs = this.get('attrs');
+        var {
+          x,
+          y,
+          r
+        } = attrs;
+        context.beginPath();
+        context.arc(x, y, r, 0, Math.PI * 2, false);
+        context.closePath();
+      }
+
+      calculateBox() {
+        var attrs = this.get('attrs');
+        var {
+          x,
+          y,
+          r
+        } = attrs;
+        return {
+          minX: x - r,
+          maxX: x + r,
+          minY: y - r,
+          maxY: y + r
+        };
+      }
+
+    }
+
+    Shape$2.Circle = Circle;
+
+    var start = Vector2.create();
+    var end = Vector2.create();
+    var extremity = Vector2.create();
+
+    function getCubicBezierXYatT(startPt, controlPt1, controlPt2, endPt, T) {
+      var x = CubicN(T, startPt.x, controlPt1.x, controlPt2.x, endPt.x);
+      var y = CubicN(T, startPt.y, controlPt1.y, controlPt2.y, endPt.y);
+      return {
+        x,
+        y
+      };
+    } // cubic helper formula at T distance
+
+
+    function CubicN(T, a, b, c, d) {
+      var t2 = T * T;
+      var t3 = t2 * T;
+      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;
+    }
+
+    function cubicBezierBounds(c) {
+      var minX = Infinity;
+      var maxX = -Infinity;
+      var minY = Infinity;
+      var maxY = -Infinity;
+      var s = {
+        x: c[0],
+        y: c[1]
+      };
+      var c1 = {
+        x: c[2],
+        y: c[3]
+      };
+      var c2 = {
+        x: c[4],
+        y: c[5]
+      };
+      var e = {
+        x: c[6],
+        y: c[7]
+      };
+
+      for (var t = 0; t < 100; t++) {
+        var pt = getCubicBezierXYatT(s, c1, c2, e, t / 100);
+
+        if (pt.x < minX) {
+          minX = pt.x;
+        }
+
+        if (pt.x > maxX) {
+          maxX = pt.x;
+        }
+
+        if (pt.y < minY) {
+          minY = pt.y;
+        }
+
+        if (pt.y > maxY) {
+          maxY = pt.y;
+        }
+      }
+
+      return {
+        minX,
+        minY,
+        maxX,
+        maxY
+      };
+    }
+
+    function getBBoxFromPoints(points, lineWidth) {
+      if (points.length === 0) {
+        return;
+      }
+
+      var p = points[0];
+      var left = p.x;
+      var right = p.x;
+      var top = p.y;
+      var bottom = p.y;
+      var len = points.length;
+
+      for (var i = 1; i < len; i++) {
+        p = points[i];
+        left = Math.min(left, p.x);
+        right = Math.max(right, p.x);
+        top = Math.min(top, p.y);
+        bottom = Math.max(bottom, p.y);
+      }
+
+      lineWidth = lineWidth / 2 || 0;
+      return {
+        minX: left - lineWidth,
+        minY: top - lineWidth,
+        maxX: right + lineWidth,
+        maxY: bottom + lineWidth
+      };
+    }
+
+    function getBBoxFromLine(x0, y0, x1, y1, lineWidth) {
+      lineWidth = lineWidth / 2 || 0;
+      return {
+        minX: Math.min(x0, x1) - lineWidth,
+        minY: Math.min(y0, y1) - lineWidth,
+        maxX: Math.max(x0, x1) + lineWidth,
+        maxY: Math.max(y0, y1) + lineWidth
+      };
+    }
+
+    function getBBoxFromArc(x, y, r, startAngle, endAngle, anticlockwise) {
+      var diff = Math.abs(startAngle - endAngle);
+
+      if (diff % (Math.PI * 2) < 1e-4 && diff > 1e-4) {
+        // Is a circle
+        return {
+          minX: x - r,
+          minY: y - r,
+          maxX: x + r,
+          maxY: y + r
+        };
+      }
+
+      start[0] = Math.cos(startAngle) * r + x;
+      start[1] = Math.sin(startAngle) * r + y;
+      end[0] = Math.cos(endAngle) * r + x;
+      end[1] = Math.sin(endAngle) * r + y;
+      var min = [0, 0];
+      var max = [0, 0];
+      Vector2.min(min, start, end);
+      Vector2.max(max, start, end); // Thresh to [0, Math.PI * 2]
+
+      startAngle = startAngle % (Math.PI * 2);
+
+      if (startAngle < 0) {
+        startAngle = startAngle + Math.PI * 2;
+      }
+
+      endAngle = endAngle % (Math.PI * 2);
+
+      if (endAngle < 0) {
+        endAngle = endAngle + Math.PI * 2;
+      }
+
+      if (startAngle > endAngle && !anticlockwise) {
+        endAngle += Math.PI * 2;
+      } else if (startAngle < endAngle && anticlockwise) {
+        startAngle += Math.PI * 2;
+      }
+
+      if (anticlockwise) {
+        var tmp = endAngle;
+        endAngle = startAngle;
+        startAngle = tmp;
+      }
+
+      for (var angle = 0; angle < endAngle; angle += Math.PI / 2) {
+        if (angle > startAngle) {
+          extremity[0] = Math.cos(angle) * r + x;
+          extremity[1] = Math.sin(angle) * r + y;
+          Vector2.min(min, extremity, min);
+          Vector2.max(max, extremity, max);
+        }
+      }
+
+      return {
+        minX: min[0],
+        minY: min[1],
+        maxX: max[0],
+        maxY: max[1]
+      };
+    }
+
+    function getBBoxFromBezierGroup(points, lineWidth) {
+      var minX = Infinity;
+      var maxX = -Infinity;
+      var minY = Infinity;
+      var maxY = -Infinity;
+
+      for (var i = 0, len = points.length; i < len; i++) {
+        var bbox = cubicBezierBounds(points[i]);
+
+        if (bbox.minX < minX) {
+          minX = bbox.minX;
+        }
+
+        if (bbox.maxX > maxX) {
+          maxX = bbox.maxX;
+        }
+
+        if (bbox.minY < minY) {
+          minY = bbox.minY;
+        }
+
+        if (bbox.maxY > maxY) {
+          maxY = bbox.maxY;
+        }
+      }
+
+      lineWidth = lineWidth / 2 || 0;
+      return {
+        minX: minX - lineWidth,
+        minY: minY - lineWidth,
+        maxX: maxX + lineWidth,
+        maxY: maxY + lineWidth
+      };
+    }
+
+    class Line$1 extends Shape$2 {
+      _initProperties() {
+        super._initProperties();
+
+        this._attrs.canStroke = true;
+        this._attrs.type = 'line';
+      }
+
+      getDefaultAttrs() {
+        return {
+          x1: 0,
+          y1: 0,
+          x2: 0,
+          y2: 0,
+          lineWidth: 1
+        };
+      }
+
+      createPath(context) {
+        var attrs = this.get('attrs');
+        var {
+          x1,
+          y1,
+          x2,
+          y2
+        } = attrs;
+        context.beginPath();
+        context.moveTo(x1, y1);
+        context.lineTo(x2, y2);
+      }
+
+      calculateBox() {
+        var attrs = this.get('attrs');
+        var {
+          x1,
+          y1,
+          x2,
+          y2,
+          lineWidth
+        } = attrs;
+        return getBBoxFromLine(x1, y1, x2, y2, lineWidth);
+      }
+
+    }
+
+    Shape$2.Line = Line$1;
+
+    class Polygon extends Shape$2 {
+      _initProperties() {
+        super._initProperties();
+
+        this._attrs.canFill = true;
+        this._attrs.canStroke = true;
+        this._attrs.type = 'polygon';
+      }
+
+      getDefaultAttrs() {
+        return {
+          points: null,
+          lineWidth: 0
+        };
+      }
+
+      createPath(context) {
+        var self = this;
+        var attrs = self.get('attrs');
+        var points = attrs.points;
+        context.beginPath();
+
+        for (var i = 0, len = points.length; i < len; i++) {
+          var point = points[i];
+
+          if (i === 0) {
+            context.moveTo(point.x, point.y);
+          } else {
+            context.lineTo(point.x, point.y);
+          }
+        }
+
+        context.closePath();
+      }
+
+      calculateBox() {
+        var attrs = this.get('attrs');
+        var {
+          points
+        } = attrs;
+        return getBBoxFromPoints(points);
+      }
+
+    }
+
+    Shape$2.Polygon = Polygon;
+
+    /**
+     * @fileOverview convert the line to curve
+     * @author dxq613@gmail.com
+     */
+
+    function getPoint(v) {
+      return [v.x, v.y];
+    }
+
+    function smoothBezier(points, smooth, isLoop, constraint) {
+      var cps = [];
+      var prevPoint;
+      var nextPoint;
+      var hasConstraint = !!constraint;
+      var min;
+      var max;
+      var point;
+      var len;
+      var l;
+      var i;
+
+      if (hasConstraint) {
+        min = [Infinity, Infinity];
+        max = [-Infinity, -Infinity];
+
+        for (i = 0, l = points.length; i < l; i++) {
+          point = getPoint(points[i]);
+          Vector2.min(min, min, point);
+          Vector2.max(max, max, point);
+        }
+
+        Vector2.min(min, min, constraint[0]);
+        Vector2.max(max, max, constraint[1]);
+      }
+
+      for (i = 0, len = points.length; i < len; i++) {
+        point = getPoint(points[i]);
+
+        if (isLoop) {
+          prevPoint = getPoint(points[i ? i - 1 : len - 1]);
+          nextPoint = getPoint(points[(i + 1) % len]);
+        } else {
+          if (i === 0 || i === len - 1) {
+            cps.push([point[0], point[1]]);
+            continue;
+          } else {
+            prevPoint = getPoint(points[i - 1]);
+            nextPoint = getPoint(points[i + 1]);
+          }
+        }
+
+        var v = Vector2.sub([], nextPoint, prevPoint);
+        Vector2.scale(v, v, smooth);
+        var d0 = Vector2.distance(point, prevPoint);
+        var d1 = Vector2.distance(point, nextPoint);
+        var sum = d0 + d1;
+
+        if (sum !== 0) {
+          d0 /= sum;
+          d1 /= sum;
+        }
+
+        var v1 = Vector2.scale([], v, -d0);
+        var v2 = Vector2.scale([], v, d1);
+        var cp0 = Vector2.add([], point, v1);
+        var cp1 = Vector2.add([], point, v2);
+
+        if (hasConstraint) {
+          Vector2.max(cp0, cp0, min);
+          Vector2.min(cp0, cp0, max);
+          Vector2.max(cp1, cp1, min);
+          Vector2.min(cp1, cp1, max);
+        }
+
+        cps.push([cp0[0], cp0[1]]);
+        cps.push([cp1[0], cp1[1]]);
+      }
+
+      if (isLoop) {
+        cps.push(cps.shift());
+      }
+
+      return cps;
+    }
+
+    function catmullRom2bezier(pointList, z, constraint) {
+      var isLoop = !!z;
+      var controlPointList = smoothBezier(pointList, 0.4, isLoop, constraint);
+      var len = pointList.length;
+      var d1 = [];
+      var cp1;
+      var cp2;
+      var p;
+
+      for (var i = 0; i < len - 1; i++) {
+        cp1 = controlPointList[i * 2];
+        cp2 = controlPointList[i * 2 + 1];
+        p = pointList[i + 1];
+        d1.push(['C', cp1[0], cp1[1], cp2[0], cp2[1], p.x, p.y]);
+      }
+
+      if (isLoop) {
+        cp1 = controlPointList[len];
+        cp2 = controlPointList[len + 1];
+        p = pointList[0];
+        d1.push(['C', cp1[0], cp1[1], cp2[0], cp2[1], p.x, p.y]);
+      }
+
+      return d1;
+    }
+
+    function _filterPoints(points) {
+      var filteredPoints = [];
+
+      for (var i = 0, len = points.length; i < len; i++) {
+        var point = points[i];
+
+        if (!isNaN(point.x) && !isNaN(point.y)) {
+          filteredPoints.push(point);
+        }
+      }
+
+      return filteredPoints;
+    }
+
+    class Polyline extends Shape$2 {
+      _initProperties() {
+        super._initProperties();
+
+        this._attrs.canFill = true;
+        this._attrs.canStroke = true;
+        this._attrs.type = 'polyline';
+      }
+
+      getDefaultAttrs() {
+        return {
+          points: null,
+          lineWidth: 1,
+          smooth: false
+        };
+      }
+
+      createPath(context) {
+        var self = this;
+        var attrs = self.get('attrs');
+        var {
+          points,
+          smooth
+        } = attrs;
+
+        var filteredPoints = _filterPoints(points);
+
+        context.beginPath();
+
+        if (filteredPoints.length) {
+          context.moveTo(filteredPoints[0].x, filteredPoints[0].y);
+
+          if (smooth) {
+            var constaint = [[0, 0], [1, 1]];
+            var sps = catmullRom2bezier(filteredPoints, false, constaint);
+
+            for (var i = 0, n = sps.length; i < n; i++) {
+              var sp = sps[i];
+              context.bezierCurveTo(sp[1], sp[2], sp[3], sp[4], sp[5], sp[6]);
+            }
+          } else {
+            var _i;
+
+            var l;
+
+            for (_i = 1, l = filteredPoints.length - 1; _i < l; _i++) {
+              context.lineTo(filteredPoints[_i].x, filteredPoints[_i].y);
+            }
+
+            context.lineTo(filteredPoints[l].x, filteredPoints[l].y);
+          }
+        }
+      }
+
+      calculateBox() {
+        var attrs = this.get('attrs');
+        var {
+          points,
+          smooth,
+          lineWidth
+        } = attrs;
+
+        var filteredPoints = _filterPoints(points);
+
+        if (smooth) {
+          var newPoints = [];
+          var constaint = [[0, 0], [1, 1]];
+          var sps = catmullRom2bezier(filteredPoints, false, constaint);
+
+          for (var i = 0, n = sps.length; i < n; i++) {
+            var sp = sps[i];
+
+            if (i === 0) {
+              newPoints.push([filteredPoints[0].x, filteredPoints[0].y, sp[1], sp[2], sp[3], sp[4], sp[5], sp[6]]);
+            } else {
+              var lastPoint = sps[i - 1];
+              newPoints.push([lastPoint[5], lastPoint[6], sp[1], sp[2], sp[3], sp[4], sp[5], sp[6]]);
+            }
+          }
+
+          return getBBoxFromBezierGroup(newPoints, lineWidth);
+        }
+
+        return getBBoxFromPoints(filteredPoints, lineWidth);
+      }
+
+    }
+
+    Shape$2.Polyline = Polyline;
+
+    class Arc extends Shape$2 {
+      _initProperties() {
+        super._initProperties();
+
+        this._attrs.canStroke = true;
+        this._attrs.canFill = true;
+        this._attrs.type = 'arc';
+      }
+
+      getDefaultAttrs() {
+        return {
+          x: 0,
+          y: 0,
+          r: 0,
+          startAngle: 0,
+          endAngle: Math.PI * 2,
+          anticlockwise: false,
+          lineWidth: 1
+        };
+      }
+
+      createPath(context) {
+        var attrs = this.get('attrs');
+        var {
+          x,
+          y,
+          r,
+          startAngle,
+          endAngle,
+          anticlockwise
+        } = attrs;
+        context.beginPath();
+
+        if (startAngle !== endAngle) {
+          context.arc(x, y, r, startAngle, endAngle, anticlockwise);
+        }
+      }
+
+      calculateBox() {
+        var attrs = this.get('attrs');
+        var {
+          x,
+          y,
+          r,
+          startAngle,
+          endAngle,
+          anticlockwise
+        } = attrs;
+        return getBBoxFromArc(x, y, r, startAngle, endAngle, anticlockwise);
+      }
+
+    }
+
+    Shape$2.Arc = Arc;
+
+    class Sector extends Shape$2 {
+      _initProperties() {
+        super._initProperties();
+
+        this._attrs.canFill = true;
+        this._attrs.canStroke = true;
+        this._attrs.type = 'sector';
+      }
+
+      getDefaultAttrs() {
+        return {
+          x: 0,
+          y: 0,
+          lineWidth: 0,
+          r: 0,
+          r0: 0,
+          startAngle: 0,
+          endAngle: Math.PI * 2,
+          anticlockwise: false
+        };
+      }
+
+      createPath(context) {
+        var attrs = this.get('attrs');
+        var {
+          x,
+          y,
+          startAngle,
+          endAngle,
+          r,
+          r0,
+          anticlockwise
+        } = attrs;
+        context.beginPath();
+        var unitX = Math.cos(startAngle);
+        var unitY = Math.sin(startAngle);
+        context.moveTo(unitX * r0 + x, unitY * r0 + y);
+        context.lineTo(unitX * r + x, unitY * r + y); // 当扇形的角度非常小的时候,就不进行弧线的绘制;或者整个只有1个扇形时,会出现end<0的情况不绘制
+
+        if (Math.abs(endAngle - startAngle) > 0.0001 || startAngle === 0 && endAngle < 0) {
+          context.arc(x, y, r, startAngle, endAngle, anticlockwise);
+          context.lineTo(Math.cos(endAngle) * r0 + x, Math.sin(endAngle) * r0 + y);
+
+          if (r0 !== 0) {
+            context.arc(x, y, r0, endAngle, startAngle, !anticlockwise);
+          }
+        }
+
+        context.closePath();
+      }
+
+      calculateBox() {
+        var attrs = this.get('attrs');
+        var {
+          x,
+          y,
+          r,
+          r0,
+          startAngle,
+          endAngle,
+          anticlockwise
+        } = attrs;
+        var outerBBox = getBBoxFromArc(x, y, r, startAngle, endAngle, anticlockwise);
+        var innerBBox = getBBoxFromArc(x, y, r0, startAngle, endAngle, anticlockwise);
+        return {
+          minX: Math.min(outerBBox.minX, innerBBox.minX),
+          minY: Math.min(outerBBox.minY, innerBBox.minY),
+          maxX: Math.max(outerBBox.maxX, innerBBox.maxX),
+          maxY: Math.max(outerBBox.maxY, innerBBox.maxY)
+        };
+      }
+
+    }
+
+    Shape$2.Sector = Sector;
+
+    var Rect$1 = {
+      calcRotatedBox(_ref) {
+        var {
+          width,
+          height,
+          rotate
+        } = _ref;
+        var absRotate = Math.abs(rotate);
+        return {
+          width: Math.abs(width * Math.cos(absRotate) + height * Math.sin(absRotate)),
+          height: Math.abs(height * Math.cos(absRotate) + width * Math.sin(absRotate))
+        };
+      }
+
+    };
+
+    var textWidthCacheCounter = 0;
+    var textWidthCache = {};
+    var TEXT_CACHE_MAX = 5000;
+
+    class Text extends Shape$2 {
+      _initProperties() {
+        super._initProperties();
+
+        this._attrs.canFill = true;
+        this._attrs.canStroke = true;
+        this._attrs.type = 'text';
+      }
+
+      getDefaultAttrs() {
+        return {
+          lineWidth: 0,
+          lineCount: 1,
+          fontSize: 12,
+          fontFamily: 'sans-serif',
+          fontStyle: 'normal',
+          fontWeight: 'normal',
+          fontVariant: 'normal',
+          textAlign: 'start',
+          textBaseline: 'bottom',
+          lineHeight: null,
+          textArr: null
+        };
+      }
+
+      _getFontStyle() {
+        var attrs = this._attrs.attrs;
+        var {
+          fontSize,
+          fontFamily,
+          fontWeight,
+          fontStyle,
+          fontVariant
+        } = attrs;
+        return "".concat(fontStyle, " ").concat(fontVariant, " ").concat(fontWeight, " ").concat(fontSize, "px ").concat(fontFamily);
+      }
+
+      _afterAttrsSet() {
+        var attrs = this._attrs.attrs;
+        attrs.font = this._getFontStyle();
+
+        if (attrs.text) {
+          var text = attrs.text;
+          var textArr = null;
+          var lineCount = 1;
+
+          if (isString(text) && text.indexOf('\n') !== -1) {
+            textArr = text.split('\n');
+            lineCount = textArr.length;
+          }
+
+          attrs.lineCount = lineCount;
+          attrs.textArr = textArr;
+        }
+
+        this.set('attrs', attrs);
+      }
+
+      _getTextHeight() {
+        var attrs = this._attrs.attrs;
+
+        if (attrs.height) {
+          return attrs.height;
+        }
+
+        var lineCount = attrs.lineCount;
+        var fontSize = attrs.fontSize * 1;
+
+        if (lineCount > 1) {
+          var spaceingY = this._getSpaceingY();
+
+          return fontSize * lineCount + spaceingY * (lineCount - 1);
+        }
+
+        return fontSize;
+      }
+
+      _getSpaceingY() {
+        var attrs = this._attrs.attrs;
+        var lineHeight = attrs.lineHeight;
+        var fontSize = attrs.fontSize * 1;
+        return lineHeight ? lineHeight - fontSize : fontSize * 0.14;
+      }
+
+      drawInner(context) {
+        var self = this;
+        var attrs = self._attrs.attrs;
+        var text = attrs.text;
+        var x = attrs.x;
+        var y = attrs.y;
+
+        if (isNil(text) || isNaN(x) || isNaN(y)) {
+          // text will be 0
+          return;
+        }
+
+        var textArr = attrs.textArr;
+        var fontSize = attrs.fontSize * 1;
+
+        var spaceingY = self._getSpaceingY();
+
+        if (attrs.rotate) {
+          // do rotation
+          context.translate(x, y);
+          context.rotate(attrs.rotate);
+          x = 0;
+          y = 0;
+        }
+
+        var textBaseline = attrs.textBaseline;
+        var height;
+
+        if (textArr) {
+          height = self._getTextHeight();
+        }
+
+        var subY; // context.beginPath();
+
+        if (self.hasFill()) {
+          var fillOpacity = attrs.fillOpacity;
+
+          if (!isNil(fillOpacity) && fillOpacity !== 1) {
+            context.globalAlpha = fillOpacity;
+          }
+
+          if (textArr) {
+            for (var i = 0, len = textArr.length; i < len; i++) {
+              var subText = textArr[i];
+              subY = y + i * (spaceingY + fontSize) - height + fontSize; // bottom;
+
+              if (textBaseline === 'middle') {
+                subY += height - fontSize - (height - fontSize) / 2;
+              }
+
+              if (textBaseline === 'top') {
+                subY += height - fontSize;
+              }
+
+              context.fillText(subText, x, subY);
+            }
+          } else {
+            context.fillText(text, x, y);
+          }
+        }
+
+        if (self.hasStroke()) {
+          if (textArr) {
+            for (var _i = 0, _len = textArr.length; _i < _len; _i++) {
+              var _subText = textArr[_i];
+              subY = y + _i * (spaceingY + fontSize) - height + fontSize; // bottom;
+
+              if (textBaseline === 'middle') {
+                subY += height - fontSize - (height - fontSize) / 2;
+              }
+
+              if (textBaseline === 'top') {
+                subY += height - fontSize;
+              }
+
+              context.strokeText(_subText, x, subY);
+            }
+          } else {
+            context.strokeText(text, x, y);
+          }
+        }
+      }
+
+      calculateBox() {
+        var self = this;
+        var attrs = self._attrs.attrs;
+        var {
+          x,
+          y,
+          textAlign,
+          textBaseline
+        } = attrs;
+
+        var width = self._getTextWidth(); // attrs.width
+
+
+        if (!width) {
+          return {
+            minX: x,
+            minY: y,
+            maxX: x,
+            maxY: y
+          };
+        }
+
+        var height = self._getTextHeight(); // attrs.height
+
+
+        if (attrs.rotate) {
+          var rotatedBox = Rect$1.calcRotatedBox({
+            width,
+            height,
+            rotate: attrs.rotate
+          });
+          width = rotatedBox.width;
+          height = rotatedBox.height;
+        }
+
+        var point = {
+          x,
+          y: y - height
+        }; // default textAlign: start, textBaseline: bottom
+
+        if (textAlign) {
+          if (textAlign === 'end' || textAlign === 'right') {
+            point.x -= width;
+          } else if (textAlign === 'center') {
+            point.x -= width / 2;
+          }
+        }
+
+        if (textBaseline) {
+          if (textBaseline === 'top') {
+            point.y += height;
+          } else if (textBaseline === 'middle') {
+            point.y += height / 2;
+          }
+        }
+
+        return {
+          minX: point.x,
+          minY: point.y,
+          maxX: point.x + width,
+          maxY: point.y + height
+        };
+      }
+
+      _getTextWidth() {
+        var attrs = this._attrs.attrs;
+
+        if (attrs.width) {
+          return attrs.width;
+        }
+
+        var text = attrs.text;
+        var context = this.get('context');
+        if (isNil(text)) return undefined;
+        var font = attrs.font;
+        var textArr = attrs.textArr;
+        var key = text + '' + font;
+
+        if (textWidthCache[key]) {
+          return textWidthCache[key];
+        }
+
+        var width = 0;
+
+        if (textArr) {
+          for (var i = 0, length = textArr.length; i < length; i++) {
+            var subText = textArr[i];
+            width = Math.max(width, measureText(subText, font, context).width);
+          }
+        } else {
+          width = measureText(text, font, context).width;
+        }
+
+        if (textWidthCacheCounter > TEXT_CACHE_MAX) {
+          textWidthCacheCounter = 0;
+          textWidthCache = {};
+        }
+
+        textWidthCacheCounter++;
+        textWidthCache[key] = width;
+        return width;
+      }
+
+    }
+
+    Shape$2.Text = Text;
+
+    class Custom extends Shape$2 {
+      _initProperties() {
+        super._initProperties();
+
+        this._attrs.canFill = true;
+        this._attrs.canStroke = true;
+        this._attrs.createPath = null;
+        this._attrs.type = 'custom';
+      }
+
+      createPath(context) {
+        var createPath = this.get('createPath');
+        createPath && createPath.call(this, context);
+      }
+
+      calculateBox() {
+        var calculateBox = this.get('calculateBox');
+        return calculateBox && calculateBox.call(this);
+      }
+
+    }
+
+    Shape$2.Custom = Custom;
+
+
+
+    var G = /*#__PURE__*/Object.freeze({
+        __proto__: null,
+        Canvas: Canvas,
+        Group: Group,
+        Shape: Shape$2,
+        Matrix: Matrix,
+        Vector2: Vector2
+    });
+
+    function formatTicks(ticks) {
+      var tmp = ticks.slice(0);
+
+      if (tmp.length > 0) {
+        var first = tmp[0];
+        var last = tmp[tmp.length - 1];
+
+        if (first.value !== 0) {
+          tmp.unshift({
+            value: 0
+          });
+        }
+
+        if (last.value !== 1) {
+          tmp.push({
+            value: 1
+          });
+        }
+      }
+
+      return tmp;
+    }
+
+    class AxisController {
+      constructor(cfg) {
+        this.axisCfg = {};
+        this.frontPlot = null;
+        this.backPlot = null;
+        this.axes = {}; // store the axes's options
+
+        mix(this, cfg);
+      }
+
+      _isHide(field) {
+        var axisCfg = this.axisCfg;
+        return !axisCfg || axisCfg[field] === false;
+      }
+
+      _getLinePosition(scale, dimType, index, transposed) {
+        var position = '';
+        var field = scale.field;
+        var axisCfg = this.axisCfg;
+
+        if (axisCfg[field] && axisCfg[field].position) {
+          position = axisCfg[field].position;
+        } else if (dimType === 'x') {
+          position = transposed ? 'left' : 'bottom';
+        } else if (dimType === 'y') {
+          position = index ? 'right' : 'left';
+
+          if (transposed) {
+            position = 'bottom';
+          }
+        }
+
+        return position;
+      }
+
+      _getLineCfg(coord, dimType, position) {
+        var start;
+        var end;
+        var factor = 1; // Mark clockwise or counterclockwise
+
+        if (dimType === 'x') {
+          start = {
+            x: 0,
+            y: 0
+          };
+          end = {
+            x: 1,
+            y: 0
+          };
+        } else {
+          if (position === 'right') {
+            // there will be several y axes
+            start = {
+              x: 1,
+              y: 0
+            };
+            end = {
+              x: 1,
+              y: 1
+            };
+          } else {
+            start = {
+              x: 0,
+              y: 0
+            };
+            end = {
+              x: 0,
+              y: 1
+            };
+            factor = -1;
+          }
+        }
+
+        if (coord.transposed) {
+          factor *= -1;
+        }
+
+        return {
+          offsetFactor: factor,
+          start: coord.convertPoint(start),
+          end: coord.convertPoint(end)
+        };
+      }
+
+      _getCircleCfg(coord) {
+        return {
+          startAngle: coord.startAngle,
+          endAngle: coord.endAngle,
+          center: coord.center,
+          radius: coord.circleRadius
+        };
+      }
+
+      _getRadiusCfg(coord) {
+        var transposed = coord.transposed;
+        var start;
+        var end;
+
+        if (transposed) {
+          start = {
+            x: 0,
+            y: 0
+          };
+          end = {
+            x: 1,
+            y: 0
+          };
+        } else {
+          start = {
+            x: 0,
+            y: 0
+          };
+          end = {
+            x: 0,
+            y: 1
+          };
+        }
+
+        return {
+          offsetFactor: -1,
+          start: coord.convertPoint(start),
+          end: coord.convertPoint(end)
+        };
+      }
+
+      _getAxisCfg(coord, scale, verticalScale, dimType, defaultCfg) {
+        var self = this;
+        var axisCfg = this.axisCfg;
+        var ticks = scale.getTicks();
+        var cfg = deepMix({
+          ticks,
+          frontContainer: this.frontPlot,
+          backContainer: this.backPlot
+        }, defaultCfg, axisCfg[scale.field]);
+        var labels = [];
+        var label = cfg.label;
+        var count = ticks.length;
+        var maxWidth = 0;
+        var maxHeight = 0;
+        var labelCfg = label;
+        each(ticks, function (tick, index) {
+          if (isFunction(label)) {
+            var executedLabel = label(tick.text, index, count);
+            labelCfg = executedLabel ? mix({}, Global._defaultAxis.label, executedLabel) : null;
+          }
+
+          if (labelCfg) {
+            var textStyle = {};
+
+            if (labelCfg.textAlign) {
+              textStyle.textAlign = labelCfg.textAlign;
+            }
+
+            if (labelCfg.textBaseline) {
+              textStyle.textBaseline = labelCfg.textBaseline;
+            }
+
+            var axisLabel = new Shape$2.Text({
+              className: 'axis-label',
+              attrs: mix({
+                x: 0,
+                y: 0,
+                text: tick.text,
+                fontFamily: self.chart.get('canvas').get('fontFamily')
+              }, labelCfg),
+              value: tick.value,
+              textStyle,
+              top: labelCfg.top,
+              context: self.chart.get('canvas').get('context')
+            });
+            labels.push(axisLabel);
+            var {
+              width,
+              height
+            } = axisLabel.getBBox();
+            maxWidth = Math.max(maxWidth, width);
+            maxHeight = Math.max(maxHeight, height);
+          }
+        });
+        cfg.labels = labels;
+        cfg.maxWidth = maxWidth;
+        cfg.maxHeight = maxHeight;
+        return cfg;
+      }
+
+      _createAxis(coord, scale, verticalScale, dimType) {
+        var index = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : '';
+        var self = this;
+        var coordType = coord.type;
+        var transposed = coord.transposed;
+        var type;
+        var key;
+        var defaultCfg;
+
+        if (coordType === 'cartesian' || coordType === 'rect') {
+          var position = self._getLinePosition(scale, dimType, index, transposed);
+
+          defaultCfg = Global.axis[position];
+          defaultCfg.position = position;
+          type = 'Line';
+          key = position;
+        } else {
+          if (dimType === 'x' && !transposed || dimType === 'y' && transposed) {
+            defaultCfg = Global.axis.circle;
+            type = 'Circle';
+            key = 'circle';
+          } else {
+            defaultCfg = Global.axis.radius;
+            type = 'Line';
+            key = 'radius';
+          }
+        }
+
+        var cfg = self._getAxisCfg(coord, scale, verticalScale, dimType, defaultCfg);
+
+        cfg.type = type;
+        cfg.dimType = dimType;
+        cfg.verticalScale = verticalScale;
+        cfg.index = index;
+        this.axes[key] = cfg;
+      }
+
+      createAxis(coord, xScale, yScales) {
+        var self = this;
+
+        if (xScale && !self._isHide(xScale.field)) {
+          self._createAxis(coord, xScale, yScales[0], 'x');
+        }
+
+        each(yScales, function (yScale, index) {
+          if (!self._isHide(yScale.field)) {
+            self._createAxis(coord, yScale, xScale, 'y', index);
+          }
+        });
+        var axes = this.axes;
+        var chart = self.chart;
+
+        if (chart._isAutoPadding()) {
+          var userPadding = parsePadding(chart.get('padding'));
+          var appendPadding = parsePadding(chart.get('appendPadding'));
+          var legendRange = chart.get('legendRange') || {
+            top: 0,
+            right: 0,
+            bottom: 0,
+            left: 0
+          };
+          var padding = [userPadding[0] === 'auto' ? legendRange.top + appendPadding[0] * 2 : userPadding[0], userPadding[1] === 'auto' ? legendRange.right + appendPadding[1] : userPadding[1], userPadding[2] === 'auto' ? legendRange.bottom + appendPadding[2] : userPadding[2], userPadding[3] === 'auto' ? legendRange.left + appendPadding[3] : userPadding[3]];
+
+          if (coord.isPolar) {
+            var circleAxis = axes.circle;
+
+            if (circleAxis) {
+              var {
+                maxHeight,
+                maxWidth,
+                labelOffset
+              } = circleAxis;
+              padding[0] += maxHeight + labelOffset;
+              padding[1] += maxWidth + labelOffset;
+              padding[2] += maxHeight + labelOffset;
+              padding[3] += maxWidth + labelOffset;
+            }
+          } else {
+            if (axes.right && userPadding[1] === 'auto') {
+              var {
+                maxWidth: _maxWidth,
+                labelOffset: _labelOffset
+              } = axes.right;
+              padding[1] += _maxWidth + _labelOffset;
+            }
+
+            if (axes.left && userPadding[3] === 'auto') {
+              var {
+                maxWidth: _maxWidth2,
+                labelOffset: _labelOffset2
+              } = axes.left;
+              padding[3] += _maxWidth2 + _labelOffset2;
+            }
+
+            if (axes.bottom && userPadding[2] === 'auto') {
+              var {
+                maxHeight: _maxHeight,
+                labelOffset: _labelOffset3
+              } = axes.bottom;
+              padding[2] += _maxHeight + _labelOffset3;
+            }
+          }
+
+          chart.set('_padding', padding);
+
+          chart._updateLayout(padding);
+        }
+
+        each(axes, function (axis) {
+          var {
+            type,
+            grid,
+            verticalScale,
+            ticks,
+            dimType,
+            position,
+            index
+          } = axis;
+          var appendCfg;
+
+          if (coord.isPolar) {
+            if (type === 'Line') {
+              appendCfg = self._getRadiusCfg(coord);
+            } else if (type === 'Circle') {
+              appendCfg = self._getCircleCfg(coord);
+            }
+          } else {
+            appendCfg = self._getLineCfg(coord, dimType, position);
+          }
+
+          if (grid && verticalScale) {
+            var gridPoints = [];
+            var verticalTicks = formatTicks(verticalScale.getTicks());
+            each(ticks, function (tick) {
+              var subPoints = [];
+              each(verticalTicks, function (verticalTick) {
+                var x = dimType === 'x' ? tick.value : verticalTick.value;
+                var y = dimType === 'x' ? verticalTick.value : tick.value;
+
+                if (x >= 0 && x <= 1 && y >= 0 && y <= 1) {
+                  var point = coord.convertPoint({
+                    x,
+                    y
+                  });
+                  subPoints.push(point);
+                }
+              });
+              gridPoints.push({
+                points: subPoints,
+                _id: 'axis-' + dimType + index + '-grid-' + tick.tickValue
+              });
+            });
+            axis.gridPoints = gridPoints;
+
+            if (coord.isPolar) {
+              axis.center = coord.center;
+              axis.startAngle = coord.startAngle;
+              axis.endAngle = coord.endAngle;
+            }
+          }
+
+          appendCfg._id = 'axis-' + dimType;
+
+          if (!isNil(index)) {
+            appendCfg._id = 'axis-' + dimType + index;
+          }
+
+          new Abastract[type](mix(axis, appendCfg));
+        });
+      }
+
+      clear() {
+        this.axes = {};
+        this.frontPlot.clear();
+        this.backPlot.clear();
+      }
+
+    }
+
+    function getClip(coord) {
+      var start = coord.start;
+      var end = coord.end;
+      var width = end.x - start.x;
+      var height = Math.abs(end.y - start.y);
+      var margin = 10;
+      var clip;
+
+      if (coord.isPolar) {
+        var {
+          circleRadius,
+          center,
+          startAngle,
+          endAngle
+        } = coord;
+        clip = new Shape$2.Sector({
+          attrs: {
+            x: center.x,
+            y: center.y,
+            r: circleRadius,
+            r0: 0,
+            startAngle,
+            endAngle
+          }
+        });
+      } else {
+        clip = new Shape$2.Rect({
+          attrs: {
+            x: start.x,
+            y: end.y - margin,
+            width,
+            height: height + 2 * margin
+          }
+        });
+      }
+
+      clip.isClip = true;
+      return clip;
+    }
+
+    function isPointInPlot(point, plot) {
+      var {
+        x,
+        y
+      } = point;
+      var {
+        tl,
+        tr,
+        br
+      } = plot;
+      return x >= tl.x && x <= tr.x && y >= tl.y && y <= br.y;
+    }
+
+    var Helper = /*#__PURE__*/Object.freeze({
+        __proto__: null,
+        getClip: getClip,
+        isPointInPlot: isPointInPlot
+    });
+
+    function compare(a, b) {
+      return a - b;
+    }
+
+    function _isScaleExist(scales, compareScale) {
+      var flag = false;
+      each(scales, function (scale) {
+        var scaleValues = [].concat(scale.values);
+        var compareScaleValues = [].concat(compareScale.values);
+
+        if (scale.type === compareScale.type && scale.field === compareScale.field && scaleValues.sort(compare).toString() === compareScaleValues.sort(compare).toString()) {
+          flag = true;
+          return;
+        }
+      });
+      return flag;
+    }
+
+    class Chart extends Base {
+      static initPlugins() {
+        return {
+          _plugins: [],
+          _cacheId: 0,
+
+          register(plugins) {
+            var p = this._plugins;
+            [].concat(plugins).forEach(function (plugin) {
+              if (p.indexOf(plugin) === -1) {
+                p.push(plugin);
+              }
+            });
+            this._cacheId++;
+          },
+
+          unregister(plugins) {
+            var p = this._plugins;
+            [].concat(plugins).forEach(function (plugin) {
+              var idx = p.indexOf(plugin);
+
+              if (idx !== -1) {
+                p.splice(idx, 1);
+              }
+            });
+            this._cacheId++;
+          },
+
+          clear() {
+            this._plugins = [];
+            this._cacheId++;
+          },
+
+          count() {
+            return this._plugins.length;
+          },
+
+          getAll() {
+            return this._plugins;
+          },
+
+          notify(chart, hook, args) {
+            var descriptors = this.descriptors(chart);
+            var ilen = descriptors.length;
+            var i;
+            var descriptor;
+            var plugin;
+            var params;
+            var method;
+
+            for (i = 0; i < ilen; ++i) {
+              descriptor = descriptors[i];
+              plugin = descriptor.plugin;
+              method = plugin[hook];
+
+              if (typeof method === 'function') {
+                params = [chart].concat(args || []);
+
+                if (method.apply(plugin, params) === false) {
+                  return false;
+                }
+              }
+            }
+
+            return true;
+          },
+
+          descriptors(chart) {
+            var cache = chart._plugins || (chart._plugins = {});
+
+            if (cache.id === this._cacheId) {
+              return cache.descriptors;
+            }
+
+            var plugins = [];
+            var descriptors = [];
+
+            this._plugins.concat(chart && chart.get('plugins') || []).forEach(function (plugin) {
+              var idx = plugins.indexOf(plugin);
+
+              if (idx !== -1) {
+                return;
+              }
+
+              plugins.push(plugin);
+              descriptors.push({
+                plugin
+              });
+            });
+
+            cache.descriptors = descriptors;
+            cache.id = this._cacheId;
+            return descriptors;
+          }
+
+        };
+      }
+
+      getDefaultCfg() {
+        return {
+          /**
+           * the id of canvas
+           * @type {String}
+           */
+          id: null,
+          rendered: false,
+
+          /**
+           * padding
+           * @type {Array|Number}
+           */
+          padding: Global.padding,
+
+          /**
+           * data
+           * @type {Array}
+           */
+          data: null,
+
+          /**
+           * scales of chart
+           * @type {Object}
+           */
+          scales: {},
+
+          /**
+           * @private
+           * geometry instances
+           * @type {Array}
+           */
+          geoms: [],
+
+          /**
+           * scale configuration
+           * @type {Object}
+           */
+          colDefs: null,
+          pixelRatio: Global.pixelRatio,
+
+          /**
+           * filter options
+           * @type {Object}
+           */
+          filters: null,
+          appendPadding: Global.appendPadding
+        };
+      }
+
+      _syncYScales() {
+        var syncY = this.get('syncY');
+
+        if (!syncY) {
+          return;
+        }
+
+        var geoms = this.get('geoms');
+        var syncScales = [];
+        var min = [];
+        var max = [];
+        each(geoms, function (geom) {
+          var yScale = geom.getYScale();
+
+          if (yScale.isLinear) {
+            syncScales.push(yScale);
+            min.push(yScale.min);
+            max.push(yScale.max);
+          }
+        });
+        min = Math.min.apply(null, min);
+        max = Math.max.apply(null, max);
+        each(syncScales, function (scale) {
+          scale.change({
+            min
+          });
+          scale.change({
+            max
+          });
+        });
+      }
+
+      _getFieldsForLegend() {
+        var fields = [];
+        var geoms = this.get('geoms');
+        each(geoms, function (geom) {
+          var attrOptions = geom.get('attrOptions');
+          var attrCfg = attrOptions.color;
+
+          if (attrCfg && attrCfg.field && isString(attrCfg.field)) {
+            var arr = attrCfg.field.split('*');
+            each(arr, function (item) {
+              if (fields.indexOf(item) === -1) {
+                fields.push(item);
+              }
+            });
+          }
+        });
+        return fields;
+      }
+
+      _getScaleData(field) {
+        var data = this.get('data');
+        var filteredData = this.get('filteredData');
+
+        if (filteredData.length) {
+          var legendFields = this._getFieldsForLegend();
+
+          if (legendFields.indexOf(field) === -1) {
+            data = filteredData;
+          }
+        }
+
+        return data;
+      } // _updateScales() {
+      //   const scaleController = this.get('scaleController');
+      //   scaleController.updateScales();
+      //   this._adjustScale();
+      // }
+
+
+      _adjustScale() {
+        var self = this;
+        var scaleController = self.get('scaleController'); // 看起来是为了让柱状图最小或最大都默认从0开始
+
+        var geoms = this.get('geoms');
+
+        for (var i = 0; i < geoms.length; i++) {
+          var geom = geoms[i];
+
+          if (geom.get('type') === 'interval') {
+            var yScale = geom.getYScale();
+            scaleController.adjustStartZero(yScale);
+          }
+        }
+      }
+
+      _removeGeoms() {
+        var geoms = this.get('geoms');
+
+        while (geoms.length > 0) {
+          var geom = geoms.shift();
+          geom.destroy();
+        }
+      }
+
+      _clearGeoms() {
+        var geoms = this.get('geoms');
+
+        for (var i = 0, length = geoms.length; i < length; i++) {
+          var geom = geoms[i];
+          geom.clear();
+        }
+      }
+
+      _clearInner() {
+        this._clearGeoms();
+
+        Chart.plugins.notify(this, 'clearInner');
+        this.emit(EVENT_CLEAR_INNER);
+        this.get('axisController') && this.get('axisController').clear();
+      }
+
+      _initFilteredData() {
+        var filters = this.get('filters');
+        var data = this.get('data') || [];
+
+        if (filters) {
+          data = data.filter(function (obj) {
+            var rst = true;
+            each(filters, function (fn, k) {
+              if (fn) {
+                rst = fn(obj[k], obj);
+
+                if (!rst) {
+                  return false;
+                }
+              }
+            });
+            return rst;
+          });
+        }
+
+        this.set('filteredData', data);
+      }
+
+      _changeGeomsData() {
+        var geoms = this.get('geoms');
+        var data = this.get('filteredData');
+
+        for (var i = 0, length = geoms.length; i < length; i++) {
+          var geom = geoms[i];
+          geom.changeData(data);
+        }
+      }
+
+      _initGeom(geom) {
+        if (geom.get('isInit')) {
+          return;
+        }
+
+        var coord = this.get('coord');
+        var data = this.get('filteredData');
+        var colDefs = this.get('colDefs');
+        var middlePlot = this.get('middlePlot');
+        geom.set('chart', this);
+        geom.set('container', middlePlot.addGroup());
+        geom.set('data', data);
+        geom.set('coord', coord);
+        geom.set('colDefs', colDefs);
+        geom.init();
+        this.emit(EVENT_AFTER_GEOM_INIT, geom);
+      }
+
+      _initGeoms() {
+        var geoms = this.get('geoms');
+
+        for (var i = 0, length = geoms.length; i < length; i++) {
+          this._initGeom(geoms[i]);
+        }
+      }
+
+      _initCoord() {
+        var plot = this.get('plotRange');
+        var coordCfg = mix({
+          type: 'cartesian'
+        }, this.get('coordCfg'), {
+          plot
+        });
+        var type = coordCfg.type;
+        var C = Base$1[upperFirst(type)];
+        var coord = new C(coordCfg);
+        this.set('coord', coord);
+      }
+
+      _initLayout() {
+        var padding = this.get('_padding');
+
+        if (!padding) {
+          padding = this.get('margin') || this.get('padding');
+          padding = parsePadding(padding);
+        }
+
+        var top = padding[0] === 'auto' ? 0 : padding[0];
+        var right = padding[1] === 'auto' ? 0 : padding[1];
+        var bottom = padding[2] === 'auto' ? 0 : padding[2];
+        var left = padding[3] === 'auto' ? 0 : padding[3];
+        var width = this.get('width');
+        var height = this.get('height');
+        var start = {
+          x: left,
+          y: top
+        };
+        var end = {
+          x: width - right,
+          y: height - bottom
+        };
+        var plot = this.get('plot');
+
+        if (plot) {
+          plot.reset(start, end);
+          return;
+        }
+
+        var newPlot = new Plot({
+          start,
+          end
+        });
+        this.set('plotRange', newPlot);
+        this.set('plot', newPlot);
+      }
+
+      _initCanvas() {
+        var self = this;
+
+        try {
+          var canvas = new Canvas({
+            el: self.get('el') || self.get('id'),
+            context: self.get('context'),
+            pixelRatio: self.get('pixelRatio'),
+            width: self.get('width'),
+            height: self.get('height'),
+            fontFamily: Global.fontFamily
+          });
+          self.set('canvas', canvas);
+          self.set('el', canvas.get('el'));
+          self.set('width', canvas.get('width'));
+          self.set('height', canvas.get('height'));
+        } catch (error) {
+          throw error;
+        }
+
+        Chart.plugins.notify(self, 'afterCanvasInit');
+      }
+
+      _initLayers() {
+        var canvas = this.get('canvas');
+        this.set('backPlot', canvas.addGroup());
+        this.set('middlePlot', canvas.addGroup({
+          zIndex: 10
+        }));
+        this.set('frontPlot', canvas.addGroup({
+          zIndex: 20
+        }));
+      }
+
+      _initEvents() {
+        var _this = this;
+
+        // 数据更新后的一些更新
+        this.on(EVENT_AFTER_DATA_CHANGE, function () {
+          // 数据更新后,重新设置filterdata
+          _this._initFilteredData(); // 更新geoms里的数据
+
+
+          _this._changeGeomsData();
+        }); // 大小变化后的一些更新
+
+        this.on(EVENT_AFTER_SIZE_CHANGE, function () {
+          _this._initLayout(); // layout变化后,坐标轴也需要做相应的变化
+
+
+          var coord = _this.get('coord');
+
+          if (coord) {
+            coord.reset(_this.get('plot'));
+          }
+        });
+      }
+
+      _initScaleController() {
+        var scaleController = new ScaleController({
+          chart: this
+        }); // 让colDefs 和 scaleController.defs 用同一个对象,这样就不用考虑同步的问题
+
+        this.set('colDefs', scaleController.defs); // 已经实例化的scales 也保持统一个对象
+
+        this.set('scales', scaleController.scales);
+        this.set('scaleController', scaleController);
+      }
+
+      _clearScaleController() {
+        var scaleController = this.get('scaleController');
+        scaleController.clear();
+      }
+
+      _init() {
+        var self = this;
+
+        self._initCanvas();
+
+        self._initLayout();
+
+        self._initLayers();
+
+        self._initEvents();
+
+        self._initScaleController();
+
+        self.set('axisController', new AxisController({
+          frontPlot: self.get('frontPlot').addGroup({
+            className: 'axisContainer'
+          }),
+          backPlot: self.get('backPlot').addGroup({
+            className: 'axisContainer'
+          }),
+          chart: self
+        }));
+        Chart.plugins.notify(self, 'init');
+      }
+
+      constructor(cfg) {
+        super(cfg);
+        var self = this;
+        each(Geom, function (geomConstructor, className) {
+          var methodName = lowerFirst(className);
+
+          self[methodName] = function (cfg) {
+            var geom = new geomConstructor(cfg);
+            self.addGeom(geom);
+            return geom;
+          };
+        });
+
+        self._init();
+      }
+
+      init() {
+        // 初始filterData
+        this._initFilteredData(); // initialization coordinate instance
+
+
+        this._initCoord();
+
+        Chart.plugins.notify(this, 'beforeGeomInit'); // init all geometry instances
+
+        this._initGeoms(); // 多 Y 轴的情况时,统一 Y 轴的数值范围。
+
+
+        this._syncYScales(); // do some adjust for data
+
+
+        this._adjustScale();
+
+        this.emit(EVENT_AFTER_INIT);
+      }
+      /**
+       * set data and some scale configuration
+       * @chainable
+       * @param  {Array} data the dataset to visualize
+       * @param  {Object} colDefs the configuration for scales
+       * @return {Chart} return the chart instance
+       */
+
+
+      source(data, colDefs) {
+        this.set('data', data);
+
+        if (colDefs) {
+          this.scale(colDefs);
+        }
+
+        return this;
+      }
+
+      scale(field, cfg) {
+        var scaleController = this.get('scaleController');
+        scaleController.setFieldDef(field, cfg);
+        return this;
+      }
+      /**
+       * configure the axis
+       * @chainable
+       * @param  {String|Boolean} field the field name of data
+       * @param  {Object} cfg configuration for axis
+       * @return {Chart} return the chart instance
+       */
+
+
+      axis(field, cfg) {
+        var axisController = this.get('axisController');
+
+        if (!field) {
+          axisController.axisCfg = null;
+        } else {
+          axisController.axisCfg = axisController.axisCfg || {};
+          axisController.axisCfg[field] = cfg;
+        }
+
+        return this;
+      }
+      /**
+       * configure the coordinate
+       * @chainable
+       * @param  {String} type set the type of coodinate
+       * @param  {Object} cfg configuration for coordinate
+       * @return {Chart} return the chart instance
+       */
+
+
+      coord(type, cfg) {
+        var coordCfg;
+
+        if (isObject(type)) {
+          coordCfg = type;
+        } else {
+          coordCfg = cfg || {};
+          coordCfg.type = type || 'cartesian';
+        }
+
+        this.set('coordCfg', coordCfg);
+        return this;
+      }
+
+      filter(field, condition) {
+        var filters = this.get('filters') || {};
+        filters[field] = condition;
+        this.set('filters', filters); // 如果已经render过,则再重新触发一次change
+
+        if (this.get('rendered')) {
+          this.emit(EVENT_AFTER_DATA_CHANGE, this.get('data'));
+        }
+      }
+      /**
+       * render the chart
+       * @chainable
+       * @return {Chart} return the chart instance
+       */
+
+
+      render() {
+        var rendered = this.get('rendered');
+        var canvas = this.get('canvas');
+        var geoms = this.get('geoms'); // 已经渲染过
+
+        if (rendered) {
+          this._initGeoms();
+
+          this._adjustScale();
+        } else {
+          this.init();
+          this.set('rendered', true);
+        }
+
+        this.emit(EVENT_BEFORE_RENDER);
+        Chart.plugins.notify(this, 'beforeGeomDraw');
+
+        this._renderAxis();
+
+        var middlePlot = this.get('middlePlot');
+
+        if (this.get('limitInPlot') && !middlePlot.attr('clip')) {
+          var coord = this.get('coord');
+          var clip = getClip(coord);
+          clip.set('canvas', middlePlot.get('canvas'));
+          middlePlot.attr('clip', clip);
+        }
+
+        this.emit(EVENT_BEFORE_GEOM_DRAW);
+
+        for (var i = 0, length = geoms.length; i < length; i++) {
+          var geom = geoms[i];
+          geom.paint();
+        }
+
+        this.emit(EVENT_AFTER_GEOM_DRAW);
+        Chart.plugins.notify(this, 'afterGeomDraw');
+        canvas.sort();
+        this.get('frontPlot').sort();
+        Chart.plugins.notify(this, 'beforeCanvasDraw');
+        canvas.draw();
+        this.emit(EVENT_AFTER_RENDER);
+        return this;
+      }
+      /**
+       * clear the chart, include geometris and all the shapes
+       * @chainable
+       * @return {Chart} return the chart
+       */
+
+
+      clear() {
+        Chart.plugins.notify(this, 'clear');
+        this.emit(EVENT_CLEAR);
+
+        this._clearInner();
+
+        this._removeGeoms();
+
+        this._clearScaleController();
+
+        this.set('legendItems', null);
+        this.set('filters', null);
+        this.set('isUpdate', false);
+        this.set('_padding', null);
+        this.set('rendered', false);
+        var canvas = this.get('canvas');
+        canvas.draw();
+        return this;
+      }
+
+      repaint() {
+        // 如果在没有render之前就repaint的,就直接return退出
+        var rendered = this.get('rendered');
+
+        if (!rendered) {
+          return;
+        }
+
+        this.set('isUpdate', true);
+        this.set('legendItems', null);
+        Chart.plugins.notify(this, 'repaint');
+
+        this._clearInner();
+
+        this.emit(EVENT_REPAINT);
+        this.render();
+      }
+
+      changeData(data) {
+        this.emit(EVENT_BEFORE_DATA_CHANGE, data);
+        this.set('data', data);
+        Chart.plugins.notify(this, 'changeData');
+        this.emit(EVENT_AFTER_DATA_CHANGE, data);
+        this.set('_padding', null);
+        this.repaint();
+      }
+
+      changeSize(width, height) {
+        if (width) {
+          this.set('width', width);
+        } else {
+          width = this.get('width');
+        }
+
+        if (height) {
+          this.set('height', height);
+        } else {
+          height = this.get('height');
+        }
+
+        var canvas = this.get('canvas');
+        canvas.changeSize(width, height);
+        this.emit(EVENT_AFTER_SIZE_CHANGE, {
+          width,
+          height
+        });
+        this.repaint();
+        return this;
+      }
+
+      destroy() {
+        this.clear();
+        var canvas = this.get('canvas');
+        canvas.destroy();
+        Chart.plugins.notify(this, 'afterCanvasDestroyed');
+
+        if (this._interactions) {
+          each(this._interactions, function (interaction) {
+            interaction.destroy();
+          });
+        }
+
+        super.destroy();
+      }
+      /**
+       * calculate dataset's position on canvas
+       * @param  {Object} record the dataset
+       * @return {Object} return the position
+       */
+
+
+      getPosition(record) {
+        var self = this;
+        var coord = self.get('coord');
+        var xScale = self.getXScale();
+        var xField = xScale.field;
+        var yScales = self.getYScales(); // default first
+
+        var yScale = yScales[0];
+        var yField = yScale.field;
+
+        for (var i = 0, len = yScales.length; i < len; i++) {
+          var scale = yScales[i];
+          var field = scale.field;
+
+          if (record[field]) {
+            yScale = scale;
+            yField = field;
+            break;
+          }
+        }
+
+        var x = xScale.scale(record[xField]);
+        var y = yScale.scale(record[yField]);
+        return coord.convertPoint({
+          x,
+          y
+        });
+      }
+      /**
+       * get the data item of the point
+       * @param  {Object} point canvas position
+       * @return {Object} return the data item
+       */
+
+
+      getRecord(point) {
+        var self = this;
+        var coord = self.get('coord');
+        var xScale = self.getXScale();
+        var yScale = self.getYScales()[0];
+        var invertPoint = coord.invertPoint(point);
+        var record = {};
+        record[xScale.field] = xScale.invert(invertPoint.x);
+        record[yScale.field] = yScale.invert(invertPoint.y);
+        return record;
+      }
+      /**
+       * get the dataset of the point
+       * @param  {Object} point canvas position
+       * @return {Array} return the dataset
+      **/
+
+
+      getSnapRecords(point) {
+        var geom = this.get('geoms')[0];
+        var data = [];
+
+        if (geom) {
+          // need to judge
+          data = geom.getSnapRecords(point);
+        }
+
+        return data;
+      }
+      /**
+       * creat scale instances
+       * @param  {String} field field name of data
+       * @return {Scale} return the scale
+       */
+
+
+      createScale(field) {
+        var data = this._getScaleData(field);
+
+        var scaleController = this.get('scaleController');
+        return scaleController.createScale(field, data);
+      }
+      /**
+       * @protected
+       * add geometry instance to geoms
+       * @param {Geom} geom geometry instance
+       */
+
+
+      addGeom(geom) {
+        var geoms = this.get('geoms');
+        geoms.push(geom);
+      }
+      /**
+       * get the scale of x axis
+       * @return {Scale} return the scale
+       */
+
+
+      getXScale() {
+        var self = this;
+        var geoms = self.get('geoms');
+        var xScale = geoms[0].getXScale();
+        return xScale;
+      }
+      /**
+       * get the scale of y axis
+       * @return {Array} return the scale
+       */
+
+
+      getYScales() {
+        var geoms = this.get('geoms');
+        var rst = [];
+        each(geoms, function (geom) {
+          var yScale = geom.getYScale();
+
+          if (rst.indexOf(yScale) === -1) {
+            rst.push(yScale);
+          }
+        });
+        return rst;
+      }
+
+      getLegendItems() {
+        if (this.get('legendItems')) {
+          return this.get('legendItems');
+        }
+
+        var legendItems = {};
+        var scales = [];
+        var geoms = this.get('geoms');
+        each(geoms, function (geom) {
+          var colorAttr = geom.getAttr('color');
+
+          if (colorAttr) {
+            var scale = colorAttr.getScale('color'); // 只支持分类图例
+
+            if (scale.isCategory && !_isScaleExist(scales, scale)) {
+              scales.push(scale);
+              var field = scale.field;
+              var ticks = scale.getTicks();
+              var items = [];
+              each(ticks, function (tick) {
+                var text = tick.text;
+                var name = text;
+                var scaleValue = tick.value;
+                var value = scale.invert(scaleValue);
+                var color = colorAttr.mapping(value).join('') || Global.defaultColor;
+                var marker = {
+                  fill: color,
+                  radius: 3,
+                  symbol: 'circle',
+                  stroke: '#fff'
+                };
+                items.push({
+                  name,
+                  // for display
+                  dataValue: value,
+                  // the origin value
+                  checked: true,
+                  marker
+                });
+              });
+              legendItems[field] = items;
+            }
+          }
+        });
+        this.set('legendItems', legendItems);
+        return legendItems;
+      } // register the plugins
+
+
+      registerPlugins(plugins) {
+        var self = this;
+        var chartPlugins = self.get('plugins') || [];
+
+        if (!isArray(chartPlugins)) {
+          chartPlugins = [chartPlugins];
+        }
+
+        [].concat(plugins).forEach(function (plugin) {
+          if (chartPlugins.indexOf(plugin) === -1) {
+            plugin.init && plugin.init(self); // init
+
+            chartPlugins.push(plugin);
+          }
+        });
+        Chart.plugins._cacheId++;
+        self.set('plugins', chartPlugins);
+      }
+
+      _renderAxis() {
+        var axisController = this.get('axisController');
+        var xScale = this.getXScale();
+        var yScales = this.getYScales();
+        var coord = this.get('coord');
+        Chart.plugins.notify(this, 'beforeRenderAxis');
+        axisController.createAxis(coord, xScale, yScales);
+      }
+
+      _isAutoPadding() {
+        if (this.get('_padding')) {
+          return false;
+        }
+
+        var padding = this.get('padding');
+
+        if (isArray(padding)) {
+          return padding.indexOf('auto') !== -1;
+        }
+
+        return padding === 'auto';
+      }
+
+      _updateLayout(padding) {
+        var width = this.get('width');
+        var height = this.get('height');
+        var start = {
+          x: padding[3],
+          y: padding[0]
+        };
+        var end = {
+          x: width - padding[1],
+          y: height - padding[2]
+        };
+        var plot = this.get('plot');
+        var coord = this.get('coord');
+        plot.reset(start, end);
+        coord.reset(plot);
+      }
+
+    }
+
+    Chart.plugins = Chart.initPlugins();
+
+    var track = function track() {
+      return null;
+    };
+
+    /**
+     * @fileOverview shape util
+     * @author dxq613@gmail.com
+     */
+
+    function splitPoints(obj) {
+      var points = [];
+      var x = obj.x;
+      var y = obj.y;
+      y = isArray(y) ? y : [y];
+      y.forEach(function (yItem, index) {
+        var point = {
+          x: isArray(x) ? x[index] : x,
+          y: yItem
+        };
+        points.push(point);
+      });
+      return points;
+    }
+
+    function splitArray(data, yField, connectNulls) {
+      if (!data.length) return [];
+      var arr = [];
+      var tmp = [];
+      var yValue;
+      each(data, function (obj) {
+        yValue = obj._origin ? obj._origin[yField] : obj[yField];
+
+        if (connectNulls) {
+          if (!isNil(yValue)) {
+            tmp.push(obj);
+          }
+        } else {
+          if (isArray(yValue) && isNil(yValue[0]) || isNil(yValue)) {
+            if (tmp.length) {
+              arr.push(tmp);
+              tmp = [];
+            }
+          } else {
+            tmp.push(obj);
+          }
+        }
+      });
+
+      if (tmp.length) {
+        arr.push(tmp);
+      }
+
+      return arr;
+    }
+
+    var SHAPES = ['circle', 'hollowCircle', 'rect'];
+    var Point = Shape$1.registerFactory('point', {
+      defaultShapeType: 'circle',
+
+      getDefaultPoints(pointInfo) {
+        return splitPoints(pointInfo);
+      }
+
+    });
+
+    function getPointsCfg(cfg) {
+      var style = {
+        lineWidth: 0,
+        stroke: cfg.color,
+        fill: cfg.color
+      };
+
+      if (cfg.size) {
+        style.size = cfg.size;
+      }
+
+      mix(style, cfg.style);
+      return mix({}, Global.shape.point, style);
+    }
+
+    function drawShape(cfg, container, shape) {
+      if (cfg.size === 0) return;
+      var pointCfg = getPointsCfg(cfg);
+      var size = pointCfg.r || pointCfg.size;
+      var x = cfg.x;
+      var y = !isArray(cfg.y) ? [cfg.y] : cfg.y;
+
+      if (shape === 'hollowCircle') {
+        pointCfg.lineWidth = 1;
+        pointCfg.fill = null;
+      }
+
+      for (var i = 0, len = y.length; i < len; i++) {
+        if (shape === 'rect') {
+          return container.addShape('Rect', {
+            className: 'point',
+            attrs: mix({
+              x: x - size,
+              y: y[i] - size,
+              width: size * 2,
+              height: size * 2
+            }, pointCfg)
+          });
+        }
+
+        return container.addShape('Circle', {
+          className: 'point',
+          attrs: mix({
+            x,
+            y: y[i],
+            r: size
+          }, pointCfg)
+        });
+      }
+    }
+
+    each(SHAPES, function (shapeType) {
+      Shape$1.registerShape('point', shapeType, {
+        draw(cfg, container) {
+          return drawShape(cfg, container, shapeType);
+        }
+
+      });
+    });
+
+    class Point$1 extends Geom {
+      getDefaultCfg() {
+        var cfg = super.getDefaultCfg();
+        cfg.type = 'point';
+        cfg.shapeType = 'point';
+        cfg.generatePoints = false;
+        return cfg;
+      }
+
+      draw(data, shapeFactory) {
+        var self = this;
+        var container = self.get('container');
+        each(data, function (obj) {
+          var shape = obj.shape;
+          var cfg = self.getDrawCfg(obj);
+
+          if (isArray(obj.y)) {
+            var hasStack = self.hasAdjust('stack');
+            each(obj.y, function (y, idx) {
+              cfg.y = y;
+
+              if (!hasStack || idx !== 0) {
+                self.drawShape(shape, obj, cfg, container, shapeFactory);
+              }
+            });
+          } else if (!isNil(obj.y)) {
+            self.drawShape(shape, obj, cfg, container, shapeFactory);
+          }
+        });
+      }
+
+    }
+
+    Geom.Point = Point$1;
+
+    var Line$2 = Shape$1.registerFactory('line', {
+      defaultShapeType: 'line'
+    });
+
+    function getStyle$1(cfg) {
+      var style = {
+        strokeStyle: cfg.color
+      };
+
+      if (cfg.size >= 0) {
+        style.lineWidth = cfg.size;
+      }
+
+      mix(style, cfg.style);
+      return mix({}, Global.shape.line, style);
+    }
+
+    function drawLines(cfg, container, style, smooth) {
+      var points = cfg.points;
+
+      if (points.length && isArray(points[0].y)) {
+        var topPoints = [];
+        var bottomPoints = [];
+
+        for (var i = 0, len = points.length; i < len; i++) {
+          var point = points[i];
+          var tmp = splitPoints(point);
+          bottomPoints.push(tmp[0]);
+          topPoints.push(tmp[1]);
+        }
+
+        if (cfg.isInCircle) {
+          topPoints.push(topPoints[0]);
+          bottomPoints.push(bottomPoints[0]);
+        }
+
+        if (cfg.isStack) {
+          return container.addShape('Polyline', {
+            className: 'line',
+            attrs: mix({
+              points: topPoints,
+              smooth
+            }, style)
+          });
+        }
+
+        var topShape = container.addShape('Polyline', {
+          className: 'line',
+          attrs: mix({
+            points: topPoints,
+            smooth
+          }, style)
+        });
+        var bottomShape = container.addShape('Polyline', {
+          className: 'line',
+          attrs: mix({
+            points: bottomPoints,
+            smooth
+          }, style)
+        });
+        return [topShape, bottomShape];
+      }
+
+      if (cfg.isInCircle) {
+        points.push(points[0]);
+      }
+
+      return container.addShape('Polyline', {
+        className: 'line',
+        attrs: mix({
+          points,
+          smooth
+        }, style)
+      });
+    }
+
+    var SHAPES$1 = ['line', 'smooth', 'dash'];
+    each(SHAPES$1, function (shapeType) {
+      Shape$1.registerShape('line', shapeType, {
+        draw(cfg, container) {
+          var smooth = shapeType === 'smooth';
+          var style = getStyle$1(cfg);
+
+          if (shapeType === 'dash') {
+            style.lineDash = Global.lineDash;
+          }
+
+          return drawLines(cfg, container, style, smooth);
+        }
+
+      });
+    });
+
+    class Path extends Geom {
+      getDefaultCfg() {
+        var cfg = super.getDefaultCfg();
+        cfg.type = 'path';
+        cfg.shapeType = 'line';
+        return cfg;
+      }
+
+      getDrawCfg(obj) {
+        var cfg = super.getDrawCfg(obj);
+        cfg.isStack = this.hasAdjust('stack');
+        return cfg;
+      }
+
+      draw(data, shapeFactory) {
+        var self = this;
+        var container = self.get('container');
+        var yScale = self.getYScale();
+        var connectNulls = self.get('connectNulls');
+        var splitArrayObj = splitArray(data, yScale.field, connectNulls);
+        var cfg = this.getDrawCfg(data[0]);
+        cfg.origin = data;
+        each(splitArrayObj, function (subData, splitedIndex) {
+          cfg.splitedIndex = splitedIndex;
+          cfg.points = subData;
+          self.drawShape(cfg.shape, data[0], cfg, container, shapeFactory);
+        });
+      }
+
+    }
+
+    Geom.Path = Path;
+
+    class Line$3 extends Path {
+      getDefaultCfg() {
+        var cfg = super.getDefaultCfg();
+        cfg.type = 'line';
+        cfg.sortable = true;
+        return cfg;
+      }
+
+    }
+
+    Geom.Line = Line$3;
+
+    function equals(v1, v2) {
+      return Math.abs(v1 - v2) < 0.00001;
+    }
+
+    function notEmpty(value) {
+      return !isNaN(value) && !isNil(value);
+    }
+
+    function filterPoints(points) {
+      var filteredPoints = []; // filter the point which x or y is NaN
+
+      for (var i = 0, len = points.length; i < len; i++) {
+        var point = points[i];
+
+        if (notEmpty(point.x) && notEmpty(point.y)) {
+          filteredPoints.push(point);
+        }
+      }
+
+      return filteredPoints;
+    }
+
+    function equalsCenter(points, center) {
+      var eqls = true;
+      each(points, function (point) {
+        if (!equals(point.x, center.x) || !equals(point.y, center.y)) {
+          eqls = false;
+          return false;
+        }
+      });
+      return eqls;
+    }
+
+    function drawRectShape(topPoints, bottomPoints, container, style, isSmooth) {
+      var shape;
+      var points = topPoints.concat(bottomPoints);
+
+      if (isSmooth) {
+        shape = container.addShape('Custom', {
+          className: 'area',
+          attrs: mix({
+            points
+          }, style),
+
+          createPath(context) {
+            var constaint = [[0, 0], [1, 1]];
+            var points = filterPoints(this._attrs.attrs.points);
+            var pointsLen = points.length;
+            var topPoints = points.slice(0, pointsLen / 2);
+            var bottomPoints = points.slice(pointsLen / 2, pointsLen);
+            var topSps = catmullRom2bezier(topPoints, false, constaint);
+            context.beginPath();
+            context.moveTo(topPoints[0].x, topPoints[0].y);
+
+            for (var i = 0, n = topSps.length; i < n; i++) {
+              var sp = topSps[i];
+              context.bezierCurveTo(sp[1], sp[2], sp[3], sp[4], sp[5], sp[6]);
+            }
+
+            if (bottomPoints.length) {
+              var bottomSps = catmullRom2bezier(bottomPoints, false, constaint);
+              context.lineTo(bottomPoints[0].x, bottomPoints[0].y);
+
+              for (var _i = 0, _n = bottomSps.length; _i < _n; _i++) {
+                var _sp = bottomSps[_i];
+                context.bezierCurveTo(_sp[1], _sp[2], _sp[3], _sp[4], _sp[5], _sp[6]);
+              }
+            }
+
+            context.closePath();
+          },
+
+          calculateBox() {
+            var points = filterPoints(this._attrs.attrs.points);
+            return getBBoxFromPoints(points);
+          }
+
+        });
+      } else {
+        shape = container.addShape('Polyline', {
+          className: 'area',
+          attrs: mix({
+            points
+          }, style)
+        });
+      }
+
+      return shape;
+    }
+
+    function drawShape$1(cfg, container, isSmooth) {
+      var self = this;
+      var points = cfg.points;
+      var topPoints = [];
+      var bottomPoints = [];
+      each(points, function (point) {
+        bottomPoints.push(point[0]);
+        topPoints.push(point[1]);
+      });
+      var style = mix({
+        fillStyle: cfg.color
+      }, Global.shape.area, cfg.style);
+      bottomPoints.reverse();
+      topPoints = self.parsePoints(topPoints);
+      bottomPoints = self.parsePoints(bottomPoints);
+
+      if (cfg.isInCircle) {
+        topPoints.push(topPoints[0]);
+        bottomPoints.unshift(bottomPoints[bottomPoints.length - 1]);
+
+        if (equalsCenter(bottomPoints, cfg.center)) {
+          bottomPoints = [];
+        }
+      }
+
+      return drawRectShape(topPoints, bottomPoints, container, style, isSmooth);
+    }
+
+    var Area = Shape$1.registerFactory('area', {
+      defaultShapeType: 'area',
+
+      getDefaultPoints(obj) {
+        var x = obj.x;
+        var y = obj.y;
+        var y0 = obj.y0;
+        y = isArray(y) ? y : [y0, y];
+        var points = [];
+        points.push({
+          x,
+          y: y[0]
+        }, {
+          x,
+          y: y[1]
+        });
+        return points;
+      }
+
+    });
+    var SHAPES$2 = ['area', 'smooth'];
+    each(SHAPES$2, function (shapeType) {
+      Shape$1.registerShape('area', shapeType, {
+        draw(cfg, container) {
+          var smooth = shapeType === 'smooth';
+          return drawShape$1.call(this, cfg, container, smooth);
+        }
+
+      });
+    });
+
+    /**
+     * @fileOverview area geometry
+     * @author dxq613 @gmail.com
+     * @author sima.zhang1990@gmail.com
+     */
+
+    class Area$1 extends Geom {
+      /**
+       * get the default configuration
+       * @protected
+       * @return {Object} return the result
+       */
+      getDefaultCfg() {
+        var cfg = super.getDefaultCfg();
+        cfg.type = 'area';
+        cfg.shapeType = 'area';
+        cfg.generatePoints = true;
+        cfg.sortable = true;
+        return cfg;
+      }
+
+      draw(data, shapeFactory) {
+        var self = this;
+        var container = self.get('container');
+        var cfg = this.getDrawCfg(data[0]);
+        var yScale = self.getYScale();
+        var connectNulls = self.get('connectNulls');
+        var splitArrayfn = splitArray(data, yScale.field, connectNulls);
+        cfg.origin = data;
+        each(splitArrayfn, function (subData, splitedIndex) {
+          cfg.splitedIndex = splitedIndex;
+          var points = subData.map(function (obj) {
+            return obj.points;
+          });
+          cfg.points = points;
+          self.drawShape(cfg.shape, data[0], cfg, container, shapeFactory);
+        });
+      }
+
+    }
+
+    Geom.Area = Area$1;
+
+    /**
+     * @fileOverview Utility for calculate the with ratui in x axis
+     * @author sima.zhang1990@gmail.com
+     * @author dxq613@gmail.com
+     */
+    var SizeMixin = {
+      initEvent() {
+        var _this = this;
+
+        var chart = this.get('chart');
+
+        if (!chart) {
+          return;
+        }
+
+        chart.on(EVENT_AFTER_SIZE_CHANGE, function () {
+          _this.set('_width', null);
+        });
+      },
+
+      getDefaultSize() {
+        var defaultSize = this.get('defaultSize');
+
+        if (!defaultSize) {
+          var coord = this.get('coord');
+          var xScale = this.getXScale();
+          var dataArray = this.get('dataArray');
+          var values = uniq(xScale.values);
+          var count = values.length;
+          var range = xScale.range;
+          var normalizeSize = 1 / count;
+          var widthRatio = 1;
+
+          if (coord && coord.isPolar) {
+            if (coord.transposed && count > 1) {
+              widthRatio = Global.widthRatio.multiplePie;
+            } else {
+              widthRatio = Global.widthRatio.rose;
+            }
+          } else {
+            if (xScale.isLinear) {
+              normalizeSize *= range[1] - range[0];
+            }
+
+            widthRatio = Global.widthRatio.column;
+          }
+
+          normalizeSize *= widthRatio;
+
+          if (this.hasAdjust('dodge')) {
+            normalizeSize = normalizeSize / dataArray.length;
+          }
+
+          defaultSize = normalizeSize;
+          this.set('defaultSize', defaultSize);
+        }
+
+        return defaultSize;
+      },
+
+      getDimWidth(dimName) {
+        var coord = this.get('coord');
+        var start = coord.convertPoint({
+          x: 0,
+          y: 0
+        });
+        var end = coord.convertPoint({
+          x: dimName === 'x' ? 1 : 0,
+          y: dimName === 'x' ? 0 : 1
+        });
+        var width = 0;
+
+        if (start && end) {
+          width = Math.sqrt(Math.pow(end.x - start.x, 2) + Math.pow(end.y - start.y, 2));
+        }
+
+        return width;
+      },
+
+      _getWidth() {
+        var width = this.get('_width');
+
+        if (!width) {
+          var coord = this.get('coord');
+
+          if (coord && coord.isPolar && !coord.transposed) {
+            width = (coord.endAngle - coord.startAngle) * coord.circleRadius;
+          } else {
+            width = this.getDimWidth('x');
+          }
+
+          this.set('_width', width);
+        }
+
+        return width;
+      },
+
+      _toNormalizedSize(size) {
+        var width = this._getWidth();
+
+        return size / width;
+      },
+
+      _toCoordSize(normalizeSize) {
+        var width = this._getWidth();
+
+        return width * normalizeSize;
+      },
+
+      getNormalizedSize(obj) {
+        var size = this.getAttrValue('size', obj);
+
+        if (isNil(size)) {
+          size = this.getDefaultSize();
+        } else {
+          size = this._toNormalizedSize(size);
+        }
+
+        return size;
+      },
+
+      getSize(obj) {
+        var size = this.getAttrValue('size', obj);
+
+        if (isNil(size)) {
+          var normalizeSize = this.getDefaultSize();
+          size = this._toCoordSize(normalizeSize);
+        }
+
+        return size;
+      }
+
+    };
+
+    function getRectPoints(cfg) {
+      var {
+        x,
+        y,
+        y0,
+        size
+      } = cfg;
+      var ymin = y0;
+      var ymax = y;
+
+      if (isArray(y)) {
+        ymax = y[1];
+        ymin = y[0];
+      }
+
+      var xmin;
+      var xmax;
+
+      if (isArray(x)) {
+        xmin = x[0];
+        xmax = x[1];
+      } else {
+        xmin = x - size / 2;
+        xmax = x + size / 2;
+      }
+
+      return [{
+        x: xmin,
+        y: ymin
+      }, {
+        x: xmin,
+        y: ymax
+      }, {
+        x: xmax,
+        y: ymax
+      }, {
+        x: xmax,
+        y: ymin
+      }];
+    }
+
+    function getRectRange(points) {
+      var xValues = [];
+      var yValues = [];
+
+      for (var i = 0, len = points.length; i < len; i++) {
+        var point = points[i];
+        xValues.push(point.x);
+        yValues.push(point.y);
+      }
+
+      var xMin = Math.min.apply(null, xValues);
+      var yMin = Math.min.apply(null, yValues);
+      var xMax = Math.max.apply(null, xValues);
+      var yMax = Math.max.apply(null, yValues);
+      return {
+        x: xMin,
+        y: yMin,
+        width: xMax - xMin,
+        height: yMax - yMin
+      };
+    }
+
+    function getMiddlePoint(a, b) {
+      var x = (a.x - b.x) / 2 + b.x;
+      var y = (a.y - b.y) / 2 + b.y;
+      return {
+        x,
+        y
+      };
+    }
+
+    var Interval = Shape$1.registerFactory('interval', {
+      defaultShapeType: 'rect',
+
+      getDefaultPoints(cfg) {
+        return getRectPoints(cfg);
+      }
+
+    });
+    Shape$1.registerShape('interval', 'rect', {
+      draw(cfg, container) {
+        var points = this.parsePoints(cfg.points);
+        var style = mix({
+          fill: cfg.color
+        }, Global.shape.interval, cfg.style);
+
+        if (cfg.isInCircle) {
+          var newPoints = points.slice(0);
+
+          if (this._coord.transposed) {
+            newPoints = [points[0], points[3], points[2], points[1]];
+          }
+
+          var {
+            x,
+            y
+          } = cfg.center;
+          var v = [1, 0];
+          var v0 = [newPoints[0].x - x, newPoints[0].y - y];
+          var v1 = [newPoints[1].x - x, newPoints[1].y - y];
+          var v2 = [newPoints[2].x - x, newPoints[2].y - y];
+          var startAngle = Vector2.angleTo(v, v1);
+          var endAngle = Vector2.angleTo(v, v2);
+          var r0 = Vector2.length(v0);
+          var r = Vector2.length(v1);
+
+          if (startAngle >= 1.5 * Math.PI) {
+            startAngle = startAngle - 2 * Math.PI;
+          }
+
+          if (endAngle >= 1.5 * Math.PI) {
+            endAngle = endAngle - 2 * Math.PI;
+          }
+
+          return container.addShape('Sector', {
+            className: 'interval',
+            attrs: mix({
+              x,
+              y,
+              r,
+              r0,
+              startAngle,
+              endAngle
+            }, style)
+          });
+        }
+
+        var rectCfg = getRectRange(points);
+        return container.addShape('rect', {
+          className: 'interval',
+          attrs: mix(rectCfg, style)
+        });
+      }
+
+    }); // 金字塔 和 漏斗图
+
+    ['pyramid', 'funnel'].forEach(function (shapeType) {
+      Shape$1.registerShape('interval', shapeType, {
+        getPoints(cfg) {
+          cfg.size = cfg.size * 2; // 漏斗图的 size 是柱状图的两倍
+
+          return getRectPoints(cfg);
+        },
+
+        draw(cfg, container) {
+          var points = this.parsePoints(cfg.points);
+          var nextPoints = this.parsePoints(cfg.nextPoints);
+          var polygonPoints = null;
+
+          if (nextPoints) {
+            polygonPoints = [points[0], points[1], nextPoints[1], nextPoints[0]];
+          } else {
+            polygonPoints = [points[0], points[1]]; // pyramid 顶部是三角形,所以取中心点就好了,funnel顶部是长方形
+
+            if (shapeType === 'pyramid') {
+              polygonPoints.push(getMiddlePoint(points[2], points[3]));
+            } else {
+              polygonPoints.push(points[2], points[3]);
+            }
+          }
+
+          var attrs = mix({
+            fill: cfg.color,
+            points: polygonPoints
+          }, Global.shape.interval, cfg.style);
+          return container.addShape('polygon', {
+            className: 'interval',
+            attrs
+          });
+        }
+
+      });
+    });
+
+    class Interval$1 extends Geom {
+      getDefaultCfg() {
+        var cfg = super.getDefaultCfg();
+        cfg.type = 'interval';
+        cfg.shapeType = 'interval';
+        cfg.generatePoints = true;
+        return cfg;
+      }
+
+      constructor(cfg) {
+        super(cfg);
+        mix(this, SizeMixin);
+      }
+
+      init() {
+        super.init(); // 绑定事件
+
+        this.initEvent();
+      }
+
+      createShapePointsCfg(obj) {
+        var cfg = super.createShapePointsCfg(obj);
+        cfg.size = this.getNormalizedSize(obj);
+        return cfg;
+      }
+
+      clearInner() {
+        super.clearInner();
+        this.set('defaultSize', null);
+      }
+
+    }
+
+    Geom.Interval = Interval$1;
+
+    var Polygon$1 = Shape$1.registerFactory('polygon', {
+      defaultShapeType: 'polygon',
+
+      getDefaultPoints(pointInfo) {
+        var points = [];
+        var {
+          x,
+          y
+        } = pointInfo;
+
+        for (var i = 0, len = x.length; i < len; i++) {
+          points.push({
+            x: x[i],
+            y: y[i]
+          });
+        }
+
+        return points;
+      }
+
+    });
+    Shape$1.registerShape('polygon', 'polygon', {
+      draw(cfg, container) {
+        var points = this.parsePoints(cfg.points);
+        var style = mix({
+          fill: cfg.color,
+          points
+        }, cfg.style);
+        return container.addShape('Polygon', {
+          className: 'polygon',
+          attrs: style
+        });
+      }
+
+    });
+
+    class Polygon$2 extends Geom {
+      getDefaultCfg() {
+        var cfg = super.getDefaultCfg();
+        cfg.type = 'polygon';
+        cfg.shapeType = 'polygon';
+        cfg.generatePoints = true;
+        return cfg;
+      }
+
+      createShapePointsCfg(obj) {
+        var cfg = super.createShapePointsCfg(obj);
+        var self = this;
+        var x = cfg.x;
+        var y = cfg.y;
+        var temp;
+
+        if (!(isArray(x) && isArray(y))) {
+          var xScale = self.getXScale();
+          var yScale = self.getYScale();
+          var xCount = xScale.values ? xScale.values.length : xScale.ticks.length;
+          var yCount = yScale.values ? yScale.values.length : yScale.ticks.length;
+          var xOffset = 0.5 * 1 / xCount;
+          var yOffset = 0.5 * 1 / yCount;
+
+          if (xScale.isCategory && yScale.isCategory) {
+            x = [x - xOffset, x - xOffset, x + xOffset, x + xOffset];
+            y = [y - yOffset, y + yOffset, y + yOffset, y - yOffset];
+          } else if (isArray(x)) {
+            temp = x;
+            x = [temp[0], temp[0], temp[1], temp[1]];
+            y = [y - yOffset / 2, y + yOffset / 2, y + yOffset / 2, y - yOffset / 2];
+          } else if (isArray(y)) {
+            temp = y;
+            y = [temp[0], temp[1], temp[1], temp[0]];
+            x = [x - xOffset / 2, x - xOffset / 2, x + xOffset / 2, x + xOffset / 2];
+          }
+
+          cfg.x = x;
+          cfg.y = y;
+        }
+
+        return cfg;
+      }
+
+    }
+
+    Geom.Polygon = Polygon$2;
+
+    function _sortValue(value) {
+      var sorted = value.sort(function (a, b) {
+        return a < b ? 1 : -1;
+      });
+      var length = sorted.length;
+
+      if (length < 4) {
+        var min = sorted[length - 1];
+
+        for (var i = 0; i < 4 - length; i++) {
+          sorted.push(min);
+        }
+      }
+
+      return sorted;
+    } // from left bottom corner, and clockwise
+
+
+    function getCandlePoints(x, y, width) {
+      var yValues = _sortValue(y);
+
+      var points = [{
+        x,
+        y: yValues[0]
+      }, {
+        x,
+        y: yValues[1]
+      }, {
+        x: x - width / 2,
+        y: yValues[2]
+      }, {
+        x: x - width / 2,
+        y: yValues[1]
+      }, {
+        x: x + width / 2,
+        y: yValues[1]
+      }, {
+        x: x + width / 2,
+        y: yValues[2]
+      }, {
+        x,
+        y: yValues[2]
+      }, {
+        x,
+        y: yValues[3]
+      }];
+      return points;
+    }
+
+    var Schema = Shape$1.registerFactory('schema', {});
+    Shape$1.registerShape('schema', 'candle', {
+      getPoints(cfg) {
+        return getCandlePoints(cfg.x, cfg.y, cfg.size);
+      },
+
+      draw(cfg, container) {
+        var points = this.parsePoints(cfg.points);
+        var style = mix({
+          stroke: cfg.color,
+          fill: cfg.color,
+          lineWidth: 1
+        }, cfg.style);
+        return container.addShape('Custom', {
+          className: 'schema',
+          attrs: style,
+
+          createPath(ctx) {
+            ctx.beginPath();
+            ctx.moveTo(points[0].x, points[0].y);
+            ctx.lineTo(points[1].x, points[1].y);
+            ctx.moveTo(points[2].x, points[2].y);
+
+            for (var i = 3; i < 6; i++) {
+              ctx.lineTo(points[i].x, points[i].y);
+            }
+
+            ctx.closePath();
+            ctx.moveTo(points[6].x, points[6].y);
+            ctx.lineTo(points[7].x, points[7].y);
+          }
+
+        });
+      }
+
+    });
+
+    class Schema$1 extends Geom {
+      getDefaultCfg() {
+        var cfg = super.getDefaultCfg();
+        cfg.type = 'schema';
+        cfg.shapeType = 'schema';
+        cfg.generatePoints = true;
+        return cfg;
+      }
+
+      constructor(cfg) {
+        super(cfg);
+        mix(this, SizeMixin);
+      }
+
+      init() {
+        super.init(); // 绑定事件
+
+        this.initEvent();
+      }
+
+      createShapePointsCfg(obj) {
+        var cfg = super.createShapePointsCfg(obj);
+        cfg.size = this.getNormalizedSize(obj);
+        return cfg;
+      }
+
+      clearInner() {
+        super.clearInner();
+        this.set('defaultSize', null);
+      }
+
+    }
+
+    Geom.Schema = Schema$1;
+
+    var toString$3 = {}.toString;
+    var isType$1 = function isType(value, type) {
+      return toString$3.call(value) === '[object ' + type + ']';
+    };
+
+    var isType_1 = isType$1;
+
+    var isArray$1 = Array.isArray ? Array.isArray : function (value) {
+      return isType_1(value, 'Array');
+    };
+
+    var isArray_1 = isArray$1;
+
+    // isFinite,
+    var isNil$1 = function isNil(value) {
+      /**
+       * isNil(null) => true
+       * isNil() => true
+       */
+      return value === null || value === undefined;
+    };
+
+    var isNil_1 = isNil$1;
+
+    function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; }
+
+
+
+
+
+
+
+    var Stack =
+    /*#__PURE__*/
+    function (_Adjust) {
+      _inheritsLoose(Stack, _Adjust);
+
+      function Stack() {
+        return _Adjust.apply(this, arguments) || this;
+      }
+
+      var _proto = Stack.prototype;
+
+      _proto._initDefaultCfg = function _initDefaultCfg() {
+        this.xField = null; // 调整对应的 x 方向对应的字段名称
+
+        this.yField = null; // 调整对应的 y 方向对应的字段名称
+      };
+
+      _proto.processAdjust = function processAdjust(dataArray) {
+        this.processStack(dataArray);
+      };
+
+      _proto.processStack = function processStack(dataArray) {
+        var self = this;
+        var xField = self.xField;
+        var yField = self.yField;
+        var count = dataArray.length;
+        var stackCache = {
+          positive: {},
+          negative: {}
+        }; // 层叠顺序翻转
+
+        if (self.reverseOrder) {
+          dataArray = dataArray.slice(0).reverse();
+        }
+
+        for (var i = 0; i < count; i++) {
+          var data = dataArray[i];
+
+          for (var j = 0, len = data.length; j < len; j++) {
+            var item = data[j];
+            var x = item[xField] || 0;
+            var y = item[yField];
+            var xkey = x.toString();
+            y = isArray_1(y) ? y[1] : y;
+
+            if (!isNil_1(y)) {
+              var direction = y >= 0 ? 'positive' : 'negative';
+
+              if (!stackCache[direction][xkey]) {
+                stackCache[direction][xkey] = 0;
+              }
+
+              item[yField] = [stackCache[direction][xkey], y + stackCache[direction][xkey]];
+              stackCache[direction][xkey] += y;
+            }
+          }
+        }
+      };
+
+      return Stack;
+    }(base);
+
+    base.Stack = Stack;
+
+    var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
+
+    var isObject$1 = function isObject(value) {
+      /**
+       * isObject({}) => true
+       * isObject([1, 2, 3]) => true
+       * isObject(Function) => true
+       * isObject(null) => false
+       */
+      var type = typeof value === 'undefined' ? 'undefined' : _typeof(value);
+      return value !== null && type === 'object' || type === 'function';
+    };
+
+    var isObject_1 = isObject$1;
+
+    var each$1 = function each(elements, func) {
+      if (!elements) {
+        return;
+      }
+      var rst = void 0;
+      if (isArray_1(elements)) {
+        for (var i = 0, len = elements.length; i < len; i++) {
+          rst = func(elements[i], i);
+          if (rst === false) {
+            break;
+          }
+        }
+      } else if (isObject_1(elements)) {
+        for (var k in elements) {
+          if (elements.hasOwnProperty(k)) {
+            rst = func(elements[k], k);
+            if (rst === false) {
+              break;
+            }
+          }
+        }
+      }
+    };
+
+    var each_1 = each$1;
+
+    function _inheritsLoose$1(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; }
+
+
+
+
+
+    var MARGIN_RATIO = 1 / 2;
+    var DODGE_RATIO = 1 / 2;
+
+    var Dodge =
+    /*#__PURE__*/
+    function (_Adjust) {
+      _inheritsLoose$1(Dodge, _Adjust);
+
+      function Dodge() {
+        return _Adjust.apply(this, arguments) || this;
+      }
+
+      var _proto = Dodge.prototype;
+
+      _proto._initDefaultCfg = function _initDefaultCfg() {
+        /**
+         * 调整过程中,2个数据的间距
+         * @type {Number}
+         */
+        this.marginRatio = MARGIN_RATIO;
+        /**
+         * 调整占单位宽度的比例,例如:占2个分类间距的 1/2
+         * @type {Number}
+         */
+
+        this.dodgeRatio = DODGE_RATIO;
+        this.adjustNames = ['x', 'y']; // 调整的维度,默认,x,y都做调整
+      };
+
+      _proto.getDodgeOffset = function getDodgeOffset(range, index, count) {
+        var self = this;
+        var pre = range.pre;
+        var next = range.next;
+        var tickLength = next - pre;
+        var width = tickLength * self.dodgeRatio / count;
+        var margin = self.marginRatio * width;
+        var offset = 1 / 2 * (tickLength - count * width - (count - 1) * margin) + ((index + 1) * width + index * margin) - 1 / 2 * width - 1 / 2 * tickLength;
+        return (pre + next) / 2 + offset;
+      };
+
+      _proto.processAdjust = function processAdjust(dataArray) {
+        var self = this;
+        var count = dataArray.length;
+        var xField = self.xField;
+        each_1(dataArray, function (data, index) {
+          for (var i = 0, len = data.length; i < len; i++) {
+            var obj = data[i];
+            var value = obj[xField];
+            var range = {
+              pre: len === 1 ? value - 1 : value - 0.5,
+              next: len === 1 ? value + 1 : value + 0.5
+            };
+            var dodgeValue = self.getDodgeOffset(range, index, count);
+            obj[xField] = dodgeValue;
+          }
+        });
+      };
+
+      return Dodge;
+    }(base);
+
+    base.Dodge = Dodge;
+
+    /**
+     * 是否为函数
+     * @param  {*} fn 对象
+     * @return {Boolean}  是否函数
+     */
+
+
+    var isFunction$1 = function isFunction(value) {
+      return isType_1(value, 'Function');
+    };
+
+    var isFunction_1 = isFunction$1;
+
+    /**
+     * @param {Array} arr The array to iterate over.
+     * @param {Function} [fn] The iteratee invoked per element.
+     * @return {*} Returns the maximum value.
+     * @example
+     *
+     * var objects = [{ 'n': 1 }, { 'n': 2 }];
+     *
+     * maxBy(objects, function(o) { return o.n; });
+     * // => { 'n': 2 }
+     *
+     * maxBy(objects, 'n');
+     * // => { 'n': 2 }
+     */
+    var maxBy$1 = function maxBy(arr, fn) {
+      if (!isArray_1(arr)) {
+        return undefined;
+      }
+      var max = arr[0];
+      var maxData = void 0;
+      if (isFunction_1(fn)) {
+        maxData = fn(arr[0]);
+      } else {
+        maxData = arr[0][fn];
+      }
+      var data = void 0;
+      each_1(arr, function (val) {
+        if (isFunction_1(fn)) {
+          data = fn(val);
+        } else {
+          data = val[fn];
+        }
+        if (data > maxData) {
+          max = val;
+          maxData = data;
+        }
+      });
+      return max;
+    };
+
+    var maxBy_1 = maxBy$1;
+
+    var merge$1 = function merge(dataArray) {
+      var rst = [];
+      for (var i = 0; i < dataArray.length; i++) {
+        rst = rst.concat(dataArray[i]);
+      }
+      return rst;
+    };
+
+    var merge_1 = merge$1;
+
+    function _inheritsLoose$2(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; }
+
+
+
+
+
+
+
+    var ArrayUtil = {
+      merge: merge_1
+    };
+
+
+
+    var Symmetric =
+    /*#__PURE__*/
+    function (_Adjust) {
+      _inheritsLoose$2(Symmetric, _Adjust);
+
+      function Symmetric() {
+        return _Adjust.apply(this, arguments) || this;
+      }
+
+      var _proto = Symmetric.prototype;
+
+      _proto._initDefaultCfg = function _initDefaultCfg() {
+        this.xField = null; // 调整对应的 x 方向对应的字段名称
+
+        this.yField = null; // 调整对应的 y 方向对应的字段名称
+
+        this.cacheMax = null; // 缓存的最大值
+
+        this.adjustNames = ['y']; // Only support stack y
+
+        this.groupFields = null; // 参与分组的数据维度
+      }; // 获取最大的y值
+
+
+      _proto._getMax = function _getMax(dim) {
+        var self = this;
+        var mergeData = self.mergeData;
+        var maxRecord = maxBy_1(mergeData, function (obj) {
+          var value = obj[dim];
+
+          if (isArray_1(value)) {
+            return Math.max.apply(null, value);
+          }
+
+          return value;
+        });
+        var maxValue = maxRecord[dim];
+        var max = isArray_1(maxValue) ? Math.max.apply(null, maxValue) : maxValue;
+        return max;
+      }; // 获取每个字段最大的值
+
+
+      _proto._getXValuesMax = function _getXValuesMax() {
+        var self = this;
+        var yField = self.yField;
+        var xField = self.xField;
+        var cache = {};
+        var mergeData = self.mergeData;
+        each_1(mergeData, function (obj) {
+          var xValue = obj[xField];
+          var yValue = obj[yField];
+          var max = isArray_1(yValue) ? Math.max.apply(null, yValue) : yValue;
+          cache[xValue] = cache[xValue] || 0;
+
+          if (cache[xValue] < max) {
+            cache[xValue] = max;
+          }
+        });
+        return cache;
+      }; // 入口函数
+
+
+      _proto.processAdjust = function processAdjust(dataArray) {
+        var self = this;
+        var mergeData = ArrayUtil.merge(dataArray);
+        self.mergeData = mergeData;
+
+        self._processSymmetric(dataArray);
+
+        self.mergeData = null;
+      }; // 处理对称
+
+
+      _proto._processSymmetric = function _processSymmetric(dataArray) {
+        var self = this;
+        var xField = self.xField;
+        var yField = self.yField;
+
+        var max = self._getMax(yField);
+
+        var first = dataArray[0][0];
+        var cache;
+
+        if (first && isArray_1(first[yField])) {
+          cache = self._getXValuesMax();
+        }
+
+        each_1(dataArray, function (data) {
+          each_1(data, function (obj) {
+            var value = obj[yField];
+            var offset;
+
+            if (isArray_1(value)) {
+              var xValue = obj[xField];
+              var valueMax = cache[xValue];
+              offset = (max - valueMax) / 2;
+              var tmp = [];
+              /* eslint-disable no-loop-func */
+
+              each_1(value, function (subVal) {
+                // 多个字段
+                tmp.push(offset + subVal);
+              });
+              /* eslint-enable no-loop-func */
+
+              obj[yField] = tmp;
+            } else {
+              offset = (max - value) / 2;
+              obj[yField] = [offset, value + offset];
+            }
+          });
+        });
+      };
+
+      return Symmetric;
+    }(base);
+
+    base.Symmetric = Symmetric;
+
+    class Polar extends Base$1 {
+      _initDefaultCfg() {
+        this.type = 'polar';
+        this.startAngle = -Math.PI / 2;
+        this.endAngle = Math.PI * 3 / 2;
+        this.inner = 0;
+        this.innerRadius = 0; // alias
+
+        this.isPolar = true;
+        this.transposed = false;
+        this.center = null;
+        this.radius = null; // relative, 0 ~ 1
+      }
+
+      init(start, end) {
+        super.init(start, end);
+        var self = this;
+        var inner = self.inner || self.innerRadius;
+        var width = Math.abs(end.x - start.x);
+        var height = Math.abs(end.y - start.y);
+        var maxRadius;
+        var center;
+
+        if (self.startAngle === -Math.PI && self.endAngle === 0) {
+          maxRadius = Math.min(width / 2, height);
+          center = {
+            x: (start.x + end.x) / 2,
+            y: start.y
+          };
+        } else {
+          maxRadius = Math.min(width, height) / 2;
+          center = {
+            x: (start.x + end.x) / 2,
+            y: (start.y + end.y) / 2
+          };
+        }
+
+        var radius = self.radius;
+
+        if (radius > 0 && radius <= 1) {
+          maxRadius = maxRadius * radius;
+        }
+
+        this.x = {
+          start: self.startAngle,
+          end: self.endAngle
+        };
+        this.y = {
+          start: maxRadius * inner,
+          end: maxRadius
+        };
+        this.center = center;
+        this.circleRadius = maxRadius; // the radius value in px
+      }
+
+      _convertPoint(point) {
+        var self = this;
+        var center = self.center;
+        var transposed = self.transposed;
+        var xDim = transposed ? 'y' : 'x';
+        var yDim = transposed ? 'x' : 'y';
+        var x = self.x;
+        var y = self.y;
+        var angle = x.start + (x.end - x.start) * point[xDim];
+        var radius = y.start + (y.end - y.start) * point[yDim];
+        return {
+          x: center.x + Math.cos(angle) * radius,
+          y: center.y + Math.sin(angle) * radius
+        };
+      }
+
+      _invertPoint(point) {
+        var self = this;
+        var {
+          center,
+          transposed,
+          x,
+          y
+        } = self;
+        var xDim = transposed ? 'y' : 'x';
+        var yDim = transposed ? 'x' : 'y';
+        var m = [1, 0, 0, 1, 0, 0];
+        Matrix.rotate(m, m, x.start);
+        var startV = [1, 0];
+        Vector2.transformMat2d(startV, startV, m);
+        startV = [startV[0], startV[1]];
+        var pointV = [point.x - center.x, point.y - center.y];
+
+        if (Vector2.zero(pointV)) {
+          return {
+            x: 0,
+            y: 0
+          };
+        }
+
+        var theta = Vector2.angleTo(startV, pointV, x.end < x.start);
+
+        if (Math.abs(theta - Math.PI * 2) < 0.001) {
+          theta = 0;
+        }
+
+        var l = Vector2.length(pointV);
+        var percentX = theta / (x.end - x.start);
+        percentX = x.end - x.start > 0 ? percentX : -percentX;
+        var percentY = (l - y.start) / (y.end - y.start);
+        var rst = {};
+        rst[xDim] = percentX;
+        rst[yDim] = percentY;
+        return rst;
+      }
+
+    }
+
+    Base$1.Polar = Polar;
+
+    class Circle$1 extends Abastract {
+      _initDefaultCfg() {
+        super._initDefaultCfg();
+
+        this.startAngle = -Math.PI / 2; // start angle,in radian
+
+        this.endAngle = Math.PI * 3 / 2; // end angle, in radian
+
+        this.radius = null; // radius
+
+        this.center = null; // center
+      }
+
+      getOffsetPoint(value) {
+        var {
+          startAngle,
+          endAngle
+        } = this;
+        var angle = startAngle + (endAngle - startAngle) * value;
+        return this._getCirclePoint(angle);
+      }
+
+      _getCirclePoint(angle, radius) {
+        var self = this;
+        var center = self.center;
+        radius = radius || self.radius;
+        return {
+          x: center.x + Math.cos(angle) * radius,
+          y: center.y + Math.sin(angle) * radius
+        };
+      }
+
+      getTextAlignInfo(point, offset) {
+        var self = this;
+        var offsetVector = self.getOffsetVector(point, offset);
+        var align;
+        var baseLine = 'middle';
+
+        if (offsetVector[0] > 0) {
+          align = 'left';
+        } else if (offsetVector[0] < 0) {
+          align = 'right';
+        } else {
+          align = 'center';
+
+          if (offsetVector[1] > 0) {
+            baseLine = 'top';
+          } else if (offsetVector[1] < 0) {
+            baseLine = 'bottom';
+          }
+        }
+
+        return {
+          textAlign: align,
+          textBaseline: baseLine
+        };
+      }
+
+      getAxisVector(point) {
+        var center = this.center;
+        var factor = this.offsetFactor;
+        return [(point.y - center.y) * factor, (point.x - center.x) * -1 * factor];
+      }
+
+      drawLine(lineCfg) {
+        var {
+          center,
+          radius,
+          startAngle,
+          endAngle
+        } = this;
+        var container = this.getContainer(lineCfg.top);
+        container.addShape('arc', {
+          className: 'axis-line',
+          attrs: mix({
+            x: center.x,
+            y: center.y,
+            r: radius,
+            startAngle,
+            endAngle
+          }, lineCfg)
+        });
+      }
+
+    }
+
+    Abastract.Circle = Circle$1;
+
+    var KEYWORDS_PERCENT = {
+      min: 0,
+      median: 0.5,
+      max: 1
+    };
+
+    class GuideBase {
+      _initDefaultCfg() {}
+
+      constructor(cfg) {
+        this._initDefaultCfg();
+
+        deepMix(this, cfg);
+      }
+
+      _getNormalizedValue(val, scale) {
+        var rst;
+
+        if (isNil(KEYWORDS_PERCENT[val])) {
+          rst = scale.scale(val);
+        } else {
+          rst = KEYWORDS_PERCENT[val];
+        }
+
+        return rst;
+      }
+
+      parsePercentPoint(coord, position) {
+        var xPercent = parseFloat(position[0]) / 100;
+        var yPercent = parseFloat(position[1]) / 100;
+        var start = coord.start;
+        var end = coord.end;
+        var width = Math.abs(start.x - end.x);
+        var height = Math.abs(start.y - end.y);
+        var x = width * xPercent + Math.min(start.x, end.x);
+        var y = height * yPercent + Math.min(start.y, end.y);
+        return {
+          x,
+          y
+        };
+      }
+
+      parsePoint(coord, position) {
+        var self = this;
+        var xScale = self.xScale;
+        var yScales = self.yScales;
+
+        if (isFunction(position)) {
+          position = position(xScale, yScales); // position 必须是对象
+        } // 如果数据格式是 ['50%', '50%'] 的格式
+        // fix: 原始数据中可能会包含 'xxx5%xxx' 这样的数据,需要判断下 https://github.com/antvis/f2/issues/590
+
+
+        if (isString(position[0]) && position[0].indexOf('%') !== -1 && !isNaN(position[0].slice(0, -1))) {
+          return this.parsePercentPoint(coord, position);
+        }
+
+        var x = self._getNormalizedValue(position[0], xScale);
+
+        var y = self._getNormalizedValue(position[1], yScales[0]);
+
+        var point = coord.convertPoint({
+          x,
+          y
+        });
+
+        if (self.limitInPlot) {
+          // limit in chart plotRange
+          if (x >= 0 && x <= 1 && y >= 0 && y <= 1) {
+            return point;
+          }
+
+          return null;
+        }
+
+        return point;
+      }
+      /**
+       * render the guide component
+       * @param  {Coord} coord  coordinate instance
+       * @param  {Canvas.Group} group the container
+       */
+
+
+      render()
+      /* coord,group */
+      {}
+
+      repaint() {
+        this.remove();
+        var {
+          coord,
+          container,
+          canvas
+        } = this;
+
+        if (container && !container.isDestroyed()) {
+          this.render(coord, container);
+          canvas.draw();
+        }
+      }
+
+      remove() {
+        var {
+          element
+        } = this;
+        element && element.remove(true);
+      }
+
+      changeVisible(visible) {
+        var self = this;
+        self.visible = visible;
+        var element = self.element;
+        if (!element) return;
+
+        if (element.set) {
+          element.set('visible', visible);
+        } else {
+          element.style.display = visible ? '' : 'none';
+        }
+      }
+
+    }
+
+    class Arc$1 extends GuideBase {
+      _initDefaultCfg() {
+        this.type = 'arc';
+        /**
+         * start point
+         * @type {Array | Function}
+         */
+
+        this.start = [];
+        /**
+         * end point
+         * @type {Array | Function}
+         */
+
+        this.end = [];
+        /**
+         * style configuration
+         * @type {Object}
+         */
+
+        this.style = {
+          stroke: '#999',
+          lineWidth: 1
+        };
+      }
+
+      render(coord, container) {
+        var self = this;
+        var start = self.parsePoint(coord, self.start);
+        var end = self.parsePoint(coord, self.end);
+
+        if (!start || !end) {
+          return;
+        }
+
+        var coordCenter = coord.center;
+        var radius = Math.sqrt((start.x - coordCenter.x) * (start.x - coordCenter.x) + (start.y - coordCenter.y) * (start.y - coordCenter.y));
+        var startAngle = Math.atan2(start.y - coordCenter.y, start.x - coordCenter.x);
+        var endAngle = Math.atan2(end.y - coordCenter.y, end.x - coordCenter.x);
+        var shape = container.addShape('arc', {
+          className: 'guide-arc',
+          attrs: mix({
+            x: coordCenter.x,
+            y: coordCenter.y,
+            r: radius,
+            startAngle,
+            endAngle
+          }, self.style)
+        });
+        self.element = shape;
+        return shape;
+      }
+
+    }
+
+    GuideBase.Arc = Arc$1;
+
+    function getOffsetFromAlign(alignX, alignY, width, height) {
+      var result = [];
+
+      if (alignX === 'left' && alignY === 'top') {
+        result[0] = 0;
+        result[1] = 0;
+      } else if (alignX === 'right' && alignY === 'top') {
+        result[0] = -width;
+        result[1] = 0;
+      } else if (alignX === 'left' && alignY === 'bottom') {
+        result[0] = 0;
+        result[1] = Math.floor(-height);
+      } else if (alignX === 'right' && alignY === 'bottom') {
+        result[0] = Math.floor(-width);
+        result[1] = Math.floor(-height);
+      } else if (alignX === 'right' && alignY === 'middle') {
+        result[0] = Math.floor(-width);
+        result[1] = Math.floor(-height / 2);
+      } else if (alignX === 'left' && alignY === 'middle') {
+        result[0] = 0;
+        result[1] = Math.floor(-height / 2);
+      } else if (alignX === 'center' && alignY === 'bottom') {
+        result[0] = Math.floor(-width / 2);
+        result[1] = Math.floor(-height);
+      } else if (alignX === 'center' && alignY === 'top') {
+        result[0] = Math.floor(-width / 2);
+        result[1] = 0;
+      } else {
+        result[0] = Math.floor(-width / 2);
+        result[1] = Math.floor(-height / 2);
+      }
+
+      return result;
+    }
+
+    function modifyCSS(DOM, CSS) {
+      for (var key in CSS) {
+        if (CSS.hasOwnProperty(key)) {
+          DOM.style[key] = CSS[key];
+        }
+      }
+
+      return DOM;
+    }
+
+    function createDom(str) {
+      var container = document.createElement('div');
+      str = str.replace(/(^\s*)|(\s*$)/g, '');
+      container.innerHTML = '' + str;
+      return container.childNodes[0];
+    }
+
+    class Html extends GuideBase {
+      _initDefaultCfg() {
+        this.type = 'html';
+        /**
+         * dom position
+         * @type {Object | Array}
+         */
+
+        this.position = null;
+        /**
+          * alignment for horizontal direction,can be 'left','center','right'
+          * @type {String}
+          */
+
+        this.alignX = 'center';
+        /**
+          * alignment for vertical direction,can be 'top', 'middle', 'bottom'
+          * @type {String}
+          */
+
+        this.alignY = 'middle';
+        /**
+          * offset for horizontal direction
+          * @type {Number}
+          */
+
+        this.offsetX = null;
+        /**
+          * offset for vertical direction
+          * @type {Number}
+          */
+
+        this.offsetY = null;
+        /**
+        * the html string
+        *@type {String | Function}
+        */
+
+        this.html = null;
+      } // override paint
+
+
+      render(coord, container) {
+        var self = this;
+        var position = self.parsePoint(coord, self.position);
+
+        if (!position) {
+          return;
+        }
+
+        var myNode = createDom(self.html);
+        myNode = modifyCSS(myNode, {
+          position: 'absolute',
+          top: Math.floor(position.y) + 'px',
+          left: Math.floor(position.x) + 'px',
+          visibility: 'hidden'
+        });
+        var canvasDom = container.get('canvas').get('el');
+        var parentNode = canvasDom.parentNode;
+        parentNode = modifyCSS(parentNode, {
+          position: 'relative'
+        });
+        var wrapperNode = createDom('<div class="guideWapper" style="position: absolute;top: 0; left: 0;"></div>');
+        parentNode.appendChild(wrapperNode);
+        wrapperNode.appendChild(myNode);
+        var canvasOffsetTop = canvasDom.offsetTop;
+        var canvasOffsetLeft = canvasDom.offsetLeft;
+        var {
+          alignX,
+          alignY,
+          offsetX,
+          offsetY
+        } = self;
+        var width = getWidth(myNode);
+        var height = getHeight(myNode);
+        var newOffset = getOffsetFromAlign(alignX, alignY, width, height);
+        position.x = position.x + newOffset[0] + canvasOffsetLeft;
+        position.y = position.y + newOffset[1] + canvasOffsetTop;
+
+        if (offsetX) {
+          position.x += offsetX;
+        }
+
+        if (offsetY) {
+          position.y += offsetY;
+        }
+
+        modifyCSS(myNode, {
+          top: Math.floor(position.y) + 'px',
+          left: Math.floor(position.x) + 'px',
+          visibility: 'visible'
+        });
+        self.element = wrapperNode;
+      }
+
+      remove() {
+        var element = this.element;
+        element && element.parentNode && element.parentNode.removeChild(element);
+      }
+
+    }
+
+    GuideBase.Html = Html;
+
+    class Line$4 extends GuideBase {
+      _initDefaultCfg() {
+        this.type = 'line';
+        this.start = [];
+        this.end = [];
+        this.style = {
+          stroke: '#000',
+          lineWidth: 1
+        };
+      }
+
+      render(coord, container) {
+        var points = [];
+        points[0] = this.parsePoint(coord, this.start);
+        points[1] = this.parsePoint(coord, this.end);
+
+        if (!points[0] || !points[1]) {
+          return;
+        }
+
+        var shape = container.addShape('Line', {
+          className: 'guide-line',
+          attrs: mix({
+            x1: points[0].x,
+            y1: points[0].y,
+            x2: points[1].x,
+            y2: points[1].y
+          }, this.style)
+        });
+        this.element = shape;
+        return shape;
+      }
+
+    }
+
+    GuideBase.Line = Line$4;
+
+    class Rect$2 extends GuideBase {
+      _initDefaultCfg() {
+        this.type = 'rect';
+        this.start = [];
+        this.end = [];
+        this.style = {
+          fill: '#CCD7EB',
+          opacity: 0.4
+        };
+      }
+
+      render(coord, container) {
+        var start = this.parsePoint(coord, this.start);
+        var end = this.parsePoint(coord, this.end);
+
+        if (!start || !end) {
+          return;
+        }
+
+        var shape = container.addShape('rect', {
+          className: 'guide-rect',
+          attrs: mix({
+            x: Math.min(start.x, end.x),
+            y: Math.min(start.y, end.y),
+            width: Math.abs(end.x - start.x),
+            height: Math.abs(start.y - end.y)
+          }, this.style)
+        });
+        this.element = shape;
+        return shape;
+      }
+
+    }
+
+    GuideBase.Rect = Rect$2;
+
+    class Text$1 extends GuideBase {
+      _initDefaultCfg() {
+        this.type = 'text';
+        /**
+         * the position of text
+         * @type {Function | Array}
+         */
+
+        this.position = null;
+        /**
+         * the display content
+         * @type {String}
+         */
+
+        this.content = null;
+        /**
+         * style configuration for text
+         * @type {Object}
+         */
+
+        this.style = {
+          fill: '#000'
+        };
+        /**
+         * offset of horizontal direction
+         * @type {Number}
+         */
+
+        this.offsetX = 0;
+        /**
+         * offset of vertical direction
+         * @type {Number}
+         */
+
+        this.offsetY = 0;
+      }
+
+      render(coord, container) {
+        var position = this.position;
+        var point = this.parsePoint(coord, position);
+
+        if (!point) {
+          return;
+        }
+
+        var {
+          content,
+          style,
+          offsetX,
+          offsetY
+        } = this;
+
+        if (offsetX) {
+          point.x += offsetX;
+        }
+
+        if (offsetY) {
+          point.y += offsetY;
+        }
+
+        var shape = container.addShape('text', {
+          className: 'guide-text',
+          attrs: mix({
+            x: point.x,
+            y: point.y,
+            text: content
+          }, style)
+        });
+        this.element = shape;
+        return shape;
+      }
+
+    }
+
+    GuideBase.Text = Text$1;
+
+    class Tag extends GuideBase {
+      _initDefaultCfg() {
+        this.type = 'tag';
+        this.position = null;
+        this.content = null;
+        this.direct = 'tl';
+        this.autoAdjust = true;
+        this.offsetX = 0;
+        this.offsetY = 0;
+        this.side = 4;
+        this.background = {
+          padding: 5,
+          radius: 2,
+          fill: '#1890FF'
+        };
+        this.textStyle = {
+          fontSize: 12,
+          fill: '#fff',
+          textAlign: 'center',
+          textBaseline: 'middle'
+        };
+        this.withPoint = true;
+        this.pointStyle = {
+          fill: '#1890FF',
+          r: 3,
+          lineWidth: 1,
+          stroke: '#fff'
+        };
+      }
+
+      _getDirect(container, point, tagWidth, tagHeight) {
+        var direct = this.direct;
+        var side = this.side;
+        var canvas = container.get('canvas');
+        var clientWidth = canvas.get('width');
+        var clientHeight = canvas.get('height');
+        var {
+          x,
+          y
+        } = point;
+        var vertical = direct[0];
+        var horizontal = direct[1]; // adjust for vertical direction
+
+        if (vertical === 't' && y - side - tagHeight < 0) {
+          vertical = 'b';
+        } else if (vertical === 'b' && y + side + tagHeight > clientHeight) {
+          vertical = 't';
+        } // adjust for horizontal direction
+
+
+        var diff = vertical === 'c' ? side : 0;
+
+        if (horizontal === 'l' && x - diff - tagWidth < 0) {
+          horizontal = 'r';
+        } else if (horizontal === 'r' && x + diff + tagWidth > clientWidth) {
+          horizontal = 'l';
+        } else if (horizontal === 'c') {
+          if (tagWidth / 2 + x + diff > clientWidth) {
+            horizontal = 'l';
+          } else if (x - tagWidth / 2 - diff < 0) {
+            horizontal = 'r';
+          }
+        }
+
+        direct = vertical + horizontal;
+        return direct;
+      }
+
+      render(coord, container) {
+        var position = this.parsePoint(coord, this.position);
+
+        if (!position) {
+          return;
+        } // 数据不在显示范围内时,x/y 会为NaN
+
+
+        if (isNaN(position.x) || isNaN(position.y)) {
+          return;
+        }
+
+        var {
+          content,
+          background,
+          textStyle
+        } = this;
+        var shapes = [];
+        var wrapperContainer = container.addGroup({
+          className: 'guide-tag'
+        });
+
+        if (this.withPoint) {
+          var pointShape = wrapperContainer.addShape('Circle', {
+            className: 'guide-tag-point',
+            attrs: mix({
+              x: position.x,
+              y: position.y
+            }, this.pointStyle)
+          });
+          shapes.push(pointShape);
+        }
+
+        var tagContainer = wrapperContainer.addGroup(); // create a text shape
+
+        var tagText = tagContainer.addShape('text', {
+          className: 'guide-tag-text',
+          zIndex: 1,
+          attrs: mix({
+            x: 0,
+            y: 0,
+            text: content
+          }, textStyle)
+        });
+        shapes.push(tagText); // create background box
+
+        var textBBox = tagText.getBBox();
+        var padding = parsePadding(background.padding);
+        var tagWidth = textBBox.width + padding[1] + padding[3];
+        var tagHeight = textBBox.height + padding[0] + padding[2];
+        var yMin = textBBox.minY - padding[0];
+        var xMin = textBBox.minX - padding[3];
+        var tagBg = tagContainer.addShape('rect', {
+          className: 'guide-tag-bg',
+          zIndex: -1,
+          attrs: mix({
+            x: xMin,
+            y: yMin,
+            width: tagWidth,
+            height: tagHeight
+          }, background)
+        });
+        shapes.push(tagBg);
+        var direct = this.autoAdjust ? this._getDirect(container, position, tagWidth, tagHeight) : this.direct;
+        var side = this.side;
+        var x = position.x + this.offsetX;
+        var y = position.y + this.offsetY;
+        var arrowPoints;
+        var radius = parsePadding(background.radius);
+
+        if (direct === 'tl') {
+          arrowPoints = [{
+            x: tagWidth + xMin - side - 1,
+            y: tagHeight + yMin - 1
+          }, // 这个 1 是为了防止出现白边
+          {
+            x: tagWidth + xMin,
+            y: tagHeight + yMin - 1
+          }, {
+            x: tagWidth + xMin,
+            y: tagHeight + side + yMin
+          }];
+          radius[2] = 0;
+          x = x - tagWidth;
+          y = y - side - tagHeight;
+        } else if (direct === 'cl') {
+          arrowPoints = [{
+            x: tagWidth + xMin - 1,
+            y: (tagHeight - side) / 2 + yMin - 1
+          }, {
+            x: tagWidth + xMin - 1,
+            y: (tagHeight + side) / 2 + yMin + 1
+          }, {
+            x: tagWidth + side + xMin,
+            y: tagHeight / 2 + yMin
+          }];
+          x = x - tagWidth - side;
+          y = y - tagHeight / 2;
+        } else if (direct === 'bl') {
+          arrowPoints = [{
+            x: tagWidth + xMin,
+            y: -side + yMin
+          }, {
+            x: tagWidth + xMin - side - 1,
+            y: yMin + 1
+          }, {
+            x: tagWidth + xMin,
+            y: yMin + 1
+          }];
+          radius[1] = 0;
+          x = x - tagWidth;
+          y = y + side;
+        } else if (direct === 'bc') {
+          arrowPoints = [{
+            x: tagWidth / 2 + xMin,
+            y: -side + yMin
+          }, {
+            x: (tagWidth - side) / 2 + xMin - 1,
+            y: yMin + 1
+          }, {
+            x: (tagWidth + side) / 2 + xMin + 1,
+            y: yMin + 1
+          }];
+          x = x - tagWidth / 2;
+          y = y + side;
+        } else if (direct === 'br') {
+          arrowPoints = [{
+            x: xMin,
+            y: yMin - side
+          }, {
+            x: xMin,
+            y: yMin + 1
+          }, {
+            x: xMin + side + 1,
+            y: yMin + 1
+          }];
+          radius[0] = 0;
+          y = y + side;
+        } else if (direct === 'cr') {
+          arrowPoints = [{
+            x: xMin - side,
+            y: tagHeight / 2 + yMin
+          }, {
+            x: xMin + 1,
+            y: (tagHeight - side) / 2 + yMin - 1
+          }, {
+            x: xMin + 1,
+            y: (tagHeight + side) / 2 + yMin + 1
+          }];
+          x = x + side;
+          y = y - tagHeight / 2;
+        } else if (direct === 'tr') {
+          arrowPoints = [{
+            x: xMin,
+            y: tagHeight + side + yMin
+          }, {
+            x: xMin,
+            y: tagHeight + yMin - 1
+          }, {
+            x: side + xMin + 1,
+            y: tagHeight + yMin - 1
+          }];
+          radius[3] = 0;
+          y = y - tagHeight - side;
+        } else if (direct === 'tc') {
+          arrowPoints = [{
+            x: (tagWidth - side) / 2 + xMin - 1,
+            y: tagHeight + yMin - 1
+          }, {
+            x: (tagWidth + side) / 2 + xMin + 1,
+            y: tagHeight + yMin - 1
+          }, {
+            x: tagWidth / 2 + xMin,
+            y: tagHeight + side + yMin
+          }];
+          x = x - tagWidth / 2;
+          y = y - tagHeight - side;
+        }
+
+        var sideShape = tagContainer.addShape('Polygon', {
+          className: 'guide-tag-side',
+          zIndex: 0,
+          attrs: {
+            points: arrowPoints,
+            fill: background.fill
+          }
+        });
+        shapes.push(sideShape);
+        tagBg.attr('radius', radius);
+        tagContainer.moveTo(x - xMin, y - yMin);
+        tagContainer.sort();
+        this.element = wrapperContainer;
+        return shapes;
+      }
+
+    }
+
+    GuideBase.Tag = Tag;
+
+    class Point$2 extends GuideBase {
+      _initDefaultCfg() {
+        this.type = 'point';
+        this.position = null;
+        this.offsetX = 0;
+        this.offsetY = 0;
+        this.style = {
+          fill: '#1890FF',
+          r: 3,
+          lineWidth: 1,
+          stroke: '#fff'
+        };
+      }
+
+      render(coord, container) {
+        var position = this.parsePoint(coord, this.position);
+        if (!position) return null;
+        var shape = container.addShape('Circle', {
+          className: 'guide-point',
+          attrs: mix({
+            x: position.x + this.offsetX,
+            y: position.y + this.offsetY
+          }, this.style)
+        });
+        this.element = shape;
+        return shape;
+      }
+
+    }
+
+    GuideBase.Point = Point$2;
+
+    /**
+     * marker shapes,used for tooltip and legend
+     */
+    var SYMBOLS = {
+      circle(x, y, r, ctx) {
+        ctx.arc(x, y, r, 0, Math.PI * 2, false);
+      },
+
+      square(x, y, r, ctx) {
+        ctx.moveTo(x - r, y - r);
+        ctx.lineTo(x + r, y - r);
+        ctx.lineTo(x + r, y + r);
+        ctx.lineTo(x - r, y + r);
+        ctx.closePath();
+      }
+
+    };
+
+    class Marker extends Shape$2 {
+      _initProperties() {
+        super._initProperties();
+
+        this._attrs.canFill = true;
+        this._attrs.canStroke = true;
+        this._attrs.type = 'marker';
+      }
+
+      getDefaultAttrs() {
+        return {
+          x: 0,
+          y: 0,
+          lineWidth: 0
+        };
+      }
+
+      createPath(context) {
+        var attrs = this.get('attrs');
+        var {
+          x,
+          y,
+          radius
+        } = attrs;
+        var symbol = attrs.symbol || 'circle';
+        var method;
+
+        if (isFunction(symbol)) {
+          method = symbol;
+        } else {
+          method = SYMBOLS[symbol];
+        }
+
+        context.beginPath();
+        method(x, y, radius, context, this);
+      }
+
+      calculateBox() {
+        var attrs = this.get('attrs');
+        var {
+          x,
+          y,
+          radius
+        } = attrs;
+        return {
+          minX: x - radius,
+          minY: y - radius,
+          maxX: x + radius,
+          maxY: y + radius
+        };
+      }
+
+    }
+
+    var MARKER_RADIUS = 3;
+
+    class List {
+      getDefaultCfg() {
+        return {
+          showTitle: false,
+
+          /**
+           * title string
+           * @type {?String}
+           */
+          title: null,
+
+          /**
+           * items array
+           * @type {?Array}
+           */
+          items: null,
+
+          /**
+           * offset between title and items
+           * @type {Number}
+           */
+          titleGap: 12,
+
+          /**
+           * offset between each item
+           * @type {Number}
+           */
+          itemGap: 10,
+
+          /**
+           * the offset between each item in vertical direaction
+           * @type {Number}
+           */
+          itemMarginBottom: 12,
+
+          /**
+           * the formatter for item text
+           * @type {[type]}
+           */
+          itemFormatter: null,
+          itemWidth: null,
+
+          /**
+           * offset between marker and text
+           * @type {Number}
+           */
+          wordSpace: 6,
+          x: 0,
+          y: 0,
+          layout: 'horizontal',
+
+          /**
+           * the join string of `name` and `value`
+           * @type {String}
+           */
+          joinString: ': '
+        };
+      }
+
+      constructor(cfg) {
+        deepMix(this, this.getDefaultCfg(), cfg);
+
+        this._init();
+
+        this._renderTitle();
+
+        this._renderItems();
+      }
+
+      _init() {
+        var container = new Group({
+          zIndex: this.zIndex || 0
+        });
+        this.container = container;
+        var wrapper = container.addGroup();
+        this.wrapper = wrapper;
+        var itemsGroup = wrapper.addGroup({
+          className: 'itemsGroup'
+        });
+        this.itemsGroup = itemsGroup;
+
+        if (this.parent) {
+          this.parent.add(container);
+        }
+      }
+
+      _renderTitle(title) {
+        title = title || this.title;
+        var titleShape = this.titleShape;
+        var titleHeight = 0;
+
+        if (this.showTitle && title) {
+          if (titleShape && !titleShape.get('destroyed')) {
+            titleShape.attr('text', title);
+          } else {
+            var {
+              wrapper,
+              titleStyle
+            } = this;
+            titleShape = wrapper.addShape('text', {
+              className: 'title',
+              attrs: mix({
+                x: 0,
+                y: 0,
+                text: title
+              }, titleStyle)
+            });
+            this.titleShape = titleShape;
+          }
+
+          titleHeight = titleShape.getBBox().height + this.titleGap;
+        }
+
+        this._titleHeight = titleHeight;
+      }
+
+      _renderItems(items) {
+        var self = this;
+        items = items || self.items;
+
+        if (!items) {
+          return;
+        }
+
+        if (self.reversed) {
+          items.reverse();
+        }
+
+        each(items, function (item, index) {
+          self._addItem(item, index);
+        });
+
+        if (items.length > 1) {
+          this._adjustItems();
+        }
+
+        this._renderBackground();
+      }
+
+      _renderBackground() {
+        var background = this.background;
+
+        if (background) {
+          var container = this.container;
+          var wrapper = this.wrapper;
+          var {
+            minX,
+            minY,
+            width,
+            height
+          } = wrapper.getBBox();
+          var padding = background.padding || [0, 0, 0, 0];
+          padding = parsePadding(padding);
+          var attrs = mix({
+            x: minX - padding[3],
+            y: minY - padding[0],
+            width: width + padding[1] + padding[3],
+            height: height + padding[0] + padding[2]
+          }, background);
+          var backShape = this.backShape;
+
+          if (backShape) {
+            backShape.attr(attrs);
+          } else {
+            backShape = container.addShape('Rect', {
+              zIndex: -1,
+              attrs
+            });
+          }
+
+          this.backShape = backShape;
+          container.sort();
+        }
+      }
+
+      _addItem(item) {
+        var itemsGroup = this.itemsGroup;
+        var itemGroup = itemsGroup.addGroup({
+          name: item.name,
+          value: item.value,
+          dataValue: item.dataValue,
+          checked: item.checked
+        });
+        var {
+          unCheckStyle,
+          unCheckColor,
+          nameStyle,
+          valueStyle,
+          wordSpace
+        } = this;
+        var {
+          marker,
+          value
+        } = item;
+        var startX = 0;
+
+        if (unCheckColor) {
+          unCheckStyle.fill = unCheckColor;
+        }
+
+        if (marker) {
+          var radius = marker.radius || MARKER_RADIUS;
+          var markerAttrs = mix({
+            x: radius,
+            y: this._titleHeight
+          }, marker);
+
+          if (item.checked === false) {
+            mix(markerAttrs, unCheckStyle);
+          }
+
+          var markerShape = new Marker({
+            className: 'item-marker',
+            attrs: markerAttrs
+          });
+          itemGroup.add(markerShape);
+          startX += markerShape.getBBox().width + wordSpace;
+        }
+
+        var nameText;
+        var name = item.name;
+
+        if (name) {
+          var joinString = this.joinString || '';
+          name = value ? name + joinString : name;
+          nameText = itemGroup.addShape('text', {
+            className: 'name',
+            attrs: mix({
+              x: startX,
+              y: this._titleHeight,
+              text: this._formatItemValue(name)
+            }, nameStyle, item.checked === false ? unCheckStyle : null)
+          });
+        }
+
+        if (value) {
+          var valueX = startX;
+
+          if (nameText) {
+            valueX += nameText.getBBox().width;
+          }
+
+          itemGroup.addShape('text', {
+            className: 'value',
+            attrs: mix({
+              x: valueX,
+              y: this._titleHeight,
+              text: value
+            }, valueStyle, item.checked === false ? unCheckStyle : null)
+          });
+        }
+
+        return itemGroup;
+      }
+
+      _formatItemValue(value) {
+        var formatter = this.itemFormatter;
+
+        if (formatter) {
+          value = formatter.call(this, value);
+        }
+
+        return value;
+      }
+
+      _getMaxItemWidth() {
+        var width;
+        var itemWidth = this.itemWidth;
+
+        if (isNumber(itemWidth) || isNil(itemWidth)) {
+          return itemWidth;
+        }
+
+        if (itemWidth === 'auto') {
+          var itemsGroup = this.itemsGroup;
+          var children = itemsGroup.get('children');
+          var count = children.length;
+          var maxItemWidth = 0;
+
+          for (var i = 0; i < count; i++) {
+            var {
+              width: _width
+            } = children[i].getBBox();
+            maxItemWidth = Math.max(maxItemWidth, _width);
+          }
+
+          var maxLength = this.maxLength;
+          var itemGap = this.itemGap;
+          var twoAvgWidth = (maxLength - itemGap) / 2;
+          var threeAvgWidth = (maxLength - itemGap * 2) / 3;
+
+          if (count === 2) {
+            width = Math.max(maxItemWidth, twoAvgWidth);
+          } else {
+            // 1. max <= 3Avg, 3Avg
+            // 2. 3Avg < max && max < 2avg, 2avg
+            // 3. max > 2avg, max, one column
+            if (maxItemWidth <= threeAvgWidth) {
+              width = threeAvgWidth;
+            } else if (maxItemWidth <= twoAvgWidth) {
+              width = twoAvgWidth;
+            } else {
+              width = maxItemWidth;
+            }
+          }
+
+          return width;
+        }
+      }
+
+      _adjustHorizontal() {
+        var {
+          maxLength,
+          itemsGroup
+        } = this;
+        var children = itemsGroup.get('children');
+        var {
+          itemGap,
+          itemMarginBottom
+        } = this;
+        var titleHeight = this._titleHeight;
+        var row = 0;
+        var rowWidth = 0;
+        var width;
+        var height;
+
+        var itemWidth = this._getMaxItemWidth();
+
+        var legendHitBoxes = [];
+
+        for (var i = 0, len = children.length; i < len; i++) {
+          var child = children[i];
+          var box = child.getBBox();
+          var childHeight = box.height;
+          var childWidth = box.width;
+          width = itemWidth || childWidth;
+          height = childHeight + itemMarginBottom;
+
+          if (width - (maxLength - rowWidth) > 0.0001) {
+            row++;
+            rowWidth = 0;
+          }
+
+          child.moveTo(rowWidth, row * height);
+          legendHitBoxes.push({
+            x: rowWidth,
+            y: row * height + titleHeight - childHeight / 2,
+            width: childWidth * 1.375,
+            height: childHeight * 1.375
+          });
+          rowWidth += width + itemGap;
+        }
+
+        this.legendHitBoxes = legendHitBoxes;
+        return;
+      }
+
+      _adjustVertical() {
+        var {
+          maxLength,
+          itemsGroup
+        } = this;
+        var {
+          itemGap,
+          itemMarginBottom,
+          itemWidth
+        } = this;
+        var titleHeight = this._titleHeight;
+        var children = itemsGroup.get('children');
+        var colHeight = 0;
+        var width;
+        var height;
+        var maxItemWidth = 0;
+        var totalWidth = 0;
+        var legendHitBoxes = [];
+
+        for (var i = 0, length = children.length; i < length; i++) {
+          var child = children[i];
+          var bbox = child.getBBox();
+          width = bbox.width;
+          height = bbox.height;
+
+          if (isNumber(itemWidth)) {
+            maxItemWidth = itemWidth + itemGap;
+          } else if (width > maxItemWidth) {
+            maxItemWidth = width + itemGap;
+          }
+
+          if (maxLength - colHeight < height) {
+            colHeight = 0;
+            totalWidth += maxItemWidth;
+            child.moveTo(totalWidth, 0);
+            legendHitBoxes.push({
+              x: totalWidth,
+              y: titleHeight - height / 2,
+              width: width * 1.375,
+              height: height * 1.375
+            });
+          } else {
+            child.moveTo(totalWidth, colHeight);
+            legendHitBoxes.push({
+              x: totalWidth,
+              y: colHeight - height / 2 + titleHeight,
+              width: width * 1.375,
+              height: height * 1.375
+            });
+          }
+
+          colHeight += height + itemMarginBottom;
+        }
+
+        this.legendHitBoxes = legendHitBoxes;
+        return;
+      }
+
+      _adjustItems() {
+        var layout = this.layout;
+
+        if (layout === 'horizontal') {
+          this._adjustHorizontal();
+        } else {
+          this._adjustVertical();
+        }
+      }
+
+      moveTo(x, y) {
+        this.x = x;
+        this.y = y;
+        var container = this.container;
+        container && container.moveTo(x, y);
+        return this;
+      }
+
+      setItems(items) {
+        this.clearItems();
+
+        this._renderItems(items);
+      }
+
+      setTitle(title) {
+        this._renderTitle(title);
+      }
+
+      clearItems() {
+        var itemsGroup = this.itemsGroup;
+        itemsGroup.clear();
+      }
+
+      getWidth() {
+        var container = this.container;
+        var bbox = container.getBBox();
+        return bbox.width;
+      }
+
+      getHeight() {
+        var container = this.container;
+        var bbox = container.getBBox();
+        return bbox.height;
+      }
+
+      show() {
+        var container = this.container;
+        container.show();
+      }
+
+      hide() {
+        var container = this.container;
+        container.hide();
+      }
+
+      clear() {
+        var container = this.container;
+        container.clear();
+        container.remove(true);
+      }
+
+    }
+
+    class TextBox {
+      getDefaultCfg() {
+        return {
+          x: 0,
+          y: 0,
+          content: '',
+          textStyle: {
+            fontSize: 12,
+            fill: '#fff',
+            textAlign: 'center',
+            textBaseline: 'middle',
+            fontFamily: 'Arial'
+          },
+          background: {
+            radius: 1,
+            fill: 'rgba(0, 0, 0, 0.65)',
+            padding: [3, 5]
+          },
+          width: 0,
+          height: 0,
+          className: ''
+        };
+      }
+
+      constructor(cfg) {
+        deepMix(this, this.getDefaultCfg(), cfg);
+
+        this._init();
+
+        var {
+          content,
+          x,
+          y
+        } = this;
+
+        if (!isNil(content)) {
+          this.updateContent(content);
+        }
+
+        this.updatePosition(x, y);
+      }
+
+      _init() {
+        var {
+          content,
+          textStyle,
+          background,
+          className,
+          visible,
+          context
+        } = this;
+        var container = new Group({
+          context,
+          className,
+          zIndex: 0,
+          visible
+        });
+        var text = container.addShape('Text', {
+          className: className + '-text',
+          zIndex: 1,
+          attrs: mix({
+            text: content,
+            x: 0,
+            y: 0
+          }, textStyle)
+        });
+        var backgroundShape = container.addShape('Rect', {
+          className: className + '-bg',
+          zIndex: -1,
+          attrs: mix({
+            x: 0,
+            y: 0,
+            width: 0,
+            height: 0
+          }, background)
+        });
+        container.sort();
+        this.container = container;
+        this.textShape = text;
+        this.backgroundShape = backgroundShape;
+      }
+
+      _getBBox() {
+        var textShape = this.textShape;
+        var background = this.background;
+        var textBBox = textShape.getBBox();
+        var padding = parsePadding(background.padding);
+        var width = textBBox.width + padding[1] + padding[3];
+        var height = textBBox.height + padding[0] + padding[2];
+        var x = textBBox.minX - padding[3];
+        var y = textBBox.minY - padding[0];
+        return {
+          x,
+          y,
+          width,
+          height
+        };
+      }
+
+      updateContent(text) {
+        var {
+          textShape,
+          backgroundShape
+        } = this;
+
+        if (!isNil(text)) {
+          if (!isObject(text)) {
+            text = {
+              text
+            };
+          }
+
+          textShape.attr(text); // update box shape
+
+          var {
+            x,
+            y,
+            width: tipWidth,
+            height: tipHeight
+          } = this._getBBox();
+
+          var width = this.width || tipWidth;
+          var height = this.height || tipHeight;
+          backgroundShape.attr({
+            x,
+            y,
+            width,
+            height
+          });
+          this._width = width;
+          this._height = height;
+          this.content = text.text;
+        }
+      }
+
+      updatePosition(x, y) {
+        var container = this.container;
+
+        var {
+          x: xMin,
+          y: yMin
+        } = this._getBBox();
+
+        container.moveTo(x - xMin, y - yMin);
+        this.x = x - xMin;
+        this.y = y - yMin;
+      }
+
+      getWidth() {
+        return this._width;
+      }
+
+      getHeight() {
+        return this._height;
+      }
+
+      show() {
+        this.container.show();
+      }
+
+      hide() {
+        this.container.hide();
+      }
+
+      clear() {
+        var container = this.container;
+        container.clear();
+        container.remove(true);
+        this.container = null;
+        this.textShape = null;
+        this.backgroundShape = null;
+      }
+
+    }
+
+    var GAP = 4;
+    /**
+     * TODOList:
+     * 1. 移除 fixed 参数
+     */
+
+    class Tooltip {
+      getDefaultCfg() {
+        return {
+          /**
+           * wether show the crosshairs
+           * @type {Object}
+           */
+          showCrosshairs: false,
+
+          /**
+           * the style for crosshairs
+           * @type {Object}
+           */
+          crosshairsStyle: {
+            stroke: 'rgba(0, 0, 0, 0.25)',
+            lineWidth: 1
+          },
+
+          /**
+           * the type of crosshairs, optional value is 'x', 'y' or 'xy', default is 'y'
+           */
+          crosshairsType: 'y',
+
+          /**
+           * show or hide the x axis tip
+           */
+          showXTip: false,
+
+          /**
+           * show or hide the y axis tip
+           */
+          showYTip: false,
+          xTip: null,
+          xTipBackground: {
+            radius: 1,
+            fill: 'rgba(0, 0, 0, 0.65)',
+            padding: [3, 5]
+          },
+          xTipTextStyle: {
+            fontSize: 12,
+            fill: '#fff',
+            textAlign: 'center',
+            textBaseline: 'middle'
+          },
+          yTip: null,
+          yTipBackground: {
+            radius: 1,
+            fill: 'rgba(0, 0, 0, 0.65)',
+            padding: [3, 5]
+          },
+          yTipTextStyle: {
+            fontSize: 12,
+            fill: '#fff',
+            textAlign: 'center',
+            textBaseline: 'middle'
+          },
+
+          /**
+           * the style for tooltip container's background
+           * @type {Object}
+           */
+          background: null,
+
+          /**
+           * layout, can be horizontal or vertical
+           * @type {String}
+           */
+          layout: 'horizontal',
+          offsetX: 0,
+          offsetY: 0
+        };
+      }
+
+      constructor(cfg) {
+        deepMix(this, this.getDefaultCfg(), cfg);
+        var {
+          frontPlot,
+          custom
+        } = this;
+
+        if (!custom) {
+          // custom means user do customize
+          var container = new List(mix({
+            parent: frontPlot,
+            zIndex: 3
+          }, cfg));
+          this.container = container;
+          var {
+            fixed,
+            background
+          } = this;
+
+          if (!fixed) {
+            this.tooltipArrow = frontPlot.addShape('Polygon', {
+              className: 'tooltip-arrow',
+              visible: false,
+              zIndex: 2,
+              attrs: mix({
+                points: []
+              }, background)
+            });
+          }
+        }
+
+        if (this.showXTip) {
+          var {
+            xTipBackground,
+            xTipTextStyle
+          } = this;
+          var xTipBox = new TextBox({
+            context: frontPlot.get('context'),
+            className: 'xTip',
+            background: xTipBackground,
+            textStyle: xTipTextStyle,
+            visible: false
+          });
+          frontPlot.add(xTipBox.container);
+          this.xTipBox = xTipBox;
+        }
+
+        if (this.showYTip) {
+          var {
+            yTipBackground,
+            yTipTextStyle
+          } = this;
+          var yTipBox = new TextBox({
+            context: frontPlot.get('context'),
+            className: 'yTip',
+            background: yTipBackground,
+            textStyle: yTipTextStyle,
+            visible: false
+          });
+          frontPlot.add(yTipBox.container);
+          this.yTipBox = yTipBox;
+        }
+
+        if (this.showCrosshairs) {
+          this._renderCrosshairs();
+        }
+
+        frontPlot.sort();
+      }
+
+      setContent(title, items) {
+        this.title = title;
+        this.items = items;
+
+        if (!this.custom) {
+          var container = this.container;
+          container.setTitle(title);
+          container.setItems(items);
+        }
+      }
+
+      setYTipContent(val) {
+        var yTip = this.yTip;
+
+        if (isFunction(yTip)) {
+          val = yTip(val);
+        } else {
+          val = mix({
+            text: val
+          }, yTip);
+        }
+
+        this.yTipBox && this.yTipBox.updateContent(val);
+      }
+
+      setYTipPosition(pos) {
+        var plotRange = this.plotRange;
+        var crosshairsShapeX = this.crosshairsShapeX;
+
+        if (this.showYTip) {
+          var yTipBox = this.yTipBox;
+          var yTipHeight = yTipBox.getHeight();
+          var yTipWidth = yTipBox.getWidth();
+          var posX = plotRange.tl.x - yTipWidth;
+          var posY = pos - yTipHeight / 2;
+
+          if (posY <= plotRange.tl.y) {
+            posY = plotRange.tl.y;
+          }
+
+          if (posY + yTipHeight >= plotRange.br.y) {
+            posY = plotRange.br.y - yTipHeight;
+          }
+
+          if (posX < 0) {
+            posX = plotRange.tl.x;
+            crosshairsShapeX && crosshairsShapeX.attr('x1', plotRange.tl.x + yTipWidth);
+          }
+
+          yTipBox.updatePosition(posX, posY);
+        }
+      }
+
+      setXTipContent(val) {
+        var xTip = this.xTip;
+
+        if (isFunction(xTip)) {
+          val = xTip(val);
+        } else {
+          val = mix({
+            text: val
+          }, xTip);
+        }
+
+        this.xTipBox && this.xTipBox.updateContent(val);
+      }
+
+      setXTipPosition(pos) {
+        var {
+          showXTip,
+          canvas,
+          plotRange,
+          xTipBox,
+          crosshairsShapeY
+        } = this;
+
+        if (showXTip) {
+          // const el = canvas.get('el');
+          // const canvasHeight = Util.getHeight(el);
+          var canvasHeight = canvas.get('height');
+          var xTipWidth = xTipBox.getWidth();
+          var xTipHeight = xTipBox.getHeight();
+          var posX = pos - xTipWidth / 2;
+          var posY = plotRange.br.y;
+
+          if (posX <= plotRange.tl.x) {
+            posX = plotRange.tl.x;
+          }
+
+          if (posX + xTipWidth >= plotRange.tr.x) {
+            posX = plotRange.tr.x - xTipWidth;
+          }
+
+          if (canvasHeight - posY < xTipHeight) {
+            posY -= xTipHeight;
+          }
+
+          xTipBox.updatePosition(posX, posY);
+          crosshairsShapeY && crosshairsShapeY.attr('y1', posY);
+        }
+      }
+
+      setXCrosshairPosition(pos) {
+        this.crosshairsShapeX && this.crosshairsShapeX.moveTo(0, pos);
+      }
+
+      setYCrosshairPosition(pos) {
+        this.crosshairsShapeY && this.crosshairsShapeY.moveTo(pos, 0);
+      }
+
+      setPosition(items) {
+        var {
+          container,
+          plotRange,
+          offsetX,
+          offsetY,
+          fixed,
+          tooltipArrow
+        } = this;
+
+        if (!container) {
+          return;
+        }
+
+        var containerBBox = container.container.getBBox();
+        var {
+          minX,
+          minY,
+          width,
+          height
+        } = containerBBox;
+        var {
+          tl,
+          tr
+        } = plotRange;
+        var posX = 0;
+        var posY = tl.y - height - GAP + offsetY;
+
+        if (fixed) {
+          var x = (tl.x + tr.x) / 2;
+          posX = x - width / 2 + offsetX;
+        } else {
+          var _x;
+
+          if (items.length > 1) {
+            _x = (items[0].x + items[items.length - 1].x) / 2;
+          } else {
+            _x = items[0].x;
+          }
+
+          posX = _x - width / 2 + offsetX;
+
+          if (posX < tl.x) {
+            posX = tl.x;
+          }
+
+          if (posX + width > tr.x) {
+            posX = tr.x - width;
+          }
+
+          if (tooltipArrow) {
+            tooltipArrow.attr('points', [{
+              x: _x - 3,
+              y: tl.y - GAP + offsetY
+            }, {
+              x: _x + 3,
+              y: tl.y - GAP + offsetY
+            }, {
+              x: _x,
+              y: tl.y + offsetY
+            }]);
+            var backShape = container.backShape;
+            var radius = parsePadding(backShape.attr('radius'));
+
+            if (_x === tl.x) {
+              radius[3] = 0;
+              tooltipArrow.attr('points', [{
+                x: tl.x,
+                y: tl.y + offsetY
+              }, {
+                x: tl.x,
+                y: tl.y - GAP + offsetY
+              }, {
+                x: tl.x + GAP,
+                y: tl.y - GAP + offsetY
+              }]);
+            } else if (_x === tr.x) {
+              radius[2] = 0;
+              tooltipArrow.attr('points', [{
+                x: tr.x,
+                y: tl.y + offsetY
+              }, {
+                x: tr.x - GAP,
+                y: tl.y - GAP + offsetY
+              }, {
+                x: tr.x,
+                y: tl.y - GAP + offsetY
+              }]);
+            }
+
+            backShape.attr('radius', radius);
+          }
+        }
+
+        container.moveTo(posX - minX, posY - minY);
+      }
+
+      setMarkers() {
+        var cfg = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
+        var self = this;
+        var {
+          items,
+          style,
+          type
+        } = cfg;
+
+        var markerGroup = self._getMarkerGroup(type);
+
+        if (type === 'circle') {
+          for (var i = 0, length = items.length; i < length; i++) {
+            var item = items[i];
+            var marker = new Marker({
+              className: 'tooltip-circle-marker',
+              attrs: mix({
+                x: item.x,
+                y: item.y,
+                stroke: item.color
+              }, style)
+            });
+            markerGroup.add(marker);
+          }
+        } else {
+          markerGroup.addShape('rect', {
+            className: 'tooltip-rect-marker',
+            attrs: style
+          });
+        }
+      }
+
+      clearMarkers() {
+        var markerGroup = this.markerGroup;
+        markerGroup && markerGroup.clear();
+      }
+
+      show() {
+        var crosshairsShapeX = this.crosshairsShapeX;
+        var crosshairsShapeY = this.crosshairsShapeY;
+        var markerGroup = this.markerGroup;
+        var container = this.container;
+        var tooltipArrow = this.tooltipArrow;
+        var xTipBox = this.xTipBox;
+        var yTipBox = this.yTipBox;
+        var canvas = this.canvas;
+        crosshairsShapeX && crosshairsShapeX.show();
+        crosshairsShapeY && crosshairsShapeY.show();
+        markerGroup && markerGroup.show();
+        container && container.show();
+        tooltipArrow && tooltipArrow.show();
+        xTipBox && xTipBox.show();
+        yTipBox && yTipBox.show();
+        canvas.draw();
+      }
+
+      hide() {
+        var crosshairsShapeX = this.crosshairsShapeX;
+        var crosshairsShapeY = this.crosshairsShapeY;
+        var markerGroup = this.markerGroup;
+        var container = this.container;
+        var tooltipArrow = this.tooltipArrow;
+        var xTipBox = this.xTipBox;
+        var yTipBox = this.yTipBox;
+        crosshairsShapeX && crosshairsShapeX.hide();
+        crosshairsShapeY && crosshairsShapeY.hide();
+        markerGroup && markerGroup.hide();
+        container && container.hide();
+        tooltipArrow && tooltipArrow.hide();
+        xTipBox && xTipBox.hide();
+        yTipBox && yTipBox.hide();
+      }
+
+      destroy() {
+        var crosshairsShapeX = this.crosshairsShapeX;
+        var crosshairsShapeY = this.crosshairsShapeY;
+        var markerGroup = this.markerGroup;
+        var container = this.container;
+        var tooltipArrow = this.tooltipArrow;
+        var xTipBox = this.xTipBox;
+        var yTipBox = this.yTipBox;
+        crosshairsShapeX && crosshairsShapeX.remove(true);
+        crosshairsShapeY && crosshairsShapeY.remove(true);
+        markerGroup && markerGroup.remove(true);
+        tooltipArrow && tooltipArrow.remove(true);
+        container && container.clear();
+        xTipBox && xTipBox.clear();
+        yTipBox && yTipBox.clear();
+        this.destroyed = true;
+      }
+
+      _getMarkerGroup(type) {
+        var markerGroup = this.markerGroup;
+
+        if (!markerGroup) {
+          if (type === 'circle') {
+            markerGroup = this.frontPlot.addGroup({
+              zIndex: 1
+            });
+            this.frontPlot.sort();
+          } else {
+            markerGroup = this.backPlot.addGroup();
+          }
+
+          this.markerGroup = markerGroup;
+        } else {
+          markerGroup.clear();
+        }
+
+        return markerGroup;
+      }
+
+      _renderCrosshairs() {
+        var {
+          crosshairsType,
+          crosshairsStyle,
+          frontPlot,
+          plotRange
+        } = this;
+        var {
+          tl,
+          br
+        } = plotRange;
+
+        if (directionEnabled(crosshairsType, 'x')) {
+          this.crosshairsShapeX = frontPlot.addShape('Line', {
+            className: 'tooltip-crosshairs-x',
+            zIndex: 0,
+            visible: false,
+            attrs: mix({
+              x1: tl.x,
+              y1: 0,
+              x2: br.x,
+              y2: 0
+            }, crosshairsStyle)
+          });
+        }
+
+        if (directionEnabled(crosshairsType, 'y')) {
+          this.crosshairsShapeY = frontPlot.addShape('Line', {
+            className: 'tooltip-crosshairs-y',
+            zIndex: 0,
+            visible: false,
+            attrs: mix({
+              x1: 0,
+              y1: br.y,
+              x2: 0,
+              y2: tl.y
+            }, crosshairsStyle)
+          });
+        }
+      }
+
+    }
+
+    function _defineProperty$2(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
+
+    Global.tooltip = deepMix({
+      triggerOn: 'press',
+      triggerOff: 'pressend',
+      alwaysShow: false,
+      showTitle: false,
+      showCrosshairs: false,
+      crosshairsStyle: {
+        stroke: 'rgba(0, 0, 0, 0.25)',
+        lineWidth: 1
+      },
+      showTooltipMarker: true,
+      background: {
+        radius: 1,
+        fill: 'rgba(0, 0, 0, 0.65)',
+        padding: [3, 5]
+      },
+      titleStyle: {
+        fontSize: 12,
+        fill: '#fff',
+        textAlign: 'start',
+        textBaseline: 'top'
+      },
+      nameStyle: {
+        fontSize: 12,
+        fill: 'rgba(255, 255, 255, 0.65)',
+        textAlign: 'start',
+        textBaseline: 'middle'
+      },
+      valueStyle: {
+        fontSize: 12,
+        fill: '#fff',
+        textAlign: 'start',
+        textBaseline: 'middle'
+      },
+      showItemMarker: true,
+      itemMarkerStyle: {
+        radius: 3,
+        symbol: 'circle',
+        lineWidth: 1,
+        stroke: '#fff'
+      },
+      layout: 'horizontal',
+      snap: false
+    }, Global.tooltip || {});
+
+    function _getTooltipValueScale(geom) {
+      var colorAttr = geom.getAttr('color');
+
+      if (colorAttr) {
+        var colorScale = colorAttr.getScale(colorAttr.type);
+
+        if (colorScale.isLinear) {
+          return colorScale;
+        }
+      }
+
+      var xScale = geom.getXScale();
+      var yScale = geom.getYScale();
+
+      if (yScale) {
+        return yScale;
+      }
+
+      return xScale;
+    }
+
+    function getTooltipName(geom, origin) {
+      var name;
+      var nameScale;
+
+      var groupScales = geom._getGroupScales();
+
+      if (groupScales.length) {
+        each(groupScales, function (scale) {
+          nameScale = scale;
+          return false;
+        });
+      }
+
+      if (nameScale) {
+        var field = nameScale.field;
+        name = nameScale.getText(origin[field]);
+      } else {
+        var valueScale = _getTooltipValueScale(geom);
+
+        name = valueScale.alias || valueScale.field;
+      }
+
+      return name;
+    }
+
+    function getTooltipValue(geom, origin) {
+      var scale = _getTooltipValueScale(geom);
+
+      return scale.getText(origin[scale.field]);
+    }
+
+    function getTooltipTitle(geom, origin) {
+      var position = geom.getAttr('position');
+      var field = position.getFields()[0];
+      var scale = geom.get('scales')[field];
+      return scale.getText(origin[scale.field]);
+    }
+
+    function _indexOfArray(items, item) {
+      var rst = -1;
+      each(items, function (sub, index) {
+        if (sub.title === item.title && sub.name === item.name && sub.value === item.value && sub.color === item.color) {
+          rst = index;
+          return false;
+        }
+      });
+      return rst;
+    }
+
+    function _uniqItems(items) {
+      var tmp = [];
+      each(items, function (item) {
+        var index = _indexOfArray(tmp, item);
+
+        if (index === -1) {
+          tmp.push(item);
+        } else {
+          tmp[index] = item;
+        }
+      });
+      return tmp;
+    }
+
+    function isEqual$1(arr1, arr2) {
+      return JSON.stringify(arr1) === JSON.stringify(arr2);
+    }
+
+    class TooltipController {
+      constructor(cfg) {
+        var _this = this;
+
+        _defineProperty$2(this, "handleShowEvent", function (ev) {
+          var chart = _this.chart;
+          if (!_this.enable) return;
+          var plot = chart.get('plotRange');
+          var point = createEvent(ev, chart);
+
+          if (!isPointInPlot(point, plot) && !_this._tooltipCfg.alwaysShow) {
+            // not in chart plot
+            _this.hideTooltip();
+
+            return;
+          }
+
+          var lastTimeStamp = _this.timeStamp;
+          var timeStamp = +new Date();
+
+          if (timeStamp - lastTimeStamp > 16) {
+            _this.showTooltip(point);
+
+            _this.timeStamp = timeStamp;
+          }
+        });
+
+        _defineProperty$2(this, "handleHideEvent", function () {
+          if (!_this.enable) return;
+
+          _this.hideTooltip();
+        });
+
+        this.enable = true;
+        this.cfg = {};
+        this.tooltip = null;
+        this.chart = null;
+        this.timeStamp = 0;
+        mix(this, cfg);
+        var _chart = this.chart;
+
+        var canvas = _chart.get('canvas');
+
+        this.canvas = canvas;
+        this.canvasDom = canvas.get('el');
+      }
+
+      _setCrosshairsCfg() {
+        var self = this;
+        var chart = self.chart;
+        var defaultCfg = mix({}, Global.tooltip);
+        var geoms = chart.get('geoms');
+        var shapes = [];
+        each(geoms, function (geom) {
+          var type = geom.get('type');
+
+          if (shapes.indexOf(type) === -1) {
+            shapes.push(type);
+          }
+        });
+        var coordType = chart.get('coord').type;
+
+        if (geoms.length && (coordType === 'cartesian' || coordType === 'rect')) {
+          if (shapes.length === 1 && ['line', 'area', 'path', 'point'].indexOf(shapes[0]) !== -1) {
+            mix(defaultCfg, {
+              showCrosshairs: true
+            });
+          }
+        }
+
+        return defaultCfg;
+      }
+
+      _getMaxLength() {
+        var cfg = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
+        var {
+          layout,
+          plotRange
+        } = cfg;
+        return layout === 'horizontal' ? plotRange.br.x - plotRange.bl.x : plotRange.bl.y - plotRange.tr.y;
+      }
+
+      render() {
+        var self = this;
+
+        if (self.tooltip) {
+          return;
+        }
+
+        var chart = self.chart;
+        var canvas = chart.get('canvas');
+        var frontPlot = chart.get('frontPlot').addGroup({
+          className: 'tooltipContainer',
+          zIndex: 10
+        });
+        var backPlot = chart.get('backPlot').addGroup({
+          className: 'tooltipContainer'
+        });
+        var plotRange = chart.get('plotRange');
+        var coord = chart.get('coord');
+
+        var defaultCfg = self._setCrosshairsCfg();
+
+        var cfg = self.cfg; // 通过 chart.tooltip() 接口传入的 tooltip 配置项
+
+        var tooltipCfg = deepMix({
+          plotRange,
+          frontPlot,
+          backPlot,
+          canvas,
+          fixed: coord.transposed || coord.isPolar
+        }, defaultCfg, cfg); // 创建 tooltip 实例需要的配置,不应该修改 this.cfg,即用户传入的配置
+
+        tooltipCfg.maxLength = self._getMaxLength(tooltipCfg);
+        this._tooltipCfg = tooltipCfg;
+        var tooltip = new Tooltip(tooltipCfg);
+        self.tooltip = tooltip; // 需要保持tooltip一直显示
+
+        if (tooltipCfg.alwaysShow && self.prePoint) {
+          this.showTooltip(self.prePoint);
+        }
+
+        self.bindEvents();
+      }
+
+      clear() {
+        var tooltip = this.tooltip;
+
+        if (tooltip) {
+          tooltip.destroy();
+          this.unBindEvents();
+        }
+
+        this.tooltip = null;
+        this._lastActive = null;
+      }
+
+      _getTooltipMarkerStyle() {
+        var cfg = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
+        var {
+          type,
+          items
+        } = cfg;
+        var tooltipCfg = this._tooltipCfg;
+
+        if (type === 'rect') {
+          var x;
+          var y;
+          var width;
+          var height;
+          var chart = this.chart;
+          var {
+            tl,
+            br
+          } = chart.get('plotRange');
+          var coord = chart.get('coord');
+          var firstItem = items[0];
+          var lastItem = items[items.length - 1];
+          var intervalWidth = firstItem.width;
+
+          if (coord.transposed) {
+            x = tl.x;
+            y = lastItem.y - intervalWidth * 0.75;
+            width = br.x - tl.x;
+            height = firstItem.y - lastItem.y + 1.5 * intervalWidth;
+          } else {
+            x = firstItem.x - intervalWidth * 0.75;
+            y = tl.y;
+            width = lastItem.x - firstItem.x + 1.5 * intervalWidth;
+            height = br.y - tl.y;
+          }
+
+          cfg.style = mix({
+            x,
+            y,
+            width,
+            height,
+            fill: '#CCD6EC',
+            opacity: 0.3
+          }, tooltipCfg.tooltipMarkerStyle);
+        } else {
+          cfg.style = mix({
+            radius: 4,
+            fill: '#fff',
+            lineWidth: 2
+          }, tooltipCfg.tooltipMarkerStyle);
+        }
+
+        return cfg;
+      }
+
+      _setTooltip(point, items) {
+        var tooltipMarkerCfg = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
+        this.prePoint = point;
+        var lastActive = this._lastActive;
+        var tooltip = this.tooltip;
+        var cfg = this._tooltipCfg;
+        items = _uniqItems(items);
+        var chart = this.chart;
+        var coord = chart.get('coord');
+        var yScale = chart.getYScales()[0];
+        var snap = cfg.snap;
+
+        if (snap === false && yScale.isLinear) {
+          var invertPoint = coord.invertPoint(point);
+          var plot = chart.get('plotRange');
+          var tip;
+          var pos;
+
+          if (isPointInPlot(point, plot)) {
+            if (coord.transposed) {
+              tip = yScale.invert(invertPoint.x);
+              pos = point.x;
+              tooltip.setXTipContent(tip);
+              tooltip.setXTipPosition(pos);
+              tooltip.setYCrosshairPosition(pos);
+            } else {
+              tip = yScale.invert(invertPoint.y);
+              pos = point.y;
+              tooltip.setYTipContent(tip);
+              tooltip.setYTipPosition(pos);
+              tooltip.setXCrosshairPosition(pos);
+            }
+          }
+        }
+
+        if (cfg.onShow) {
+          cfg.onShow({
+            x: point.x,
+            y: point.y,
+            tooltip,
+            items,
+            tooltipMarkerCfg
+          });
+        }
+
+        if (isEqual$1(lastActive, items)) {
+          if (snap === false && (directionEnabled(cfg.crosshairsType, 'y') || cfg.showYTip)) {
+            var canvas = this.chart.get('canvas');
+            canvas.draw();
+          }
+
+          return;
+        }
+
+        this._lastActive = items;
+        var onChange = cfg.onChange;
+
+        if (onChange) {
+          onChange({
+            x: point.x,
+            y: point.y,
+            tooltip,
+            items,
+            tooltipMarkerCfg
+          });
+        }
+
+        var first = items[0];
+        var title = first.title || first.name;
+        var xTipPosX = first.x;
+
+        if (items.length > 1) {
+          xTipPosX = (items[0].x + items[items.length - 1].x) / 2;
+        }
+
+        tooltip.setContent(title, items, coord.transposed);
+        tooltip.setPosition(items, point);
+
+        if (coord.transposed) {
+          var yTipPosY = first.y;
+
+          if (items.length > 1) {
+            yTipPosY = (items[0].y + items[items.length - 1].y) / 2;
+          }
+
+          tooltip.setYTipContent(title);
+          tooltip.setYTipPosition(yTipPosY);
+          tooltip.setXCrosshairPosition(yTipPosY);
+
+          if (snap) {
+            tooltip.setXTipContent(first.value);
+            tooltip.setXTipPosition(xTipPosX);
+            tooltip.setYCrosshairPosition(xTipPosX);
+          }
+        } else {
+          tooltip.setXTipContent(title);
+          tooltip.setXTipPosition(xTipPosX);
+          tooltip.setYCrosshairPosition(xTipPosX);
+
+          if (snap) {
+            tooltip.setYTipContent(first.value);
+            tooltip.setYTipPosition(first.y);
+            tooltip.setXCrosshairPosition(first.y);
+          }
+        }
+
+        var markerItems = tooltipMarkerCfg.items;
+
+        if (cfg.showTooltipMarker && markerItems.length) {
+          tooltipMarkerCfg = this._getTooltipMarkerStyle(tooltipMarkerCfg);
+          tooltip.setMarkers(tooltipMarkerCfg);
+        } else {
+          tooltip.clearMarkers();
+        }
+
+        tooltip.show();
+      }
+
+      showTooltip(point) {
+        var self = this;
+        var chart = self.chart;
+        var tooltipMarkerType;
+        var tooltipMarkerItems = [];
+        var items = [];
+        var cfg = self._tooltipCfg;
+        var {
+          showItemMarker,
+          itemMarkerStyle,
+          alwaysShow
+        } = cfg;
+        var marker;
+
+        if (showItemMarker) {
+          marker = itemMarkerStyle;
+        }
+
+        var geoms = chart.get('geoms');
+        var coord = chart.get('coord');
+        each(geoms, function (geom) {
+          if (geom.get('visible')) {
+            var type = geom.get('type');
+            var records = geom.getSnapRecords(point);
+            var adjust = geom.get('adjust'); // 漏斗图和金子塔图tooltip位置有问题,暂时不开放显示
+
+            if (type === 'interval' && adjust && adjust.type === 'symmetric') {
+              return;
+            }
+
+            each(records, function (record) {
+              if (record.x && record.y) {
+                var {
+                  x,
+                  y,
+                  _origin,
+                  color
+                } = record;
+                var tooltipItem = {
+                  x,
+                  y: isArray(y) ? y[1] : y,
+                  color: color || Global.defaultColor,
+                  origin: _origin,
+                  name: getTooltipName(geom, _origin),
+                  value: getTooltipValue(geom, _origin),
+                  title: getTooltipTitle(geom, _origin)
+                };
+
+                if (marker) {
+                  tooltipItem.marker = mix({
+                    fill: color || Global.defaultColor
+                  }, marker);
+                }
+
+                items.push(tooltipItem);
+
+                if (['line', 'area', 'path'].indexOf(type) !== -1) {
+                  tooltipMarkerType = 'circle';
+                  tooltipMarkerItems.push(tooltipItem);
+                } else if (type === 'interval' && (coord.type === 'cartesian' || coord.type === 'rect')) {
+                  tooltipMarkerType = 'rect';
+                  tooltipItem.width = geom.getSize(record._origin);
+                  tooltipMarkerItems.push(tooltipItem);
+                }
+              }
+            });
+          }
+        });
+
+        if (items.length) {
+          var tooltipMarkerCfg = {
+            items: tooltipMarkerItems,
+            type: tooltipMarkerType
+          };
+
+          self._setTooltip(point, items, tooltipMarkerCfg);
+
+          return;
+        }
+
+        if (!alwaysShow) {
+          self.hideTooltip();
+        }
+      }
+
+      hideTooltip() {
+        var cfg = this._tooltipCfg;
+        this._lastActive = null;
+        var tooltip = this.tooltip;
+
+        if (tooltip) {
+          tooltip.hide();
+
+          if (cfg.onHide) {
+            cfg.onHide({
+              tooltip
+            });
+          }
+
+          var canvas = this.chart.get('canvas');
+          canvas.draw();
+        }
+      }
+
+      _handleEvent(methodName, method, action) {
+        var canvas = this.canvas;
+        each([].concat(methodName), function (aMethod) {
+          if (action === 'bind') {
+            canvas.on(aMethod, method);
+          } else {
+            canvas.off(aMethod, method);
+          }
+        });
+      }
+
+      bindEvents() {
+        var cfg = this._tooltipCfg;
+        var {
+          triggerOn,
+          triggerOff,
+          alwaysShow
+        } = cfg;
+        triggerOn && this._handleEvent(triggerOn, this.handleShowEvent, 'bind'); // 如果 !alwaysShow, 则在手势离开后就隐藏
+
+        if (!alwaysShow) {
+          this._handleEvent(triggerOff, this.handleHideEvent, 'bind');
+        }
+      }
+
+      unBindEvents() {
+        var cfg = this._tooltipCfg;
+        var {
+          triggerOn,
+          triggerOff,
+          alwaysShow
+        } = cfg;
+        triggerOn && this._handleEvent(triggerOn, this.handleShowEvent, 'unBind');
+
+        if (!alwaysShow) {
+          this._handleEvent(triggerOff, this.handleHideEvent, 'unBind');
+        }
+      }
+
+    }
+
+    function init(chart) {
+      var tooltipController = new TooltipController({
+        chart
+      });
+      chart.set('tooltipController', tooltipController);
+
+      chart.tooltip = function (enable, cfg) {
+        if (isObject(enable)) {
+          cfg = enable;
+          enable = true;
+        }
+
+        tooltipController.enable = enable;
+
+        if (cfg) {
+          tooltipController.cfg = cfg;
+        }
+
+        return this;
+      };
+    }
+
+    function afterGeomDraw(chart) {
+      var tooltipController = chart.get('tooltipController');
+      tooltipController.render();
+
+      chart.showTooltip = function (point) {
+        tooltipController.showTooltip(point);
+        return this;
+      };
+
+      chart.hideTooltip = function () {
+        tooltipController.hideTooltip();
+        return this;
+      };
+    }
+
+    function clearInner(chart) {
+      var tooltipController = chart.get('tooltipController');
+      tooltipController.clear();
+    }
+    var tooltip = {
+      init,
+      afterGeomDraw,
+      clearInner
+    };
+
+    var Tooltip$1 = /*#__PURE__*/Object.freeze({
+        __proto__: null,
+        init: init,
+        afterGeomDraw: afterGeomDraw,
+        clearInner: clearInner,
+        'default': tooltip
+    });
+
+    Global.guide = deepMix({
+      line: {
+        style: {
+          stroke: '#a3a3a3',
+          lineWidth: 1
+        },
+        top: true
+      },
+      text: {
+        style: {
+          fill: '#787878',
+          textAlign: 'center',
+          textBaseline: 'middle'
+        },
+        offsetX: 0,
+        offsetY: 0,
+        top: true
+      },
+      rect: {
+        style: {
+          fill: '#fafafa'
+        },
+        top: false
+      },
+      arc: {
+        style: {
+          stroke: '#a3a3a3'
+        },
+        top: true
+      },
+      html: {
+        offsetX: 0,
+        offsetY: 0,
+        alignX: 'center',
+        alignY: 'middle'
+      },
+      tag: {
+        top: true,
+        offsetX: 0,
+        offsetY: 0,
+        side: 4,
+        background: {
+          padding: 5,
+          radius: 2,
+          fill: '#1890FF'
+        },
+        textStyle: {
+          fontSize: 12,
+          fill: '#fff',
+          textAlign: 'center',
+          textBaseline: 'middle'
+        }
+      },
+      point: {
+        top: true,
+        offsetX: 0,
+        offsetY: 0,
+        style: {
+          fill: '#fff',
+          r: 3,
+          lineWidth: 2,
+          stroke: '#1890ff'
+        }
+      }
+    }, Global.guide || {});
+
+    class GuideController {
+      constructor(cfg) {
+        this.guides = [];
+        this.xScale = null;
+        this.yScales = null;
+        this.guideShapes = [];
+        mix(this, cfg);
+      }
+
+      _toString(position) {
+        if (isFunction(position)) {
+          position = position(this.xScale, this.yScales);
+        }
+
+        position = position.toString();
+        return position;
+      }
+
+      _getId(shape, guide) {
+        var id = guide.id;
+
+        if (!id) {
+          var type = guide.type;
+
+          if (type === 'arc' || type === 'line' || type === 'rect') {
+            id = this._toString(guide.start) + '-' + this._toString(guide.end);
+          } else {
+            id = this._toString(guide.position);
+          }
+        }
+
+        return id;
+      }
+
+      paint(coord) {
+        var self = this;
+        var {
+          chart,
+          guides,
+          xScale,
+          yScales
+        } = self;
+        var guideShapes = [];
+        each(guides, function (guide, idx) {
+          guide.xScale = xScale;
+          guide.yScales = yScales;
+          var container;
+
+          if (guide.type === 'regionFilter') {
+            // TODO: RegionFilter support animation
+            guide.chart = chart;
+          } else {
+            container = guide.top ? self.frontPlot : self.backPlot;
+          }
+
+          guide.coord = coord;
+          guide.container = container;
+          guide.canvas = chart.get('canvas');
+          var shape = guide.render(coord, container);
+
+          if (shape) {
+            var id = self._getId(shape, guide);
+
+            [].concat(shape).forEach(function (s) {
+              s._id = s.get('className') + '-' + id;
+              s.set('index', idx);
+              guideShapes.push(s);
+            });
+          }
+        });
+        self.guideShapes = guideShapes;
+      }
+
+      clear() {
+        this.reset();
+        this.guides = [];
+        return this;
+      }
+
+      reset() {
+        var guides = this.guides;
+        each(guides, function (guide) {
+          guide.remove();
+        });
+      }
+
+      _createGuide(type, cfg) {
+        var ClassName = upperFirst(type);
+        var guide = new GuideBase[ClassName](deepMix({}, Global.guide[type], cfg));
+        this.guides.push(guide);
+        return guide;
+      }
+
+      line() {
+        var cfg = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
+        return this._createGuide('line', cfg);
+      }
+
+      text() {
+        var cfg = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
+        return this._createGuide('text', cfg);
+      }
+
+      arc() {
+        var cfg = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
+        return this._createGuide('arc', cfg);
+      }
+
+      html() {
+        var cfg = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
+        return this._createGuide('html', cfg);
+      }
+
+      rect() {
+        var cfg = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
+        return this._createGuide('rect', cfg);
+      }
+
+      tag() {
+        var cfg = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
+        return this._createGuide('tag', cfg);
+      }
+
+      point() {
+        var cfg = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
+        return this._createGuide('point', cfg);
+      }
+
+      regionFilter() {
+        var cfg = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
+        return this._createGuide('regionFilter', cfg);
+      }
+
+    }
+
+    function init$1(chart) {
+      var guideController = new GuideController({
+        frontPlot: chart.get('frontPlot').addGroup({
+          zIndex: 20,
+          className: 'guideContainer'
+        }),
+        backPlot: chart.get('backPlot').addGroup({
+          className: 'guideContainer'
+        })
+      });
+      chart.set('guideController', guideController);
+      /**
+       * 为图表添加 guide
+       * @return {GuideController} 返回 guide 控制器
+       */
+
+      chart.guide = function () {
+        return guideController;
+      };
+    }
+
+    function afterGeomDraw$1(chart) {
+      var guideController = chart.get('guideController');
+
+      if (!guideController.guides.length) {
+        return;
+      }
+
+      var xScale = chart.getXScale();
+      var yScales = chart.getYScales();
+      var coord = chart.get('coord');
+      guideController.xScale = xScale;
+      guideController.yScales = yScales;
+      guideController.chart = chart; // for regionFilter
+
+      guideController.paint(coord);
+    }
+
+    function clear(chart) {
+      chart.get('guideController').clear();
+    }
+
+    function repaint(chart) {
+      chart.get('guideController').reset();
+    }
+    var guide = {
+      init: init$1,
+      afterGeomDraw: afterGeomDraw$1,
+      clear,
+      repaint
+    };
+
+    var Guide = /*#__PURE__*/Object.freeze({
+        __proto__: null,
+        init: init$1,
+        afterGeomDraw: afterGeomDraw$1,
+        clear: clear,
+        repaint: repaint,
+        'default': guide
+    });
+
+    function _defineProperty$3(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
+    var LEGEND_GAP = 12;
+    var MARKER_SIZE = 3;
+    var DEFAULT_CFG = {
+      itemMarginBottom: 12,
+      itemGap: 10,
+      showTitle: false,
+      titleStyle: {
+        fontSize: 12,
+        fill: '#808080',
+        textAlign: 'start',
+        textBaseline: 'top'
+      },
+      nameStyle: {
+        fill: '#808080',
+        fontSize: 12,
+        textAlign: 'start',
+        textBaseline: 'middle'
+      },
+      valueStyle: {
+        fill: '#000000',
+        fontSize: 12,
+        textAlign: 'start',
+        textBaseline: 'middle'
+      },
+      unCheckStyle: {
+        fill: '#bfbfbf'
+      },
+      itemWidth: 'auto',
+      wordSpace: 6,
+      selectedMode: 'multiple' // 'multiple' or 'single'
+
+    }; // Register the default configuration for Legend
+
+    Global.legend = deepMix({
+      common: DEFAULT_CFG,
+      // common legend configuration
+      right: mix({
+        position: 'right',
+        layout: 'vertical'
+      }, DEFAULT_CFG),
+      left: mix({
+        position: 'left',
+        layout: 'vertical'
+      }, DEFAULT_CFG),
+      top: mix({
+        position: 'top',
+        layout: 'horizontal'
+      }, DEFAULT_CFG),
+      bottom: mix({
+        position: 'bottom',
+        layout: 'horizontal'
+      }, DEFAULT_CFG)
+    }, Global.legend || {});
+
+    function getPaddingByPos(pos, appendPadding) {
+      var padding = 0;
+      appendPadding = parsePadding(appendPadding);
+
+      switch (pos) {
+        case 'top':
+          padding = appendPadding[0];
+          break;
+
+        case 'right':
+          padding = appendPadding[1];
+          break;
+
+        case 'bottom':
+          padding = appendPadding[2];
+          break;
+
+        case 'left':
+          padding = appendPadding[3];
+          break;
+      }
+
+      return padding;
+    }
+
+    class LegendController {
+      constructor(cfg) {
+        var _this = this;
+
+        _defineProperty$3(this, "handleEvent", function (ev) {
+          var self = _this;
+
+          function findItem(x, y) {
+            var result = null;
+            var legends = self.legends;
+            each(legends, function (legendItems) {
+              each(legendItems, function (legend) {
+                var {
+                  itemsGroup,
+                  legendHitBoxes
+                } = legend;
+                var children = itemsGroup.get('children');
+
+                if (children.length) {
+                  var legendPosX = legend.x;
+                  var legendPosY = legend.y;
+                  each(legendHitBoxes, function (box, index) {
+                    if (x >= box.x + legendPosX && x <= box.x + box.width + legendPosX && y >= box.y + legendPosY && y <= box.height + box.y + legendPosY) {
+                      // inbox
+                      result = {
+                        clickedItem: children[index],
+                        clickedLegend: legend
+                      };
+                      return false;
+                    }
+                  });
+                }
+              });
+            });
+            return result;
+          }
+
+          var chart = self.chart;
+          var {
+            x,
+            y
+          } = createEvent(ev, chart);
+          var clicked = findItem(x, y);
+
+          if (clicked && clicked.clickedLegend.clickable !== false) {
+            var {
+              clickedItem,
+              clickedLegend
+            } = clicked;
+
+            if (clickedLegend.onClick) {
+              ev.clickedItem = clickedItem;
+              clickedLegend.onClick(ev);
+            } else if (!clickedLegend.custom) {
+              var checked = clickedItem.get('checked');
+              var value = clickedItem.get('dataValue');
+              var {
+                filteredVals,
+                field,
+                selectedMode
+              } = clickedLegend;
+              var isSingeSelected = selectedMode === 'single';
+
+              if (isSingeSelected) {
+                chart.filter(field, function (val) {
+                  return val === value;
+                });
+              } else {
+                if (checked) {
+                  filteredVals.push(value);
+                } else {
+                  remove$1(filteredVals, value);
+                }
+
+                chart.filter(field, function (val) {
+                  return filteredVals.indexOf(val) === -1;
+                });
+              }
+
+              chart.repaint();
+            }
+          }
+        });
+
+        this.legendCfg = {};
+        this.enable = true;
+        this.position = 'top';
+        mix(this, cfg);
+        var _chart = this.chart;
+        this.canvasDom = _chart.get('canvas').get('el');
+        this.clear();
+      }
+
+      addLegend(scale, items, filteredVals) {
+        var self = this;
+        var legendCfg = self.legendCfg;
+        var field = scale.field;
+        var fieldCfg = legendCfg[field];
+
+        if (fieldCfg === false) {
+          return null;
+        }
+
+        if (fieldCfg && fieldCfg.custom) {
+          self.addCustomLegend(field);
+        } else {
+          var position = legendCfg.position || self.position;
+
+          if (fieldCfg && fieldCfg.position) {
+            position = fieldCfg.position;
+          }
+
+          if (scale.isCategory) {
+            self._addCategoryLegend(scale, items, position, filteredVals);
+          }
+        }
+      }
+
+      addCustomLegend(field) {
+        var self = this;
+        var legendCfg = self.legendCfg;
+
+        if (field && legendCfg[field]) {
+          legendCfg = legendCfg[field];
+        }
+
+        var position = legendCfg.position || self.position;
+        var legends = self.legends;
+        legends[position] = legends[position] || [];
+        var items = legendCfg.items;
+
+        if (!items) {
+          return null;
+        }
+
+        var container = self.container;
+        each(items, function (item) {
+          if (!isPlainObject(item.marker)) {
+            item.marker = {
+              symbol: item.marker || 'circle',
+              fill: item.fill,
+              radius: MARKER_SIZE
+            };
+          } else {
+            item.marker.radius = item.marker.radius || MARKER_SIZE;
+          }
+
+          item.checked = isNil(item.checked) ? true : item.checked;
+          item.name = item.name || item.value;
+        });
+        var legend = new List(deepMix({}, Global.legend[position], legendCfg, {
+          maxLength: self._getMaxLength(position),
+          items,
+          parent: container
+        }));
+        legends[position].push(legend);
+      }
+
+      clear() {
+        var legends = this.legends;
+        each(legends, function (legendItems) {
+          each(legendItems, function (legend) {
+            legend.clear();
+          });
+        });
+        this.legends = {};
+        this.unBindEvents();
+      }
+
+      _isFiltered(scale, values, value) {
+        var rst = false;
+        each(values, function (val) {
+          rst = rst || scale.getText(val) === scale.getText(value);
+
+          if (rst) {
+            return false;
+          }
+        });
+        return rst;
+      }
+
+      _getMaxLength(position) {
+        var chart = this.chart;
+        var appendPadding = parsePadding(chart.get('appendPadding'));
+        return position === 'right' || position === 'left' ? chart.get('height') - (appendPadding[0] + appendPadding[2]) : chart.get('width') - (appendPadding[1] + appendPadding[3]);
+      }
+
+      _addCategoryLegend(scale, items, position, filteredVals) {
+        var self = this;
+        var {
+          legendCfg,
+          legends,
+          container,
+          chart
+        } = self;
+        var field = scale.field;
+        legends[position] = legends[position] || [];
+        var symbol = 'circle';
+
+        if (legendCfg[field] && legendCfg[field].marker) {
+          symbol = legendCfg[field].marker;
+        } else if (legendCfg.marker) {
+          symbol = legendCfg.marker;
+        }
+
+        each(items, function (item) {
+          if (isPlainObject(symbol)) {
+            mix(item.marker, symbol);
+          } else {
+            item.marker.symbol = symbol;
+          }
+
+          if (filteredVals) {
+            item.checked = !self._isFiltered(scale, filteredVals, item.dataValue);
+          }
+        });
+        var legendItems = chart.get('legendItems');
+        legendItems[field] = items;
+        var lastCfg = deepMix({}, Global.legend[position], legendCfg[field] || legendCfg, {
+          maxLength: self._getMaxLength(position),
+          items,
+          field,
+          filteredVals,
+          parent: container
+        });
+
+        if (lastCfg.showTitle) {
+          deepMix(lastCfg, {
+            title: scale.alias || scale.field
+          });
+        }
+
+        var legend = new List(lastCfg);
+        legends[position].push(legend);
+        return legend;
+      }
+
+      _alignLegend(legend, pre, position) {
+        var self = this;
+        var {
+          tl,
+          bl
+        } = self.plotRange;
+        var chart = self.chart;
+        var offsetX = legend.offsetX || 0;
+        var offsetY = legend.offsetY || 0;
+        var chartWidth = chart.get('width');
+        var chartHeight = chart.get('height');
+        var appendPadding = parsePadding(chart.get('appendPadding'));
+        var legendHeight = legend.getHeight();
+        var legendWidth = legend.getWidth();
+        var x = 0;
+        var y = 0;
+
+        if (position === 'left' || position === 'right') {
+          var verticalAlign = legend.verticalAlign || 'middle';
+          var height = Math.abs(tl.y - bl.y);
+          x = position === 'left' ? appendPadding[3] : chartWidth - legendWidth - appendPadding[1];
+          y = (height - legendHeight) / 2 + tl.y;
+
+          if (verticalAlign === 'top') {
+            y = tl.y;
+          } else if (verticalAlign === 'bottom') {
+            y = bl.y - legendHeight;
+          }
+
+          if (pre) {
+            y = pre.get('y') - legendHeight - LEGEND_GAP;
+          }
+        } else {
+          var align = legend.align || 'left';
+          x = appendPadding[3];
+
+          if (align === 'center') {
+            x = chartWidth / 2 - legendWidth / 2;
+          } else if (align === 'right') {
+            x = chartWidth - (legendWidth + appendPadding[1]);
+          }
+
+          y = position === 'top' ? appendPadding[0] + Math.abs(legend.container.getBBox().minY) : chartHeight - legendHeight;
+
+          if (pre) {
+            var preWidth = pre.getWidth();
+            x = pre.x + preWidth + LEGEND_GAP;
+          }
+        }
+
+        if (position === 'bottom' && offsetY > 0) {
+          offsetY = 0;
+        }
+
+        if (position === 'right' && offsetX > 0) {
+          offsetX = 0;
+        }
+
+        legend.moveTo(x + offsetX, y + offsetY);
+      }
+
+      alignLegends() {
+        var self = this;
+        var legends = self.legends;
+        each(legends, function (legendItems, position) {
+          each(legendItems, function (legend, index) {
+            var pre = legendItems[index - 1];
+
+            self._alignLegend(legend, pre, position);
+          });
+        });
+        return self;
+      }
+
+      bindEvents() {
+        var legendCfg = this.legendCfg;
+        var triggerOn = legendCfg.triggerOn || 'touchstart';
+        addEventListener(this.canvasDom, triggerOn, this.handleEvent);
+      }
+
+      unBindEvents() {
+        var legendCfg = this.legendCfg;
+        var triggerOn = legendCfg.triggerOn || 'touchstart';
+        removeEventListener(this.canvasDom, triggerOn, this.handleEvent);
+      }
+
+    }
+
+    function init$2(chart) {
+      var legendController = new LegendController({
+        container: chart.get('backPlot'),
+        plotRange: chart.get('plotRange'),
+        chart
+      });
+      chart.set('legendController', legendController);
+
+      chart.legend = function (field, cfg) {
+        var legendCfg = legendController.legendCfg;
+        legendController.enable = true;
+
+        if (isBoolean(field)) {
+          legendController.enable = field;
+          legendCfg = cfg || {};
+        } else if (isObject(field)) {
+          legendCfg = field;
+        } else {
+          legendCfg[field] = cfg;
+        }
+
+        legendController.legendCfg = legendCfg;
+        return this;
+      };
+    }
+
+    function beforeGeomDraw(chart) {
+      var legendController = chart.get('legendController');
+      if (!legendController.enable) return null; // legend is not displayed
+
+      var legendCfg = legendController.legendCfg;
+
+      if (legendCfg && legendCfg.custom) {
+        legendController.addCustomLegend();
+      } else {
+        var legendItems = chart.getLegendItems();
+        var scales = chart.get('scales');
+        var filters = chart.get('filters');
+        each(legendItems, function (items, field) {
+          var scale = scales[field];
+          var values = scale.values;
+          var filteredVals;
+
+          if (filters && filters[field]) {
+            filteredVals = values.filter(function (v) {
+              return !filters[field](v);
+            });
+          } else {
+            filteredVals = [];
+          }
+
+          legendController.addLegend(scale, items, filteredVals);
+        });
+      }
+
+      if (legendCfg && legendCfg.clickable !== false) {
+        legendController.bindEvents();
+      }
+
+      var legends = legendController.legends;
+      var legendRange = {
+        top: 0,
+        right: 0,
+        bottom: 0,
+        left: 0
+      };
+      each(legends, function (legendItems, position) {
+        var padding = 0;
+        each(legendItems, function (legend) {
+          var width = legend.getWidth();
+          var height = legend.getHeight();
+
+          if (position === 'top' || position === 'bottom') {
+            padding = Math.max(padding, height);
+
+            if (legend.offsetY > 0) {
+              padding += legend.offsetY;
+            }
+          } else {
+            padding = Math.max(padding, width);
+
+            if (legend.offsetX > 0) {
+              padding += legend.offsetX;
+            }
+          }
+        });
+        legendRange[position] = padding + getPaddingByPos(position, chart.get('appendPadding'));
+      });
+      chart.set('legendRange', legendRange);
+    }
+
+    function afterGeomDraw$2(chart) {
+      var legendController = chart.get('legendController');
+      legendController.alignLegends();
+    }
+
+    function clearInner$1(chart) {
+      var legendController = chart.get('legendController');
+      legendController.clear();
+      chart.set('legendRange', null);
+    }
+    var legend = {
+      init: init$2,
+      beforeGeomDraw,
+      afterGeomDraw: afterGeomDraw$2,
+      clearInner: clearInner$1
+    };
+
+    var Legend = /*#__PURE__*/Object.freeze({
+        __proto__: null,
+        init: init$2,
+        beforeGeomDraw: beforeGeomDraw,
+        afterGeomDraw: afterGeomDraw$2,
+        clearInner: clearInner$1,
+        'default': legend
+    });
+
+    var clock = typeof performance === 'object' && performance.now ? performance : Date;
+
+    class Timeline {
+      constructor() {
+        this.anims = [];
+        this.time = null;
+        this.playing = false;
+        this.canvas = [];
+      }
+
+      play() {
+        var self = this;
+        self.time = clock.now();
+        self.playing = true;
+
+        function step() {
+          if (self.playing) {
+            requestAnimationFrame$1(step);
+            self.update();
+          }
+        }
+
+        requestAnimationFrame$1(step);
+      }
+
+      stop() {
+        this.playing = false;
+        this.time = null;
+        this.canvas = [];
+      }
+
+      pushAnim(animInfo) {
+        this.anims.push(animInfo);
+
+        if (this.playing) {
+          return;
+        }
+
+        this.play();
+      }
+
+      update() {
+        var currentTime = clock.now();
+        this.canvas = [];
+
+        if (!this.anims.length) {
+          this.stop();
+          return;
+        }
+
+        for (var i = 0; i < this.anims.length; i++) {
+          var propertyAnim = this.anims[i];
+
+          if (currentTime < propertyAnim.startTime || propertyAnim.hasEnded) {
+            continue;
+          }
+
+          var shape = propertyAnim.shape; // shape
+
+          if (shape.get('destroyed')) {
+            this.anims.splice(i, 1);
+            i--;
+            continue;
+          }
+
+          var {
+            startState,
+            endState,
+            interpolate,
+            duration
+          } = propertyAnim;
+
+          if (currentTime >= propertyAnim.startTime && !propertyAnim.hasStarted) {
+            propertyAnim.hasStarted = true;
+
+            if (propertyAnim.onStart) {
+              propertyAnim.onStart();
+            }
+          }
+
+          var t = (currentTime - propertyAnim.startTime) / duration;
+          t = Math.max(0, Math.min(t, 1));
+          t = propertyAnim.easing(t);
+
+          if (propertyAnim.onFrame) {
+            propertyAnim.onFrame(t);
+          } else {
+            for (var key in interpolate) {
+              var diff = interpolate[key];
+              var value = diff(t);
+              var newValue = void 0;
+
+              if (key === 'points') {
+                newValue = [];
+                var aLen = Math.max(startState.points.length, endState.points.length);
+
+                for (var j = 0; j < aLen; j += 2) {
+                  newValue.push({
+                    x: value[j],
+                    y: value[j + 1]
+                  });
+                }
+              } else {
+                newValue = value;
+              }
+
+              shape._attrs.attrs[key] = newValue;
+              shape._attrs.bbox = null; // should clear calculated bbox
+            }
+          }
+
+          var canvas = shape.get('canvas');
+
+          if (this.canvas.indexOf(canvas) === -1) {
+            this.canvas.push(canvas);
+          }
+
+          if (propertyAnim.onUpdate) {
+            propertyAnim.onUpdate(t);
+          }
+
+          if (currentTime >= propertyAnim.endTime && !propertyAnim.hasEnded) {
+            propertyAnim.hasEnded = true;
+
+            if (propertyAnim.onEnd) {
+              propertyAnim.onEnd();
+            }
+          }
+
+          if (t === 1) {
+            // end
+            this.anims.splice(i, 1);
+            i--;
+          }
+        }
+
+        this.canvas.map(function (c) {
+          c.draw();
+          return c;
+        });
+        this.time = clock.now();
+      }
+
+    }
+
+    function linear$1(k) {
+      return k;
+    }
+
+    function quadraticIn(k) {
+      return k * k;
+    }
+
+    function quadraticOut(k) {
+      return k * (2 - k);
+    }
+
+    function quadraticInOut(k) {
+      if ((k *= 2) < 1) {
+        return 0.5 * k * k;
+      }
+
+      return -0.5 * (--k * (k - 2) - 1);
+    }
+
+    function cubicIn(k) {
+      return k * k * k;
+    }
+
+    function cubicOut(k) {
+      return --k * k * k + 1;
+    }
+
+    function cubicInOut(k) {
+      if ((k *= 2) < 1) {
+        return 0.5 * k * k * k;
+      }
+
+      return 0.5 * ((k -= 2) * k * k + 2);
+    }
+
+    function elasticIn(k) {
+      var s;
+      var a = 0.1;
+      var p = 0.4;
+      if (k === 0) return 0;
+      if (k === 1) return 1;
+
+      if (!a || a < 1) {
+        a = 1;
+        s = p / 4;
+      } else {
+        s = p / (2 * Math.PI) * Math.asin(1 / a);
+      }
+
+      return -(a * Math.pow(2, 10 * (k -= 1)) * Math.sin((k - s) * (2 * Math.PI) / p));
+    }
+
+    function elasticOut(k) {
+      var s;
+      var a = 0.1;
+      var p = 0.4;
+      if (k === 0) return 0;
+      if (k === 1) return 1;
+
+      if (!a || a < 1) {
+        a = 1;
+        s = p / 4;
+      } else {
+        s = p / (2 * Math.PI) * Math.asin(1 / a);
+      }
+
+      return a * Math.pow(2, -10 * k) * Math.sin((k - s) * (2 * Math.PI) / p) + 1;
+    }
+
+    function elasticInOut(k) {
+      var s;
+      var a = 0.1;
+      var p = 0.4;
+      if (k === 0) return 0;
+      if (k === 1) return 1;
+
+      if (!a || a < 1) {
+        a = 1;
+        s = p / 4;
+      } else {
+        s = p / (2 * Math.PI) * Math.asin(1 / a);
+      }
+
+      if ((k *= 2) < 1) {
+        return -0.5 * (a * Math.pow(2, 10 * (k -= 1)) * Math.sin((k - s) * (2 * Math.PI) / p));
+      }
+
+      return a * Math.pow(2, -10 * (k -= 1)) * Math.sin((k - s) * (2 * Math.PI) / p) * 0.5 + 1;
+    }
+
+    function backIn(k) {
+      var s = 1.70158;
+      return k * k * ((s + 1) * k - s);
+    }
+
+    function backOut(k) {
+      var s = 1.70158;
+      return (k = k - 1) * k * ((s + 1) * k + s) + 1;
+    }
+
+    function backInOut(k) {
+      var s = 1.70158 * 1.525;
+
+      if ((k *= 2) < 1) {
+        return 0.5 * (k * k * ((s + 1) * k - s));
+      }
+
+      return 0.5 * ((k -= 2) * k * ((s + 1) * k + s) + 2);
+    }
+
+    function bounceIn(k) {
+      return 1 - bounceOut(1 - k);
+    }
+
+    function bounceOut(k) {
+      if ((k /= 1) < 1 / 2.75) {
+        return 7.5625 * k * k;
+      } else if (k < 2 / 2.75) {
+        return 7.5625 * (k -= 1.5 / 2.75) * k + 0.75;
+      } else if (k < 2.5 / 2.75) {
+        return 7.5625 * (k -= 2.25 / 2.75) * k + 0.9375;
+      }
+
+      return 7.5625 * (k -= 2.625 / 2.75) * k + 0.984375;
+    }
+
+    function bounceInOut(k) {
+      if (k < 0.5) {
+        return bounceIn(k * 2) * 0.5;
+      }
+
+      return bounceOut(k * 2 - 1) * 0.5 + 0.5;
+    }
+
+    var Easing = /*#__PURE__*/Object.freeze({
+        __proto__: null,
+        linear: linear$1,
+        quadraticIn: quadraticIn,
+        quadraticOut: quadraticOut,
+        quadraticInOut: quadraticInOut,
+        cubicIn: cubicIn,
+        cubicOut: cubicOut,
+        cubicInOut: cubicInOut,
+        elasticIn: elasticIn,
+        elasticOut: elasticOut,
+        elasticInOut: elasticInOut,
+        backIn: backIn,
+        backOut: backOut,
+        backInOut: backInOut,
+        bounceIn: bounceIn,
+        bounceOut: bounceOut,
+        bounceInOut: bounceInOut
+    });
+
+    function plainArray(arr) {
+      var result = [];
+
+      for (var i = 0, len = arr.length; i < len; i++) {
+        if (arr[i]) {
+          result.push(arr[i].x);
+          result.push(arr[i].y);
+        }
+      }
+
+      return result;
+    }
+
+    function interpolateNumber(a, b) {
+      a = +a;
+      b -= a;
+      return function (t) {
+        return a + b * t;
+      };
+    }
+
+    function interpolateArray(a, b) {
+      var nb = b ? b.length : 0;
+      var na = a ? Math.min(nb, a.length) : 0;
+      var x = new Array(na);
+      var c = new Array(nb);
+      var i;
+
+      for (i = 0; i < na; ++i) {
+        x[i] = interpolateNumber(a[i], b[i]);
+      }
+
+      for (; i < nb; ++i) {
+        c[i] = b[i];
+      }
+
+      return function (t) {
+        for (i = 0; i < na; ++i) {
+          c[i] = x[i](t);
+        }
+
+        return c;
+      };
+    }
+
+    class Animator {
+      constructor(shape, source, timeline) {
+        this.hasStarted = false;
+        this.hasEnded = false;
+        this.shape = shape;
+        this.source = source;
+        this.timeline = timeline;
+        this.animate = null;
+      } // delay, attrs, duration, easing
+
+
+      to() {
+        var cfg = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
+        var delay = cfg.delay || 0;
+        var attrs = cfg.attrs || {};
+        var duration = cfg.duration || 1000;
+        var easing; // 缓动函数
+
+        if (typeof cfg.easing === 'function') {
+          easing = cfg.easing;
+        } else {
+          easing = Easing[cfg.easing] || linear$1;
+        }
+
+        var animInfo = {
+          shape: this.shape,
+          startTime: this.timeline.time + delay,
+          duration,
+          easing
+        };
+        var interpolate = {}; // 差值函数
+
+        for (var attrName in attrs) {
+          var startValue = this.source[attrName];
+          var endValue = attrs[attrName];
+
+          if (attrName === 'points') {
+            startValue = plainArray(startValue);
+            endValue = plainArray(endValue);
+            interpolate.points = interpolateArray(startValue, endValue);
+            this.source.points = startValue;
+            attrs.points = endValue;
+          } else if (attrName === 'matrix') {
+            interpolate.matrix = interpolateArray(startValue, endValue);
+          } else {
+            interpolate[attrName] = interpolateNumber(startValue, endValue);
+          }
+        }
+
+        animInfo.interpolate = interpolate;
+        animInfo.startState = this.source;
+        animInfo.endState = attrs;
+        animInfo.endTime = animInfo.startTime + duration;
+        this.timeline.pushAnim(animInfo);
+        this.animate = animInfo;
+        return this;
+      }
+
+      onFrame(callback) {
+        // 自定义每一帧动画的动作
+        if (this.animate) {
+          this.animate.onFrame = function (frame) {
+            callback(frame);
+          };
+        }
+
+        return this;
+      }
+
+      onStart(callback) {
+        if (this.animate) {
+          this.animate.onStart = function () {
+            callback();
+          };
+        }
+
+        return this;
+      }
+
+      onUpdate(callback) {
+        if (this.animate) {
+          this.animate.onUpdate = function (frame) {
+            callback(frame);
+          };
+        }
+
+        return this;
+      }
+
+      onEnd(callback) {
+        if (this.animate) {
+          this.animate.onEnd = function () {
+            callback();
+          };
+        }
+
+        return this;
+      }
+
+    }
+
+    function ownKeys$1(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
+
+    function _objectSpread$1(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys$1(Object(source), true).forEach(function (key) { _defineProperty$4(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys$1(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
+
+    function _defineProperty$4(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
+    var defaultAnimationCfg = {
+      appear: {
+        duration: 450,
+        easing: 'quadraticOut'
+      },
+      // 'appear' animation options
+      update: {
+        duration: 300,
+        easing: 'quadraticOut'
+      },
+      // 'update' animation options
+      enter: {
+        duration: 300,
+        easing: 'quadraticOut'
+      },
+      // 'enter' animation options
+      leave: {
+        duration: 350,
+        easing: 'quadraticIn'
+      } // 'leave' animation options
+
+    };
+    var Animate = {
+      defaultCfg: {},
+      Action: {},
+
+      getAnimation(geomType, coord, animationType) {
+        var geomAnimateCfg = this.defaultCfg[geomType];
+
+        if (geomAnimateCfg) {
+          var animation = geomAnimateCfg[animationType];
+
+          if (isFunction(animation)) {
+            return animation(coord);
+          }
+        }
+
+        return false;
+      },
+
+      getAnimateCfg(geomType, animationType) {
+        var defaultCfg = defaultAnimationCfg[animationType];
+        var geomConfig = this.defaultCfg[geomType];
+
+        if (geomConfig && geomConfig.cfg && geomConfig.cfg[animationType]) {
+          return deepMix({}, defaultCfg, geomConfig.cfg[animationType]);
+        }
+
+        return defaultCfg;
+      },
+
+      registerAnimation(animationName, animationFun) {
+        if (!this.Action) {
+          this.Action = {};
+        }
+
+        this.Action = _objectSpread$1(_objectSpread$1({}, this.Action), {}, {
+          [animationName]: animationFun
+        });
+      }
+
+    };
+
+    /**
+     * Utility
+     * @author sima.zhang1990@gmail.com
+     */
+
+    function getCoordInfo(coord) {
+      var start = coord.start;
+      var end = coord.end;
+      return {
+        start,
+        end,
+        width: end.x - start.x,
+        height: Math.abs(end.y - start.y)
+      };
+    }
+
+    function getScaledMatrix(shape, v, direct) {
+      var scaledMatrix;
+      shape.apply(v);
+      var x = v[0];
+      var y = v[1];
+
+      if (direct === 'x') {
+        shape.transform([['t', x, y], ['s', 0.01, 1], ['t', -x, -y]]);
+        var matrix = shape.getMatrix();
+        scaledMatrix = Matrix.transform(matrix, [['t', x, y], ['s', 100, 1], ['t', -x, -y]]);
+      } else if (direct === 'y') {
+        shape.transform([['t', x, y], ['s', 1, 0.01], ['t', -x, -y]]);
+
+        var _matrix = shape.getMatrix();
+
+        scaledMatrix = Matrix.transform(_matrix, [['t', x, y], ['s', 1, 100], ['t', -x, -y]]);
+      } else if (direct === 'xy') {
+        shape.transform([['t', x, y], ['s', 0.01, 0.01], ['t', -x, -y]]);
+
+        var _matrix2 = shape.getMatrix();
+
+        scaledMatrix = Matrix.transform(_matrix2, [['t', x, y], ['s', 100, 100], ['t', -x, -y]]);
+      }
+
+      return scaledMatrix;
+    }
+
+    function getAnimateParam(animateCfg, index, id) {
+      var result = {};
+
+      if (animateCfg.delay) {
+        result.delay = isFunction(animateCfg.delay) ? animateCfg.delay(index, id) : animateCfg.delay;
+      }
+
+      result.easing = animateCfg.easing;
+      result.duration = animateCfg.duration;
+      result.delay = animateCfg.delay;
+      return result;
+    }
+
+    function doAnimation(shape, endState, animateCfg, callback) {
+      var id = shape._id;
+      var index = shape.get('index');
+      var {
+        easing,
+        delay,
+        duration
+      } = getAnimateParam(animateCfg, index, id);
+      var anim = shape.animate().to({
+        attrs: endState,
+        duration,
+        delay,
+        easing
+      });
+
+      if (callback) {
+        anim.onEnd(function () {
+          callback();
+        });
+      }
+    }
+
+    /**
+     * Animation functions for shape
+     * @author sima.zhang1990@gmail.com
+     */
+    /*
+    function waveIn(shape, animateCfg, coord) {
+      const clip = Helpers.getClip(coord);
+      clip.set('canvas', shape.get('canvas'));
+      shape.attr('clip', clip);
+      const onEnd = function() {
+        shape.attr('clip', null);
+        clip.remove(true);
+      };
+      Helpers.doAnimation(clip, clip.endState, animateCfg, onEnd);
+    }
+
+    function scaleInX(shape, animateCfg) {
+      const box = shape.getBBox();
+      const points = shape.get('origin').points;
+      let x;
+      const y = (box.minY + box.maxY) / 2;
+
+      if (points[0].y - points[1].y > 0) { // 当顶点在零点之下
+        x = box.maxX;
+      } else {
+        x = box.minX;
+      }
+      const scaledMatrix = Helpers.getScaledMatrix(shape, [ x, y ], 'x');
+      Helpers.doAnimation(shape, { matrix: scaledMatrix }, animateCfg);
+    }
+
+    function scaleInY(shape, animateCfg) {
+      const box = shape.getBBox();
+      const points = shape.get('origin').points;
+      const x = (box.minX + box.maxX) / 2;
+      let y;
+
+      if (points[0].y - points[1].y <= 0) { // 当顶点在零点之下
+        y = box.maxY;
+      } else {
+        y = box.minY;
+      }
+      const scaledMatrix = Helpers.getScaledMatrix(shape, [ x, y ], 'x');
+      Helpers.doAnimation(shape, { matrix: scaledMatrix }, animateCfg);
+    }
+    */
+
+    function fadeIn(shape, animateCfg) {
+      var fillOpacity = isNil(shape.attr('fillOpacity')) ? 1 : shape.attr('fillOpacity');
+      var strokeOpacity = isNil(shape.attr('strokeOpacity')) ? 1 : shape.attr('strokeOpacity');
+      shape.attr('fillOpacity', 0);
+      shape.attr('strokeOpacity', 0);
+      var endState = {
+        fillOpacity,
+        strokeOpacity
+      };
+      doAnimation(shape, endState, animateCfg);
+    }
+
+    var ShapeAction = /*#__PURE__*/Object.freeze({
+        __proto__: null,
+        fadeIn: fadeIn
+    });
+
+    /**
+     * Group animate functions
+     * @author sima.zhang1990@gmail.com
+     */
+
+    function _groupScaleIn(container, animateCfg, coord, zeroY, type) {
+      var {
+        start,
+        end,
+        width,
+        height
+      } = getCoordInfo(coord);
+      var x;
+      var y;
+      var clip = new Shape$2.Rect({
+        attrs: {
+          x: start.x,
+          y: end.y,
+          width,
+          height
+        }
+      });
+
+      if (type === 'y') {
+        x = start.x + width / 2;
+        y = zeroY.y < start.y ? zeroY.y : start.y;
+      } else if (type === 'x') {
+        x = zeroY.x > start.x ? zeroY.x : start.x;
+        y = start.y + height / 2;
+      } else if (type === 'xy') {
+        if (coord.isPolar) {
+          x = coord.center.x;
+          y = coord.center.y;
+        } else {
+          x = (start.x + end.x) / 2;
+          y = (start.y + end.y) / 2;
+        }
+      }
+
+      var endMatrix = getScaledMatrix(clip, [x, y], type);
+      clip.isClip = true;
+      clip.endState = {
+        matrix: endMatrix
+      };
+      clip.set('canvas', container.get('canvas'));
+      container.attr('clip', clip);
+
+      var onEnd = function onEnd() {
+        container.attr('clip', null);
+        clip.remove(true);
+      };
+
+      doAnimation(clip, clip.endState, animateCfg, onEnd);
+    }
+
+    function _shapeScale(container, animateCfg, type) {
+      var shapes = container.get('children');
+      var x;
+      var y;
+      var endMatrix;
+
+      for (var i = 0, len = shapes.length; i < len; i++) {
+        var shape = shapes[i];
+        var box = shape.getBBox();
+        x = (box.minX + box.maxX) / 2;
+        y = (box.minY + box.maxY) / 2;
+        endMatrix = getScaledMatrix(shape, [x, y], type);
+        doAnimation(shape, {
+          matrix: endMatrix
+        }, animateCfg);
+      }
+    }
+
+    function groupScaleInX(container, animateCfg, coord, zeroY) {
+      _groupScaleIn(container, animateCfg, coord, zeroY, 'x');
+    }
+
+    function groupScaleInY(container, animateCfg, coord, zeroY) {
+      _groupScaleIn(container, animateCfg, coord, zeroY, 'y');
+    }
+
+    function groupScaleInXY(container, animateCfg, coord, zeroY) {
+      _groupScaleIn(container, animateCfg, coord, zeroY, 'xy');
+    }
+
+    function shapesScaleInX(container, animateCfg) {
+      _shapeScale(container, animateCfg, 'x');
+    }
+
+    function shapesScaleInY(container, animateCfg) {
+      _shapeScale(container, animateCfg, 'y');
+    }
+
+    function shapesScaleInXY(container, animateCfg) {
+      _shapeScale(container, animateCfg, 'xy');
+    }
+
+    function groupWaveIn(container, animateCfg, coord) {
+      var clip = getClip(coord);
+      clip.set('canvas', container.get('canvas'));
+      container.attr('clip', clip);
+
+      var onEnd = function onEnd() {
+        container.attr('clip', null);
+        clip.remove(true);
+      };
+
+      var endState = {};
+
+      if (coord.isPolar) {
+        var {
+          startAngle,
+          endAngle
+        } = coord;
+        endState.endAngle = endAngle;
+        clip.attr('endAngle', startAngle);
+      } else {
+        var {
+          start,
+          end
+        } = coord;
+        var width = Math.abs(start.x - end.x);
+        var height = Math.abs(start.y - end.y);
+
+        if (coord.isTransposed) {
+          clip.attr('height', 0);
+          endState.height = height;
+        } else {
+          clip.attr('width', 0);
+          endState.width = width;
+        }
+      }
+
+      doAnimation(clip, endState, animateCfg, onEnd);
+    }
+
+    var GroupAction = /*#__PURE__*/Object.freeze({
+        __proto__: null,
+        groupWaveIn: groupWaveIn,
+        groupScaleInX: groupScaleInX,
+        groupScaleInY: groupScaleInY,
+        groupScaleInXY: groupScaleInXY,
+        shapesScaleInX: shapesScaleInX,
+        shapesScaleInY: shapesScaleInY,
+        shapesScaleInXY: shapesScaleInXY
+    });
+
+    /**
+     * Handle the detail animations
+     * @author sima.zhang1990@gmail.com
+     */
+    var timeline;
+
+    Element$1.prototype.animate = function () {
+      var attrs = mix({}, this.get('attrs'));
+      return new Animator(this, attrs, timeline);
+    };
+
+    Chart.prototype.animate = function (cfg) {
+      this.set('animate', cfg);
+      return this;
+    };
+
+    Animate.Action = ShapeAction;
+    Animate.defaultCfg = {
+      interval: {
+        enter(coord) {
+          if (coord.isPolar && coord.transposed) {
+            // for pie chart
+            return function (shape) {
+              shape.set('zIndex', -1);
+              var container = shape.get('parent');
+              container.sort();
+            };
+          }
+
+          return fadeIn;
+        }
+
+      },
+      area: {
+        enter(coord) {
+          if (coord.isPolar) return null;
+          return fadeIn;
+        }
+
+      },
+      line: {
+        enter(coord) {
+          if (coord.isPolar) return null;
+          return fadeIn;
+        }
+
+      },
+      path: {
+        enter(coord) {
+          if (coord.isPolar) return null;
+          return fadeIn;
+        }
+
+      }
+    };
+    var GROUP_ANIMATION = {
+      line(coord) {
+        if (coord.isPolar) {
+          return groupScaleInXY;
+        }
+
+        return groupWaveIn;
+      },
+
+      area(coord) {
+        if (coord.isPolar) {
+          return groupScaleInXY;
+        }
+
+        return groupWaveIn;
+      },
+
+      path(coord) {
+        if (coord.isPolar) {
+          return groupScaleInXY;
+        }
+
+        return groupWaveIn;
+      },
+
+      point() {
+        return shapesScaleInXY;
+      },
+
+      interval(coord) {
+        var result;
+
+        if (coord.isPolar) {
+          // polar coodinate
+          result = groupScaleInXY;
+
+          if (coord.transposed) {
+            // pie chart
+            result = groupWaveIn;
+          }
+        } else {
+          result = coord.transposed ? groupScaleInX : groupScaleInY;
+        }
+
+        return result;
+      },
+
+      schema() {
+        return groupWaveIn;
+      }
+
+    };
+
+    function diff(fromAttrs, toAttrs) {
+      var endState = {};
+
+      for (var k in toAttrs) {
+        if (isNumber(fromAttrs[k]) && fromAttrs[k] !== toAttrs[k]) {
+          endState[k] = toAttrs[k];
+        } else if (isArray(fromAttrs[k]) && JSON.stringify(fromAttrs[k]) !== JSON.stringify(toAttrs[k])) {
+          endState[k] = toAttrs[k];
+        }
+      }
+
+      return endState;
+    } // Add a unique id identifier to each shape
+
+
+    function _getShapeId(geom, dataObj, geomIdx) {
+      var type = geom.get('type');
+      var id = 'geom' + geomIdx + '-' + type;
+      var xScale = geom.getXScale();
+      var yScale = geom.getYScale();
+      var xField = xScale.field || 'x';
+      var yField = yScale.field || 'y';
+      var yVal = dataObj[yField];
+      var xVal;
+
+      if (xScale.isIdentity) {
+        xVal = xScale.value;
+      } else {
+        xVal = dataObj[xField];
+      }
+
+      if (type === 'interval' || type === 'schema') {
+        id += '-' + xVal;
+      } else if (type === 'line' || type === 'area' || type === 'path') {
+        id += '-' + type;
+      } else {
+        id += xScale.isCategory ? '-' + xVal : '-' + xVal + '-' + yVal;
+      }
+
+      var groupScales = geom._getGroupScales();
+
+      each(groupScales, function (groupScale) {
+        var field = groupScale.field;
+
+        if (groupScale.type !== 'identity') {
+          id += '-' + dataObj[field];
+        }
+      });
+      return id;
+    } // get geometry's shapes
+
+
+    function getShapes(geoms, chart, coord) {
+      var shapes = [];
+      each(geoms, function (geom, geomIdx) {
+        var geomContainer = geom.get('container');
+        var geomShapes = geomContainer.get('children');
+        var type = geom.get('type');
+        var animateCfg = isNil(geom.get('animateCfg')) ? _getAnimateCfgByShapeType(type, chart) : geom.get('animateCfg');
+
+        if (animateCfg !== false) {
+          each(geomShapes, function (shape, index) {
+            if (shape.get('className') === type) {
+              shape._id = _getShapeId(geom, shape.get('origin')._origin, geomIdx);
+              shape.set('coord', coord);
+              shape.set('animateCfg', animateCfg);
+              shape.set('index', index);
+              shapes.push(shape);
+            }
+          });
+        }
+
+        geom.set('shapes', geomShapes);
+      });
+      return shapes;
+    }
+
+    function cache(shapes) {
+      var rst = {};
+
+      for (var i = 0, len = shapes.length; i < len; i++) {
+        var shape = shapes[i];
+        if (!shape._id || shape.isClip) continue;
+        var id = shape._id;
+        rst[id] = {
+          _id: id,
+          type: shape.get('type'),
+          // the type of shape
+          attrs: mix({}, shape._attrs.attrs),
+          // the graphics attributes of shape
+          className: shape.get('className'),
+          geomType: shape.get('className'),
+          index: shape.get('index'),
+          coord: shape.get('coord'),
+          animateCfg: shape.get('animateCfg')
+        };
+      }
+
+      return rst;
+    }
+
+    function getAnimate(geomType, coord, animationType, animationName) {
+      var result;
+
+      if (isFunction(animationName)) {
+        result = animationName;
+      } else if (isString(animationName)) {
+        result = Animate.Action[animationName];
+      } else {
+        result = Animate.getAnimation(geomType, coord, animationType);
+      }
+
+      return result;
+    }
+
+    function getAnimateCfg(geomType, animationType, animateCfg) {
+      if (animateCfg === false || isObject(animateCfg) && animateCfg[animationType] === false) {
+        return false;
+      }
+
+      var defaultCfg = Animate.getAnimateCfg(geomType, animationType);
+
+      if (animateCfg && animateCfg[animationType]) {
+        return deepMix({}, defaultCfg, animateCfg[animationType]);
+      }
+
+      return defaultCfg;
+    }
+
+    function addAnimate(cache, shapes, canvas) {
+      var animate;
+      var animateCfg; // the order of animation: leave -> update -> enter
+
+      var updateShapes = [];
+      var newShapes = [];
+      each(shapes, function (shape) {
+        var result = cache[shape._id];
+
+        if (!result) {
+          newShapes.push(shape);
+        } else {
+          shape.set('cacheShape', result);
+          updateShapes.push(shape);
+          delete cache[shape._id];
+        }
+      }); // first do the leave animation
+
+      each(cache, function (deletedShape) {
+        var {
+          className,
+          coord,
+          _id,
+          attrs,
+          index,
+          type
+        } = deletedShape;
+        animateCfg = getAnimateCfg(className, 'leave', deletedShape.animateCfg);
+        if (animateCfg === false) return true;
+        animate = getAnimate(className, coord, 'leave', animateCfg.animation);
+
+        if (isFunction(animate)) {
+          var tempShape = canvas.addShape(type, {
+            attrs,
+            index,
+            canvas,
+            className
+          });
+          tempShape._id = _id;
+          animate(tempShape, animateCfg, coord);
+        }
+      }); // then do the update animation
+
+      each(updateShapes, function (updateShape) {
+        var className = updateShape.get('className');
+        animateCfg = getAnimateCfg(className, 'update', updateShape.get('animateCfg'));
+        if (animateCfg === false) return true;
+        var coord = updateShape.get('coord');
+        var cacheAttrs = updateShape.get('cacheShape').attrs;
+        var endState = diff(cacheAttrs, updateShape._attrs.attrs); // 判断如果属性相同的话就不进行变换
+
+        if (Object.keys(endState).length) {
+          animate = getAnimate(className, coord, 'update', animateCfg.animation);
+
+          if (isFunction(animate)) {
+            animate(updateShape, animateCfg, coord);
+          } else {
+            updateShape.attr(cacheAttrs);
+            updateShape.animate().to({
+              attrs: endState,
+              duration: animateCfg.duration,
+              easing: animateCfg.easing,
+              delay: animateCfg.delay
+            }).onEnd(function () {
+              updateShape.set('cacheShape', null);
+            });
+          }
+        }
+      }); // last, enter animation
+
+      each(newShapes, function (newShape) {
+        // 新图形元素的进场元素
+        var className = newShape.get('className');
+        var coord = newShape.get('coord');
+        animateCfg = getAnimateCfg(className, 'enter', newShape.get('animateCfg'));
+        if (animateCfg === false) return true;
+        animate = getAnimate(className, coord, 'enter', animateCfg.animation);
+
+        if (isFunction(animate)) {
+          if (className === 'interval' && coord.isPolar && coord.transposed) {
+            var index = newShape.get('index');
+            var lastShape = updateShapes[index - 1];
+            animate(newShape, animateCfg, lastShape);
+          } else {
+            animate(newShape, animateCfg, coord);
+          }
+        }
+      });
+    }
+
+    function _getAnimateCfgByShapeType(type, chart) {
+      if (!type) {
+        return null;
+      }
+
+      var animateCfg = chart.get('animate');
+
+      if (type.indexOf('guide-tag') > -1) {
+        type = 'guide-tag';
+      }
+
+      if (isObject(animateCfg)) {
+        return animateCfg[type];
+      }
+
+      if (animateCfg === false) {
+        return false;
+      }
+
+      return null;
+    }
+
+    function afterCanvasInit()
+    /* chart */
+    {
+      timeline = new Timeline();
+      timeline.play();
+    }
+
+    function beforeCanvasDraw(chart) {
+      if (chart.get('animate') === false) {
+        return;
+      }
+
+      var isUpdate = chart.get('isUpdate');
+      var canvas = chart.get('canvas');
+      var coord = chart.get('coord');
+      var geoms = chart.get('geoms');
+      var caches = canvas.get('caches') || [];
+
+      if (caches.length === 0) {
+        isUpdate = false;
+      }
+
+      var cacheShapes = getShapes(geoms, chart, coord);
+      var {
+        frontPlot,
+        backPlot
+      } = chart.get('axisController');
+      var axisShapes = frontPlot.get('children').concat(backPlot.get('children'));
+      var guideShapes = [];
+
+      if (chart.get('guideController')) {
+        guideShapes = chart.get('guideController').guideShapes;
+      }
+
+      var componentShapes = [];
+      axisShapes.concat(guideShapes).forEach(function (s) {
+        var className = s.get('className');
+
+        var animateCfg = _getAnimateCfgByShapeType(className, chart);
+
+        s.set('coord', coord);
+        s.set('animateCfg', animateCfg);
+        componentShapes.push(s);
+        cacheShapes.push(s);
+      });
+      canvas.set('caches', cache(cacheShapes));
+
+      if (isUpdate) {
+        addAnimate(caches, cacheShapes, canvas);
+      } else {
+        // do the appear animation
+        var animateCfg;
+        var animate;
+        each(geoms, function (geom) {
+          var type = geom.get('type');
+          var geomCfg = isNil(geom.get('animateCfg')) ? _getAnimateCfgByShapeType(type, chart) : geom.get('animateCfg');
+
+          if (geomCfg !== false) {
+            animateCfg = getAnimateCfg(type, 'appear', geomCfg);
+            animate = getAnimate(type, coord, 'appear', animateCfg.animation);
+
+            if (isFunction(animate)) {
+              var shapes = geom.get('shapes');
+              each(shapes, function (shape) {
+                animate(shape, animateCfg, coord);
+              });
+            } else if (GROUP_ANIMATION[type]) {
+              // do the default animation
+              animate = GroupAction[animateCfg.animation] || GROUP_ANIMATION[type](coord);
+              var yScale = geom.getYScale();
+              var zeroY = coord.convertPoint({
+                x: 0,
+                y: yScale.scale(geom.getYMinValue())
+              });
+              var container = geom.get('container');
+              animate && animate(container, animateCfg, coord, zeroY);
+            }
+          }
+        }); // do the animation of components
+
+        each(componentShapes, function (shape) {
+          var animateCfg = shape.get('animateCfg');
+          var className = shape.get('className');
+
+          if (animateCfg && animateCfg.appear) {
+            // if user configure
+            var defaultCfg = Animate.getAnimateCfg(className, 'appear');
+            var appearCfg = deepMix({}, defaultCfg, animateCfg.appear);
+
+            var _animate = getAnimate(className, coord, 'appear', appearCfg.animation);
+
+            if (isFunction(_animate)) {
+              _animate(shape, appearCfg, coord);
+            }
+          }
+        });
+      }
+    }
+
+    function afterCanvasDestroyed()
+    /* chart */
+    {
+      timeline.stop();
+    }
+    var detail = {
+      afterCanvasInit,
+      beforeCanvasDraw,
+      afterCanvasDestroyed
+    };
+
+    var Animation = /*#__PURE__*/Object.freeze({
+        __proto__: null,
+        afterCanvasInit: afterCanvasInit,
+        beforeCanvasDraw: beforeCanvasDraw,
+        afterCanvasDestroyed: afterCanvasDestroyed,
+        'default': detail
+    });
+
+    Chart._Interactions = {};
+
+    Chart.registerInteraction = function (type, constructor) {
+      Chart._Interactions[type] = constructor;
+    };
+
+    Chart.getInteraction = function (type) {
+      return Chart._Interactions[type];
+    };
+
+    Chart.prototype.interaction = function (type, cfg) {
+      var interactions = this._interactions || {};
+
+      if (interactions[type]) {
+        // if reprated, destroy last
+        interactions[type].destroy();
+      }
+
+      var Ctor = Chart.getInteraction(type);
+      var interact = new Ctor(cfg, this);
+      interactions[type] = interact;
+      this._interactions = interactions;
+      return this;
+    };
+
+    Chart.prototype.clearInteraction = function (type) {
+      var interactions = this._interactions;
+      if (!interactions) return;
+
+      if (type) {
+        interactions[type] && interactions[type].destroy();
+        delete interactions[type];
+      } else {
+        each(interactions, function (interaction, key) {
+          interaction.destroy();
+          delete interactions[key];
+        });
+      }
+
+      return this;
+    };
+
+    function _defineProperty$5(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
+
+    function isValuesEqual(values, newValues) {
+      if (values.length !== newValues.length) {
+        return false;
+      }
+
+      var lastIndex = values.length - 1;
+      return values[0] === newValues[0] && values[lastIndex] === newValues[lastIndex];
+    } // 不同交互之间共享的上下文
+
+
+    var defaultRange = [0, 1];
+
+    class Context {
+      // 最开始的原始值
+      // 当前显示的范围
+      // 缩放最小的点数
+      // 最小的缩放比例, 默认通过minCount计算
+      // minScale = 0.01;
+      // 交互开始时,ticks个数,主要为了每次缩放后,更新ticks个数
+      // lastTickCount;
+      constructor(chart) {
+        var _this = this;
+
+        _defineProperty$5(this, "chart", null);
+
+        _defineProperty$5(this, "values", null);
+
+        _defineProperty$5(this, "range", defaultRange);
+
+        _defineProperty$5(this, "startRange", defaultRange);
+
+        _defineProperty$5(this, "minCount", 10);
+
+        _defineProperty$5(this, "_afterinit", function () {
+          // 初始化value值
+          var scale = _this.getPinchScale(); // 记录原始全量数据
+
+
+          var values = [].concat(scale.values);
+          _this.values = values; // 最小的缩放比例
+
+          if (!_this.minScale) {
+            _this.minScale = _this.minCount / values.length;
+          } // 初始化的时候有设置range,则初始化成默认比例
+
+
+          if (_this.range !== defaultRange) {
+            _this.updateRange(_this.range);
+
+            _this.updateTicks();
+          }
+        });
+
+        _defineProperty$5(this, "_afterdatachange", function () {
+          _this.updateRange(_this.range);
+        });
+
+        this.chart = chart;
+
+        this._initEvent(chart);
+      }
+
+      _initEvent(chart) {
+        // 在整体初始化后还需要设置一些初始状态
+        chart.on(EVENT_AFTER_INIT, this._afterinit);
+        chart.on(EVENT_AFTER_DATA_CHANGE, this._afterdatachange);
+      } // 缩放的主轴scale
+
+
+      getPinchScale() {
+        var {
+          chart
+        } = this; // 默认缩放x轴
+
+        var scale = chart.getXScale();
+        return scale;
+      } // 跟随轴的scale
+
+
+      getFollowScale() {
+        var {
+          chart
+        } = this; // 默认缩放x轴
+
+        var scales = chart.getYScales() || [];
+        return scales[0];
+      }
+
+      start() {
+        var {
+          range
+        } = this;
+        var scale = this.getPinchScale();
+        var [start, end] = range; // 记录交互起始的范围
+
+        this.startRange = [start, end]; // 记录开始时的ticks个数
+
+        this.lastTickCount = scale.tickCount;
+      }
+
+      doZoom(leftScale, rightScale, zoom) {
+        var {
+          startRange: range,
+          minScale
+        } = this;
+        var [start, end] = range;
+        var zoomOffset = 1 - zoom;
+        var rangeLen = end - start;
+        var rangeOffset = rangeLen * zoomOffset;
+        var leftOffset = rangeOffset * leftScale;
+        var rightOffset = rangeOffset * rightScale;
+        var newStart = Math.max(0, start - leftOffset);
+        var newEnd = Math.min(1, end + rightOffset);
+        var newRange = [newStart, newEnd]; // 如果已经到了最小比例,则不能再继续再放大
+
+        if (newEnd - newStart < minScale) {
+          return;
+        }
+
+        this.updateRange(newRange);
+      }
+
+      doMove(ratio) {
+        // 不管是0, 还是其他,都不用处理
+        if (!ratio) return;
+        var {
+          startRange: range
+        } = this;
+        var [start, end] = range;
+        var rangeLen = end - start;
+        var rangeOffset = rangeLen * ratio;
+        var newStart = start - rangeOffset;
+        var newEnd = end - rangeOffset; // 处理边界值
+
+        var newRange;
+
+        if (newStart < 0) {
+          newRange = [0, rangeLen];
+        } else if (newEnd > 1) {
+          newRange = [1 - rangeLen, 1];
+        } else {
+          newRange = [newStart, newEnd];
+        }
+
+        this.updateRange(newRange);
+      }
+
+      updateRange(range) {
+        var {
+          values
+        } = this; // 0, 1 的范围之间
+
+        var [start, end] = range; // start 不能小于0
+
+        start = Math.max(0, start); // end 不能大于1
+
+        end = Math.min(1, end); // 设置当前的范围
+
+        this.range = [start, end];
+        var len = values.length;
+        var valueStart = start * len;
+        var valueEnd = end * len; // 从原始数据里截取需要显示的数据
+
+        var newValues = values.slice(valueStart, valueEnd);
+        this.repaint(newValues);
+      }
+
+      repaint(newValues) {
+        var {
+          chart
+        } = this;
+        var scale = this.getPinchScale();
+        var {
+          values: currentValues,
+          ticks
+        } = scale; // 如果新数组和当前显示的数组相同,则不更新
+
+        if (isValuesEqual(currentValues, newValues)) {
+          return;
+        } // 更新主轴values
+
+
+        this.updateScale(scale, {
+          ticks,
+          values: newValues
+        });
+        this.updateFollowScale(scale, newValues);
+        chart.repaint();
+      }
+
+      updateFollowScale(pinchScale, pinchValues) {
+        var {
+          chart
+        } = this;
+        var followScale = this.getFollowScale();
+        var {
+          field: pinchField,
+          type: pinchScaleType
+        } = pinchScale;
+        var {
+          field: followField
+        } = followScale; // 根据主轴的value值,找到所有从轴的value值
+
+        var values = []; // 转成map,让查找性能更高
+
+        var pinchValueMap = {};
+        pinchValues.forEach(function (item) {
+          pinchValueMap[item] = true;
+        });
+        var data = chart.get('data');
+        data.forEach(function (item) {
+          if (pinchScaleType === 'timeCat') {
+            var value = toTimeStamp(item[pinchField]);
+
+            if (pinchValueMap[value]) {
+              values.push(item[followField]);
+            }
+          }
+        });
+        var {
+          min,
+          max
+        } = getRange$1(values);
+        this.updateScale(followScale, {
+          min,
+          max,
+          nice: true
+        });
+      }
+
+      updateScale(scale, cfg) {
+        if (!scale) {
+          return;
+        }
+
+        scale.change(cfg);
+      } // 上一次的tick个数
+
+
+      updateTicks() {
+        var {
+          chart,
+          values
+        } = this;
+        var scale = this.getPinchScale();
+        var {
+          values: currentValues,
+          tickCount
+        } = scale; // 根据当前数据的比例,和定义的tickCount计算应该需要多少个ticks
+
+        var newTickCount = Math.round(tickCount * values.length / currentValues.length);
+        var catTicks = getTickMethod('cat');
+        var ticks = catTicks({
+          tickCount: newTickCount,
+          values
+        });
+        this.updateScale(scale, {
+          ticks,
+          values: currentValues
+        }); // 更新完后,需要重新绘制一次
+
+        chart.repaint();
+      }
+
+      destroy() {
+        var {
+          chart
+        } = this;
+        chart.off(EVENT_AFTER_INIT, this._afterinit);
+        chart.off(EVENT_AFTER_DATA_CHANGE, this._afterdatachange);
+      }
+
+    }
+
+    function _defineProperty$6(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
+
+    class Base$2 {
+      // 交互的上下文
+      getDefaultCfg() {
+        return {};
+      }
+
+      getInteractionContext(chart) {
+        var interactionContext = chart.get('interactionContext');
+
+        if (interactionContext) {
+          return interactionContext;
+        }
+
+        interactionContext = new Context(chart);
+        chart.set('interactionContext', interactionContext);
+        return interactionContext;
+      }
+
+      constructor(cfg, chart) {
+        var _this = this;
+
+        _defineProperty$6(this, "type", '');
+
+        _defineProperty$6(this, "startEvent", 'touchstart');
+
+        _defineProperty$6(this, "processEvent", 'touchmove');
+
+        _defineProperty$6(this, "endEvent", 'touchend');
+
+        _defineProperty$6(this, "resetEvent", null);
+
+        _defineProperty$6(this, "context", null);
+
+        _defineProperty$6(this, "_start", function (ev) {
+          _this.preStart && _this.preStart(ev);
+
+          _this.start(ev);
+
+          _this.onStart && _this.onStart(ev);
+        });
+
+        _defineProperty$6(this, "_process", function (ev) {
+          _this.preProcess && _this.preProcess(ev);
+
+          _this.process(ev);
+
+          _this.onProcess && _this.onProcess(ev);
+        });
+
+        _defineProperty$6(this, "_end", function (ev) {
+          _this.preEnd && _this.preEnd(ev);
+
+          _this.end(ev);
+
+          _this.onEnd && _this.onEnd(ev);
+        });
+
+        _defineProperty$6(this, "_reset", function (ev) {
+          _this.preReset && _this.preReset(ev);
+
+          _this.reset(ev);
+
+          _this.onReset && _this.onReset(ev);
+        });
+
+        mix(this, this.getDefaultCfg(), cfg);
+        this.context = this.getInteractionContext(chart);
+        this.chart = chart; // 只处理range, 暂时先这么处理后面再看情况调整
+
+        var {
+          range
+        } = this;
+
+        if (range) {
+          this.context.range = range;
+        }
+
+        this._bindEvents(chart);
+      }
+
+      _bindEvents(chart) {
+        var {
+          startEvent,
+          processEvent,
+          endEvent,
+          resetEvent
+        } = this;
+        var canvas = chart.get('canvas'); // 统一绑定事件
+
+        canvas.on(startEvent, this._start);
+        canvas.on(processEvent, this._process);
+        canvas.on(endEvent, this._end);
+        canvas.on(resetEvent, this._reset);
+      }
+
+      _clearEvents() {
+        var {
+          chart,
+          startEvent,
+          processEvent,
+          endEvent,
+          resetEvent
+        } = this;
+        var canvas = chart.get('canvas'); // 统一绑定事件
+
+        canvas.off(startEvent, this._start);
+        canvas.off(processEvent, this._process);
+        canvas.off(endEvent, this._end);
+        canvas.off(resetEvent, this._start);
+      }
+
+      // override
+      start() {} // override
+
+
+      process() {} // override
+
+
+      end() {} // override
+
+
+      reset() {}
+
+      destroy() {
+        this.context.destroy();
+
+        this._clearEvents();
+      }
+
+    }
+
+    class Pan extends Base$2 {
+      getDefaultCfg() {
+        return {
+          type: 'pan',
+          startEvent: 'panstart',
+          processEvent: 'pan',
+          endEvent: 'panend'
+        };
+      }
+
+      start() {
+        var {
+          context
+        } = this;
+        context.start();
+      }
+
+      process(e) {
+        var {
+          direction,
+          deltaX
+        } = e;
+
+        if (direction === 'up' || direction === 'down') {
+          return;
+        }
+
+        e.preventDefault && e.preventDefault();
+        var {
+          context
+        } = this;
+        var chart = context.chart;
+        var coord = chart.get('coord');
+        var {
+          start,
+          end
+        } = coord;
+        var coordWidth = end.x - start.x;
+        var ratio = deltaX / coordWidth;
+        context.doMove(ratio);
+      }
+
+    }
+
+    class Pinch extends Base$2 {
+      getDefaultCfg() {
+        return {
+          type: 'pinch',
+          startEvent: 'pinchstart',
+          processEvent: 'pinch',
+          endEvent: 'pinchend'
+        };
+      }
+
+      constructor(cfg, chart) {
+        super(cfg, chart);
+        var {
+          context
+        } = this;
+        mix(context, cfg);
+      }
+
+      start() {
+        var {
+          context
+        } = this;
+        context.start();
+      }
+
+      process(e) {
+        e.preventDefault && e.preventDefault();
+        var {
+          zoom,
+          center
+        } = e;
+        var {
+          context
+        } = this;
+        var {
+          chart
+        } = context;
+        var coord = chart.get('coord');
+        var {
+          start,
+          end
+        } = coord;
+        var coordWidth = end.x - start.x;
+        var leftLen = Math.abs(center.x - start.x);
+        var rightLen = Math.abs(end.x - center.x); // 计算左右缩放的比例
+
+        var leftScale = leftLen / coordWidth;
+        var rightScale = rightLen / coordWidth;
+        context.doZoom(leftScale, rightScale, zoom);
+      }
+
+      end() {
+        // 缩放完成后再更新ticks
+        var {
+          context
+        } = this;
+        context.updateTicks();
+      }
+
+    }
+
+    Chart.registerInteraction('pan', Pan);
+    Chart.registerInteraction('pinch', Pinch);
+
+    /**
+     * Default, without interactins
+     */
+    var Component$1 = {
+      Marker
+    }; // register plugins
+
+    Chart.plugins.register([Tooltip$1, Legend, Guide, Animation]); // 默认添加交互
+    var F2 = {
+      Component: Component$1,
+      Global,
+      Chart,
+      Shape: Shape$1,
+      G,
+      Util,
+      Helper,
+      track,
+      Animate
+    };
+
+    var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
+
+    function unwrapExports (x) {
+    	return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
+    }
+
+    function createCommonjsModule(fn, module) {
+    	return module = { exports: {} }, fn(module, module.exports), module.exports;
+    }
+
+    var array$1 = createCommonjsModule(function (module, exports) {
+
+    exports.__esModule = true;
+    exports.merge = merge;
+    exports.values = values;
+    exports.firstValue = firstValue;
+    exports.group = group;
+    exports.groupToMap = groupToMap;
+    exports.remove = remove;
+    exports.getRange = getRange;
+
+
+
+    function merge(dataArray) {
+      var rst = [];
+
+      for (var i = 0, len = dataArray.length; i < len; i++) {
+        rst = rst.concat(dataArray[i]);
+      }
+
+      return rst;
+    }
+
+    function values(data, name) {
+      var rst = [];
+      var tmpMap = {};
+
+      for (var i = 0, len = data.length; i < len; i++) {
+        var obj = data[i];
+        var value = obj[name];
+
+        if (!(0, esm.isNil)(value)) {
+          if (!(0, esm.isArray)(value)) {
+            if (!tmpMap[value]) {
+              rst.push(value);
+              tmpMap[value] = true;
+            }
+          } else {
+            (0, esm.each)(value, function (val) {
+              if (!tmpMap[val]) {
+                rst.push(val);
+                tmpMap[val] = true;
+              }
+            });
+          }
+        }
+      }
+
+      return rst;
+    }
+
+    function firstValue(data, name) {
+      var rst = null;
+
+      for (var i = 0, len = data.length; i < len; i++) {
+        var obj = data[i];
+        var value = obj[name];
+
+        if (!(0, esm.isNil)(value)) {
+          if ((0, esm.isArray)(value)) {
+            rst = value[0];
+          } else {
+            rst = value;
+          }
+
+          break;
+        }
+      }
+
+      return rst;
+    }
+
+    function groupToMap(data, fields) {
+      if (!fields) {
+        return {
+          0: data
+        };
+      }
+
+      var callback = function callback(row) {
+        var unique = '_';
+
+        for (var i = 0, l = fields.length; i < l; i++) {
+          unique += row[fields[i]] && row[fields[i]].toString();
+        }
+
+        return unique;
+      };
+
+      var groups = {};
+
+      for (var i = 0, len = data.length; i < len; i++) {
+        var row = data[i];
+        var key = callback(row);
+
+        if (groups[key]) {
+          groups[key].push(row);
+        } else {
+          groups[key] = [row];
+        }
+      }
+
+      return groups;
+    }
+
+    function group(data, fields, appendConditions) {
+      if (appendConditions === void 0) {
+        appendConditions = {};
+      }
+
+      if (!fields) {
+        return [data];
+      }
+
+      var groups = groupToMap(data, fields);
+      var array = [];
+
+      if (fields.length === 1 && appendConditions[fields[0]]) {
+        var _values = appendConditions[fields[0]];
+        (0, esm.each)(_values, function (value) {
+          value = '_' + value;
+          array.push(groups[value]);
+        });
+      } else {
+        for (var i in groups) {
+          array.push(groups[i]);
+        }
+      }
+
+      return array;
+    }
+
+    function remove(arr, obj) {
+      if (!arr) {
+        return;
+      }
+
+      var index = arr.indexOf(obj);
+
+      if (index !== -1) {
+        arr.splice(index, 1);
+      }
+    }
+
+    function getRange(values) {
+      if (!values.length) {
+        return {
+          min: 0,
+          max: 0
+        };
+      }
+
+      var max = Math.max.apply(null, values);
+      var min = Math.min.apply(null, values);
+      return {
+        min: min,
+        max: max
+      };
+    }
+    });
+
+    unwrapExports(array$1);
+    var array_1 = array$1.merge;
+    var array_2 = array$1.values;
+    var array_3 = array$1.firstValue;
+    var array_4 = array$1.group;
+    var array_5 = array$1.groupToMap;
+    var array_6 = array$1.remove;
+    var array_7 = array$1.getRange;
+
+    var dom = createCommonjsModule(function (module, exports) {
+
+    exports.__esModule = true;
+    exports.isCanvasElement = isCanvasElement;
+    exports.getPixelRatio = getPixelRatio;
+    exports.getStyle = getStyle;
+    exports.getWidth = getWidth;
+    exports.getHeight = getHeight;
+    exports.getDomById = getDomById;
+    exports.getRelativePosition = getRelativePosition;
+    exports.addEventListener = addEventListener;
+    exports.removeEventListener = removeEventListener;
+    exports.createEvent = createEvent;
+    exports.measureText = measureText;
+    exports.isBrowser = exports.isNode = exports.isMy = exports.isWx = void 0;
+
+    /**
+     * Detects support for options object argument in addEventListener.
+     * https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Safely_detecting_option_support
+     * @private
+     */
+    var supportsEventListenerOptions = function () {
+      var supports = false;
+
+      try {
+        var options = Object.defineProperty({}, 'passive', {
+          get: function get() {
+            supports = true;
+          }
+        });
+        window.addEventListener('e', null, options);
+      } catch (e) {// continue regardless of error
+      }
+
+      return supports;
+    }(); // Default passive to true as expected by Chrome for 'touchstart' and 'touchend' events.
+    // https://github.com/chartjs/Chart.js/issues/4287
+
+
+    var eventListenerOptions = supportsEventListenerOptions ? {
+      passive: true
+    } : false;
+    /* global wx, my */
+    // weixin miniprogram
+
+    var isWx = typeof wx === 'object' && typeof wx.getSystemInfoSync === 'function'; // ant miniprogram
+
+    exports.isWx = isWx;
+    var isMy = typeof my === 'object' && typeof my.getSystemInfoSync === 'function'; // in node
+
+    exports.isMy = isMy;
+    var isNode = typeof commonjsGlobal && !typeof window; // in browser
+
+    exports.isNode = isNode;
+    var isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined' && typeof window.sessionStorage !== 'undefined';
+    exports.isBrowser = isBrowser;
+
+    function isCanvasElement(el) {
+      if (!el || typeof el !== 'object') return false;
+
+      if (el.nodeType === 1 && el.nodeName) {
+        // HTMLCanvasElement
+        return true;
+      } // CanvasElement
+
+
+      return !!el.isCanvasElement;
+    }
+
+    function getPixelRatio() {
+      return window && window.devicePixelRatio || 1;
+    }
+
+    function getStyle(el, property) {
+      return el.currentStyle ? el.currentStyle[property] : document.defaultView.getComputedStyle(el, null).getPropertyValue(property);
+    }
+
+    function getWidth(el) {
+      var width = getStyle(el, 'width');
+
+      if (width === 'auto') {
+        width = el.offsetWidth;
+      }
+
+      return parseFloat(width);
+    }
+
+    function getHeight(el) {
+      var height = getStyle(el, 'height');
+
+      if (height === 'auto') {
+        height = el.offsetHeight;
+      }
+
+      return parseFloat(height);
+    }
+
+    function getDomById(id) {
+      if (!id) {
+        return null;
+      }
+
+      return document.getElementById(id);
+    }
+
+    function getRelativePosition(point, canvas) {
+      var canvasDom = canvas.get('el');
+      if (!canvasDom) return point;
+
+      var _canvasDom$getBoundin = canvasDom.getBoundingClientRect(),
+          top = _canvasDom$getBoundin.top,
+          right = _canvasDom$getBoundin.right,
+          bottom = _canvasDom$getBoundin.bottom,
+          left = _canvasDom$getBoundin.left;
+
+      var paddingLeft = parseFloat(getStyle(canvasDom, 'padding-left'));
+      var paddingTop = parseFloat(getStyle(canvasDom, 'padding-top'));
+      var paddingRight = parseFloat(getStyle(canvasDom, 'padding-right'));
+      var paddingBottom = parseFloat(getStyle(canvasDom, 'padding-bottom'));
+      var width = right - left - paddingLeft - paddingRight;
+      var height = bottom - top - paddingTop - paddingBottom;
+      var pixelRatio = canvas.get('pixelRatio');
+      var mouseX = (point.x - left - paddingLeft) / width * canvasDom.width / pixelRatio;
+      var mouseY = (point.y - top - paddingTop) / height * canvasDom.height / pixelRatio;
+      return {
+        x: mouseX,
+        y: mouseY
+      };
+    }
+
+    function addEventListener(source, type, listener) {
+      source.addEventListener(type, listener, eventListenerOptions);
+    }
+
+    function removeEventListener(source, type, listener) {
+      source.removeEventListener(type, listener, eventListenerOptions);
+    }
+
+    function createEventObj(type, chart, x, y, nativeEvent) {
+      return {
+        type: type,
+        chart: chart,
+        "native": nativeEvent || null,
+        x: x !== undefined ? x : null,
+        y: y !== undefined ? y : null
+      };
+    }
+
+    function createEvent(event, chart) {
+      var type = event.type;
+      var clientPoint; // 说明是touch相关事件
+
+      if (event.touches) {
+        // https://developer.mozilla.org/zh-CN/docs/Web/API/TouchEvent/changedTouches
+        // 这里直接拿changedTouches就可以了,不管是touchstart, touchmove, touchend changedTouches 都是有的
+        // 为了以防万一,做个空判断
+        var touch = event.changedTouches[0] || {}; // x, y: 相对canvas原点的位置,clientX, clientY 相对于可视窗口的位置
+
+        var x = touch.x,
+            y = touch.y,
+            clientX = touch.clientX,
+            clientY = touch.clientY; // 小程序环境会有x,y,这里就直接返回
+
+        if (x && y) {
+          return createEventObj(type, chart, x, y, event);
+        }
+
+        clientPoint = {
+          x: clientX,
+          y: clientY
+        };
+      } else {
+        // mouse相关事件
+        clientPoint = {
+          x: event.clientX,
+          y: event.clientY
+        };
+      } // 理论上应该是只有有在浏览器环境才会走到这里
+
+
+      var canvas = chart.get('canvas'); // 通过clientX, clientY 计算x, y
+
+      var point = getRelativePosition(clientPoint, canvas);
+      return createEventObj(type, chart, point.x, point.y, event);
+    }
+
+    function measureText(text, font, ctx) {
+      if (!ctx) {
+        ctx = document.createElement('canvas').getContext('2d');
+      }
+
+      ctx.font = font || '12px sans-serif';
+      return ctx.measureText(text);
+    }
+    });
+
+    unwrapExports(dom);
+    var dom_1 = dom.isCanvasElement;
+    var dom_2 = dom.getPixelRatio;
+    var dom_3 = dom.getStyle;
+    var dom_4 = dom.getWidth;
+    var dom_5 = dom.getHeight;
+    var dom_6 = dom.getDomById;
+    var dom_7 = dom.getRelativePosition;
+    var dom_8 = dom.addEventListener;
+    var dom_9 = dom.removeEventListener;
+    var dom_10 = dom.createEvent;
+    var dom_11 = dom.measureText;
+    var dom_12 = dom.isBrowser;
+    var dom_13 = dom.isNode;
+    var dom_14 = dom.isMy;
+    var dom_15 = dom.isWx;
+
+    var common = createCommonjsModule(function (module, exports) {
+
+    exports.__esModule = true;
+    var _exportNames = {
+      isObjectValueEqual: true,
+      parsePadding: true,
+      directionEnabled: true,
+      toTimeStamp: true,
+      upperFirst: true,
+      lowerFirst: true,
+      isString: true,
+      isNumber: true,
+      isBoolean: true,
+      isFunction: true,
+      isDate: true,
+      isArray: true,
+      isNil: true,
+      isObject: true,
+      isPlainObject: true,
+      isEqual: true,
+      deepMix: true,
+      mix: true,
+      each: true,
+      uniq: true,
+      find: true,
+      Array: true
+    };
+    exports.isObjectValueEqual = isObjectValueEqual;
+    exports.parsePadding = parsePadding;
+    exports.directionEnabled = directionEnabled;
+    exports.toTimeStamp = toTimeStamp;
+    exports.Array = void 0;
+
+
+
+    exports.upperFirst = esm.upperFirst;
+    exports.lowerFirst = esm.lowerFirst;
+    exports.isString = esm.isString;
+    exports.isNumber = esm.isNumber;
+    exports.isBoolean = esm.isBoolean;
+    exports.isFunction = esm.isFunction;
+    exports.isDate = esm.isDate;
+    exports.isArray = esm.isArray;
+    exports.isNil = esm.isNil;
+    exports.isObject = esm.isObject;
+    exports.isPlainObject = esm.isPlainObject;
+    exports.isEqual = esm.isEqual;
+    exports.deepMix = esm.deepMix;
+    exports.mix = esm.mix;
+    exports.each = esm.each;
+    exports.uniq = esm.uniq;
+    exports.find = esm.find;
+
+    var ArrayUtil = _interopRequireWildcard(array$1);
+
+    exports.Array = ArrayUtil;
+
+
+
+    Object.keys(dom).forEach(function (key) {
+      if (key === "default" || key === "__esModule") return;
+      if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
+      if (key in exports && exports[key] === dom[key]) return;
+      exports[key] = dom[key];
+    });
+
+    function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; }
+
+    function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
+
+    /**
+     * @fileOverview Utility for F2
+     * @author dxq613 @gmail.com
+     * @author sima.zhang1990@gmail.com
+     */
+    function isObjectValueEqual(a, b) {
+      // for vue.js
+      a = Object.assign({}, a);
+      b = Object.assign({}, b);
+      var aProps = Object.getOwnPropertyNames(a);
+      var bProps = Object.getOwnPropertyNames(b);
+
+      if (aProps.length !== bProps.length) {
+        return false;
+      }
+
+      for (var i = 0, len = aProps.length; i < len; i++) {
+        var propName = aProps[i];
+
+        if (a[propName] !== b[propName]) {
+          return false;
+        }
+      }
+
+      return true;
+    }
+
+    function parsePadding(padding) {
+      var top;
+      var right;
+      var bottom;
+      var left;
+
+      if ((0, esm.isNumber)(padding) || (0, esm.isString)(padding)) {
+        top = bottom = left = right = padding;
+      } else if ((0, esm.isArray)(padding)) {
+        top = padding[0];
+        right = !(0, esm.isNil)(padding[1]) ? padding[1] : padding[0];
+        bottom = !(0, esm.isNil)(padding[2]) ? padding[2] : padding[0];
+        left = !(0, esm.isNil)(padding[3]) ? padding[3] : right;
+      }
+
+      return [top, right, bottom, left];
+    }
+
+    function directionEnabled(mode, dir) {
+      if (mode === undefined) {
+        return true;
+      } else if (typeof mode === 'string') {
+        return mode.indexOf(dir) !== -1;
+      }
+
+      return false;
+    }
+
+    function toTimeStamp(value) {
+      if ((0, esm.isString)(value)) {
+        if (value.indexOf('T') > 0) {
+          value = new Date(value).getTime();
+        } else {
+          // new Date('2010/01/10') 和 new Date('2010-01-10') 的差别在于:
+          // 如果仅有年月日时,前者是带有时区的: Fri Jan 10 2020 02:40:13 GMT+0800 (中国标准时间)
+          // 后者会格式化成 Sun Jan 10 2010 08:00:00 GMT+0800 (中国标准时间)
+          value = new Date(value.replace(/-/gi, '/')).getTime();
+        }
+      }
+
+      if ((0, esm.isDate)(value)) {
+        value = value.getTime();
+      }
+
+      return value;
+    }
+    });
+
+    unwrapExports(common);
+    var common_1 = common.isObjectValueEqual;
+    var common_2 = common.parsePadding;
+    var common_3 = common.directionEnabled;
+    var common_4 = common.toTimeStamp;
+    var common_5 = common.Array;
+    var common_6 = common.upperFirst;
+    var common_7 = common.lowerFirst;
+    var common_8 = common.isString;
+    var common_9 = common.isNumber;
+    var common_10 = common.isBoolean;
+    var common_11 = common.isFunction;
+    var common_12 = common.isDate;
+    var common_13 = common.isArray;
+    var common_14 = common.isNil;
+    var common_15 = common.isObject;
+    var common_16 = common.isPlainObject;
+    var common_17 = common.isEqual;
+    var common_18 = common.deepMix;
+    var common_19 = common.mix;
+    var common_20 = common.each;
+    var common_21 = common.uniq;
+    var common_22 = common.find;
+
+    var emit = createCommonjsModule(function (module, exports) {
+
+    exports.__esModule = true;
+    exports["default"] = void 0;
+
+
+
+    // 实现简单的事件机制
+    var EventEmit = /*#__PURE__*/function () {
+      function EventEmit() {
+        this.__events = {};
+      }
+
+      var _proto = EventEmit.prototype;
+
+      _proto.on = function on(type, listener) {
+        if (!type || !listener) {
+          return;
+        }
+
+        var events = this.__events[type] || [];
+        events.push(listener);
+        this.__events[type] = events;
+      };
+
+      _proto.emit = function emit(type, e) {
+        var _this = this;
+
+        if ((0, common.isObject)(type)) {
+          e = type;
+          type = e && e.type;
+        }
+
+        if (!type) {
+          return;
+        }
+
+        var events = this.__events[type];
+
+        if (!events || !events.length) {
+          return;
+        }
+
+        events.forEach(function (listener) {
+          listener.call(_this, e);
+        });
+      };
+
+      _proto.off = function off(type, listener) {
+        var __events = this.__events;
+        var events = __events[type];
+
+        if (!events || !events.length) {
+          return;
+        } // 如果没有指定方法,则删除所有项
+
+
+        if (!listener) {
+          delete __events[type];
+          return;
+        } // 删除指定的 listener
+
+
+        for (var i = 0, len = events.length; i < len; i++) {
+          if (events[i] === listener) {
+            events.splice(i, 1);
+            i--;
+          }
+        }
+      };
+
+      return EventEmit;
+    }();
+
+    var _default = EventEmit;
+    exports["default"] = _default;
+    });
+
+    unwrapExports(emit);
+
+    var controller = createCommonjsModule(function (module, exports) {
+
+    exports.__esModule = true;
+    exports["default"] = void 0;
+
+
+
+
+
+    function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
+
+    // 计算滑动的方向
+    var calcDirection = function calcDirection(start, end) {
+      var xDistance = end.x - start.x;
+      var yDistance = end.y - start.y; // x 的距离大于y 说明是横向,否则就是纵向
+
+      if (Math.abs(xDistance) > Math.abs(yDistance)) {
+        return xDistance > 0 ? 'right' : 'left';
+      }
+
+      return yDistance > 0 ? 'down' : 'up';
+    }; // 计算2点之间的距离
+
+
+    var calcDistance = function calcDistance(point1, point2) {
+      var xDistance = Math.abs(point2.x - point1.x);
+      var yDistance = Math.abs(point2.y - point1.y);
+      return Math.sqrt(xDistance * xDistance + yDistance * yDistance);
+    };
+
+    var getCenter = function getCenter(point1, point2) {
+      var x = point1.x + (point2.x - point1.x) / 2;
+      var y = point1.y + (point2.y - point1.y) / 2;
+      return {
+        x: x,
+        y: y
+      };
+    };
+
+    var convertPoints = function convertPoints(ev, canvas) {
+      var touches = ev.touches; // 认为是mouse事件
+
+      if (!touches) {
+        var point = (0, dom.getRelativePosition)({
+          x: ev.clientX,
+          y: ev.clientY
+        }, canvas);
+        return [point];
+      }
+
+      var points = [];
+      var len = touches.length;
+
+      for (var i = 0; i < len; i++) {
+        var touch = touches[i]; // x, y: 相对canvas原点的位置,clientX, clientY 相对于可视窗口的位置
+
+        var x = touch.x,
+            y = touch.y,
+            clientX = touch.clientX,
+            clientY = touch.clientY;
+
+        var _point = void 0; // 小程序环境会有x,y
+
+
+        if ((0, common.isNumber)(x) || (0, common.isNumber)(y)) {
+          _point = {
+            x: x,
+            y: y
+          };
+        } else {
+          // 浏览器环境再计算下canvas的相对位置
+          _point = (0, dom.getRelativePosition)({
+            x: clientX,
+            y: clientY
+          }, canvas);
+        }
+
+        points.push(_point);
+      }
+
+      return points;
+    };
+
+    var PRESS_DELAY = 250;
+
+    var EventController = /*#__PURE__*/function () {
+      function EventController(_ref) {
+        var _this = this;
+
+        var canvas = _ref.canvas,
+            el = _ref.el;
+
+        _defineProperty(this, "_click", function (ev) {
+          var points = convertPoints(ev, _this.canvas);
+          ev.points = points;
+
+          _this.emitEvent('click', ev);
+        });
+
+        _defineProperty(this, "_start", function (ev) {
+          var points = convertPoints(ev, _this.canvas);
+
+          if (!points) {
+            return;
+          }
+
+          ev.points = points;
+
+          _this.emitEvent('touchstart', ev); // 防止上次的内容没有清理掉,重新reset下
+
+
+          _this.reset(); // 记录touch start 的时间
+
+
+          _this.startTime = Date.now(); // 记录touch start 的点
+
+          _this.startPoints = points;
+
+          if (points.length > 1) {
+            _this.startDistance = calcDistance(points[0], points[1]);
+            _this.center = getCenter(points[0], points[1]);
+          } else {
+            // 如果touchstart后停顿250ms, 则也触发press事件
+            _this.pressTimeout = setTimeout(function () {
+              // 这里固定触发press事件
+              var eventType = 'press';
+              var direction = 'none';
+              ev.direction = direction;
+
+              _this.emitStart(eventType, ev);
+
+              _this.emitEvent(eventType, ev);
+
+              _this.eventType = eventType;
+              _this.direction = direction;
+            }, PRESS_DELAY);
+          }
+        });
+
+        _defineProperty(this, "_move", function (ev) {
+          var points = convertPoints(ev, _this.canvas);
+          if (!points) return;
+
+          _this.clearPressTimeout();
+
+          ev.points = points;
+
+          _this.emitEvent('touchmove', ev);
+
+          var startPoints = _this.startPoints;
+          if (!startPoints) return; // 多指触控
+
+          if (points.length > 1) {
+            // touchstart的距离
+            var startDistance = _this.startDistance;
+            var currentDistance = calcDistance(points[0], points[1]);
+            ev.zoom = currentDistance / startDistance;
+            ev.center = _this.center; // 触发缩放事件
+
+            _this.emitStart('pinch', ev);
+
+            _this.emitEvent('pinch', ev);
+          } else {
+            var deltaX = points[0].x - startPoints[0].x;
+            var deltaY = points[0].y - startPoints[0].y;
+            var direction = _this.direction || calcDirection(startPoints[0], points[0]);
+            _this.direction = direction; // 获取press或者pan的事件类型
+            // press 按住滑动, pan表示平移
+            // 如果start后立刻move,则触发pan, 如果有停顿,则触发press
+
+            var eventType = _this.getEventType(points);
+
+            ev.direction = direction;
+            ev.deltaX = deltaX;
+            ev.deltaY = deltaY;
+
+            _this.emitStart(eventType, ev);
+
+            _this.emitEvent(eventType, ev); // 记录最后2次move的时间和坐标,为了给swipe事件用
+
+
+            var prevMoveTime = _this.lastMoveTime;
+            var now = Date.now(); // 最后2次的时间间隔一定要大于0,否则swipe没发计算
+
+            if (now - prevMoveTime > 0) {
+              _this.prevMoveTime = prevMoveTime;
+              _this.prevMovePoints = _this.lastMovePoints;
+              _this.lastMoveTime = now;
+              _this.lastMovePoints = points;
+            }
+          }
+        });
+
+        _defineProperty(this, "_end", function (ev) {
+          _this.emitEnd(ev);
+
+          _this.emitEvent('touchend', ev); // swipe事件处理, 在touchend之后触发
+
+
+          var lastMoveTime = _this.lastMoveTime;
+          var now = Date.now(); // 做这个判断是为了最后一次touchmove后到end前,还有一个停顿的过程
+          // 100 是拍的一个值,理论这个值会很短,一般不卡顿的话在10ms以内
+
+          if (now - lastMoveTime < 100) {
+            var prevMoveTime = _this.prevMoveTime || _this.startTime;
+            var intervalTime = lastMoveTime - prevMoveTime; // 时间间隔一定要大于0, 否则计算没意义
+
+            if (intervalTime > 0) {
+              var prevMovePoints = _this.prevMovePoints || _this.startPoints;
+              var lastMovePoints = _this.lastMovePoints; // move速率
+
+              var velocity = calcDistance(prevMovePoints[0], lastMovePoints[0]) / intervalTime; // 0.3 是参考hammerjs的设置
+
+              if (velocity > 0.3) {
+                ev.velocity = velocity;
+                ev.direction = calcDirection(prevMovePoints[0], lastMovePoints[0]);
+
+                _this.emitEvent('swipe', ev);
+              }
+            }
+          }
+
+          _this.reset();
+
+          var touches = ev.touches; // 当多指只释放了1指时也会触发end, 这时重新触发一次start
+
+          if (touches && touches.length > 0) {
+            _this._start(ev);
+          }
+        });
+
+        _defineProperty(this, "_cancel", function (ev) {
+          _this.emitEvent('touchcancel', ev);
+
+          _this.reset();
+        });
+
+        // canvasEl
+        this.canvas = canvas;
+        this.delegateEvent(el); // 用来记录当前触发的事件
+
+        this.processEvent = {};
+      }
+
+      var _proto = EventController.prototype;
+
+      _proto.delegateEvent = function delegateEvent(canvasEl) {
+        // 代理这几个事件
+        canvasEl.addEventListener('click', this._click);
+        canvasEl.addEventListener('touchstart', this._start);
+        canvasEl.addEventListener('touchmove', this._move);
+        canvasEl.addEventListener('touchend', this._end);
+        canvasEl.addEventListener('touchcancel', this._cancel);
+      };
+
+      _proto.emitEvent = function emitEvent(type, ev) {
+        var canvas = this.canvas;
+        canvas.emit(type, ev);
+      };
+
+      _proto.getEventType = function getEventType(points) {
+        var eventType = this.eventType,
+            canvas = this.canvas,
+            startTime = this.startTime,
+            startPoints = this.startPoints;
+
+        if (eventType) {
+          return eventType;
+        }
+
+        var type;
+        var panEventListeners = canvas.__events.pan; // 如果没有pan事件的监听,默认都是press
+
+        if (!panEventListeners || !panEventListeners.length) {
+          type = 'press';
+        } else {
+          // 如果有pan事件的处理,press则需要停顿250ms, 且移动距离小于10
+          var now = Date.now();
+
+          if (now - startTime > PRESS_DELAY && calcDistance(startPoints[0], points[0]) < 10) {
+            type = 'press';
+          } else {
+            type = 'pan';
+          }
+        }
+
+        this.eventType = type;
+        return type;
+      };
+
+      _proto.enable = function enable(eventType) {
+        this.processEvent[eventType] = true;
+      } // 是否进行中的事件
+      ;
+
+      _proto.isProcess = function isProcess(eventType) {
+        return this.processEvent[eventType];
+      } // 触发start事件
+      ;
+
+      _proto.emitStart = function emitStart(type, ev) {
+        if (this.isProcess(type)) {
+          return;
+        }
+
+        this.enable(type);
+        this.emitEvent(type + "start", ev);
+      } // 触发end事件
+      ;
+
+      _proto.emitEnd = function emitEnd(ev) {
+        var _this2 = this;
+
+        var processEvent = this.processEvent;
+        Object.keys(processEvent).forEach(function (type) {
+          _this2.emitEvent(type + "end", ev);
+
+          delete processEvent[type];
+        });
+      };
+
+      _proto.clearPressTimeout = function clearPressTimeout() {
+        if (this.pressTimeout) {
+          clearTimeout(this.pressTimeout);
+          this.pressTimeout = 0;
+        }
+      };
+
+      _proto.reset = function reset() {
+        this.clearPressTimeout();
+        this.startTime = 0;
+        this.startPoints = null;
+        this.startDistance = 0;
+        this.direction = null;
+        this.eventType = null;
+        this.pinch = false;
+        this.prevMoveTime = 0;
+        this.prevMovePoints = null;
+        this.lastMoveTime = 0;
+        this.lastMovePoints = null;
+      };
+
+      return EventController;
+    }();
+
+    var _default = EventController;
+    exports["default"] = _default;
+    });
+
+    unwrapExports(controller);
+
+    var canvasElement = createCommonjsModule(function (module, exports) {
+
+    exports.__esModule = true;
+    exports["default"] = void 0;
+
+    var _emit = _interopRequireDefault(emit);
+
+    function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
+
+    function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; }
+
+    var CanvasElement = /*#__PURE__*/function (_EventEmit) {
+      _inheritsLoose(CanvasElement, _EventEmit);
+
+      function CanvasElement(ctx) {
+        var _this;
+
+        _this = _EventEmit.call(this) || this;
+        _this.context = ctx; // canvas实际的宽高 (width/height) * pixelRatio
+
+        _this.width = 0;
+        _this.height = 0;
+        _this.style = {};
+        _this.currentStyle = {}; // 用来标识是CanvasElement实例
+
+        _this.isCanvasElement = true;
+        return _this;
+      }
+
+      var _proto = CanvasElement.prototype;
+
+      _proto.getContext = function getContext()
+      /* type */
+      {
+        return this.context;
+      };
+
+      _proto.getBoundingClientRect = function getBoundingClientRect() {
+        var width = this.width;
+        var height = this.height; // 默认都处理成可视窗口的顶部位置
+
+        return {
+          top: 0,
+          right: width,
+          bottom: height,
+          left: 0
+        };
+      };
+
+      _proto.addEventListener = function addEventListener(type, listener) {
+        this.on(type, listener);
+      };
+
+      _proto.removeEventListener = function removeEventListener(type, listener) {
+        this.off(type, listener);
+      };
+
+      _proto.dispatchEvent = function dispatchEvent(type, e) {
+        this.emit(type, e);
+      };
+
+      return CanvasElement;
+    }(_emit["default"]);
+
+    function supportEventListener(canvas) {
+      if (!canvas) {
+        return false;
+      } // 非 HTMLCanvasElement
+
+
+      if (canvas.nodeType !== 1 || !canvas.nodeName || canvas.nodeName.toLowerCase() !== 'canvas') {
+        return false;
+      } // 微信小程序canvas.getContext('2d')时也是CanvasRenderingContext2D
+      // 也会有ctx.canvas, 而且nodeType也是1,所以还要在看下是否支持addEventListener
+
+
+      var support = false;
+
+      try {
+        canvas.addEventListener('eventTest', function () {
+          support = true;
+        });
+        canvas.dispatchEvent(new Event('eventTest'));
+      } catch (error) {
+        support = false;
+      }
+
+      return support;
+    }
+
+    var _default = {
+      create: function create(ctx) {
+        if (!ctx) {
+          return null;
+        }
+
+        if (supportEventListener(ctx.canvas)) {
+          return ctx.canvas;
+        }
+
+        return new CanvasElement(ctx);
+      }
+    };
+    exports["default"] = _default;
+    });
+
+    unwrapExports(canvasElement);
+
+    var matrix = createCommonjsModule(function (module, exports) {
+
+    exports.__esModule = true;
+    exports["default"] = void 0;
+    var Matrix = {
+      generateDefault: function generateDefault() {
+        return [1, 0, 0, 1, 0, 0];
+      },
+      isChanged: function isChanged(m) {
+        return m[0] !== 1 || m[1] !== 0 || m[2] !== 0 || m[3] !== 1 || m[4] !== 0 || m[5] !== 0;
+      },
+      multiply: function multiply(m1, m2) {
+        var m11 = m1[0] * m2[0] + m1[2] * m2[1];
+        var m12 = m1[1] * m2[0] + m1[3] * m2[1];
+        var m21 = m1[0] * m2[2] + m1[2] * m2[3];
+        var m22 = m1[1] * m2[2] + m1[3] * m2[3];
+        var dx = m1[0] * m2[4] + m1[2] * m2[5] + m1[4];
+        var dy = m1[1] * m2[4] + m1[3] * m2[5] + m1[5];
+        return [m11, m12, m21, m22, dx, dy];
+      },
+      scale: function scale(out, m, v) {
+        out[0] = m[0] * v[0];
+        out[1] = m[1] * v[0];
+        out[2] = m[2] * v[1];
+        out[3] = m[3] * v[1];
+        out[4] = m[4];
+        out[5] = m[5];
+        return out;
+      },
+      rotate: function rotate(out, m, radian) {
+        var c = Math.cos(radian);
+        var s = Math.sin(radian);
+        var m11 = m[0] * c + m[2] * s;
+        var m12 = m[1] * c + m[3] * s;
+        var m21 = m[0] * -s + m[2] * c;
+        var m22 = m[1] * -s + m[3] * c;
+        out[0] = m11;
+        out[1] = m12;
+        out[2] = m21;
+        out[3] = m22;
+        out[4] = m[4];
+        out[5] = m[5];
+        return out;
+      },
+      translate: function translate(out, m, v) {
+        out[0] = m[0];
+        out[1] = m[1];
+        out[2] = m[2];
+        out[3] = m[3];
+        out[4] = m[4] + m[0] * v[0] + m[2] * v[1];
+        out[5] = m[5] + m[1] * v[0] + m[3] * v[1];
+        return out;
+      },
+      transform: function transform(m, actions) {
+        var out = [].concat(m);
+
+        for (var i = 0, len = actions.length; i < len; i++) {
+          var action = actions[i];
+
+          switch (action[0]) {
+            case 't':
+              Matrix.translate(out, out, [action[1], action[2]]);
+              break;
+
+            case 's':
+              Matrix.scale(out, out, [action[1], action[2]]);
+              break;
+
+            case 'r':
+              Matrix.rotate(out, out, action[1]);
+              break;
+          }
+        }
+
+        return out;
+      }
+    };
+    var _default = Matrix;
+    exports["default"] = _default;
+    });
+
+    unwrapExports(matrix);
+
+    var vector2 = createCommonjsModule(function (module, exports) {
+
+    exports.__esModule = true;
+    exports["default"] = void 0;
+
+    /**
+     * 2 Dimensional Vector
+     * @module vector2
+     */
+    var _default = {
+      /**
+       * Creates a new, empty vector2
+       *
+       * @return {vector2} a new 2D vector
+       */
+      create: function create() {
+        return [0, 0];
+      },
+
+      /**
+       * Calculates the length of a vector2
+       *
+       * @param {vector2} v vector to calculate length of
+       * @return {Number} length of v
+       */
+      length: function length(v) {
+        var x = v[0];
+        var y = v[1];
+        return Math.sqrt(x * x + y * y);
+      },
+
+      /**
+       * Normalize a vector2
+       *
+       * @param {vector2} out the receiving vector
+       * @param {vector2} v vector to normalize
+       * @return {vector2} out
+       */
+      normalize: function normalize(out, v) {
+        var len = this.length(v);
+
+        if (len === 0) {
+          out[0] = 0;
+          out[1] = 0;
+        } else {
+          out[0] = v[0] / len;
+          out[1] = v[1] / len;
+        }
+
+        return out;
+      },
+
+      /**
+       * Adds two vector2's
+       *
+       * @param {vector2} out the receiving vector
+       * @param {vector2} v1 the first operand
+       * @param {vector2} v2 the second operand
+       * @return {vector2} out
+       */
+      add: function add(out, v1, v2) {
+        out[0] = v1[0] + v2[0];
+        out[1] = v1[1] + v2[1];
+        return out;
+      },
+
+      /**
+       * Subtracts vector v2 from vector v1
+       *
+       * @param {vector2} out the receiving vector
+       * @param {vector2} v1 the first operand
+       * @param {vector2} v2 the second operand
+       * @return {vector2} out
+       */
+      sub: function sub(out, v1, v2) {
+        out[0] = v1[0] - v2[0];
+        out[1] = v1[1] - v2[1];
+        return out;
+      },
+
+      /**
+       * Scales a vector2 by a scalar number
+       *
+       * @param {vector2} out the receiving vector
+       * @param {vector2} v the vector to scale
+       * @param {Number} s amount to scale the vector by
+       * @return {vector2} out
+       */
+      scale: function scale(out, v, s) {
+        out[0] = v[0] * s;
+        out[1] = v[1] * s;
+        return out;
+      },
+
+      /**
+       * Calculates the dot product of two vector2's
+       *
+       * @param {vector2} v1 the first operand
+       * @param {vector2} v2 the second operand
+       * @return {Number} dot product of v1 and v2
+       */
+      dot: function dot(v1, v2) {
+        return v1[0] * v2[0] + v1[1] * v2[1];
+      },
+
+      /**
+       * Calculates the direction of two vector2's
+       *
+       * @param {vector2} v1 the first operand
+       * @param {vector2} v2 the second operand
+       * @return {Boolean} the direction of v1 and v2
+       */
+      direction: function direction(v1, v2) {
+        return v1[0] * v2[1] - v2[0] * v1[1];
+      },
+
+      /**
+       * Calculates the angle of two vector2's
+       *
+       * @param {vector2} v1 the first operand
+       * @param {vector2} v2 the second operand
+       * @return {Number} angle of v1 and v2
+       */
+      angle: function angle(v1, v2) {
+        var theta = this.dot(v1, v2) / (this.length(v1) * this.length(v2));
+        return Math.acos(theta);
+      },
+
+      /**
+       * Calculates the angle of two vector2's with direction
+       *
+       * @param {vector2} v1 the first operand
+       * @param {vector2} v2 the second operand
+       * @param {Boolean} direction the direction of two vector2's
+       * @return {Number} angle of v1 and v2
+       */
+      angleTo: function angleTo(v1, v2, direction) {
+        var angle = this.angle(v1, v2);
+        var angleLargeThanPI = this.direction(v1, v2) >= 0;
+
+        if (direction) {
+          if (angleLargeThanPI) {
+            return Math.PI * 2 - angle;
+          }
+
+          return angle;
+        }
+
+        if (angleLargeThanPI) {
+          return angle;
+        }
+
+        return Math.PI * 2 - angle;
+      },
+
+      /**
+       * whether a vector2 is zero vector
+       *
+       * @param  {vector2} v vector to calculate
+       * @return {Boolean}   is or not a zero vector
+       */
+      zero: function zero(v) {
+        return v[0] === 0 && v[1] === 0;
+      },
+
+      /**
+       * Calculates the euclidian distance between two vector2's
+       *
+       * @param {vector2} v1 the first operand
+       * @param {vector2} v2 the second operand
+       * @return {Number} distance between a and b
+       */
+      distance: function distance(v1, v2) {
+        var x = v2[0] - v1[0];
+        var y = v2[1] - v1[1];
+        return Math.sqrt(x * x + y * y);
+      },
+
+      /**
+       * Creates a new vector2 initialized with values from an existing vector
+       *
+       * @param {vector2} v vector to clone
+       * @return {Array} a new 2D vector
+       */
+      clone: function clone(v) {
+        return [v[0], v[1]];
+      },
+
+      /**
+       * Return the minimum of two vector2's
+       *
+       * @param {vector2} out the receiving vector
+       * @param {vector2} v1 the first operand
+       * @param {vector2} v2 the second operand
+       * @return {vector2} out
+       */
+      min: function min(out, v1, v2) {
+        out[0] = Math.min(v1[0], v2[0]);
+        out[1] = Math.min(v1[1], v2[1]);
+        return out;
+      },
+
+      /**
+       * Return the maximum of two vector2's
+       *
+       * @param {vector2} out the receiving vector
+       * @param {vector2} v1 the first operand
+       * @param {vector2} v2 the second operand
+       * @return {vector2} out
+       */
+      max: function max(out, v1, v2) {
+        out[0] = Math.max(v1[0], v2[0]);
+        out[1] = Math.max(v1[1], v2[1]);
+        return out;
+      },
+
+      /**
+       * Transforms the vector2 with a mat2d
+       *
+       * @param {vector2} out the receiving vector
+       * @param {vector2} v the vector to transform
+       * @param {mat2d} m matrix to transform with
+       * @return {vector2} out
+       */
+      transformMat2d: function transformMat2d(out, v, m) {
+        var x = v[0];
+        var y = v[1];
+        out[0] = m[0] * x + m[2] * y + m[4];
+        out[1] = m[1] * x + m[3] * y + m[5];
+        return out;
+      }
+    };
+    exports["default"] = _default;
+    });
+
+    unwrapExports(vector2);
+
+    var styleParse = createCommonjsModule(function (module, exports) {
+
+    exports.__esModule = true;
+    exports.parseStyle = parseStyle;
+    exports["default"] = void 0;
+
+
+
+    function _mod(n, m) {
+      return (n % m + m) % m;
+    }
+
+    function _addStop(steps, gradient) {
+      (0, common.each)(steps, function (item) {
+        item = item.split(':');
+        gradient.addColorStop(Number(item[0]), item[1]);
+      });
+    } // the string format: 'l(0) 0:#ffffff 0.5:#7ec2f3 1:#1890ff'
+
+
+    function _parseLineGradient(color, shape, context) {
+      var arr = color.split(' ');
+      var angle = arr[0].slice(2, arr[0].length - 1);
+      angle = _mod(parseFloat(angle) * Math.PI / 180, Math.PI * 2);
+      var steps = arr.slice(1);
+
+      var _shape$getBBox = shape.getBBox(),
+          minX = _shape$getBBox.minX,
+          minY = _shape$getBBox.minY,
+          maxX = _shape$getBBox.maxX,
+          maxY = _shape$getBBox.maxY;
+
+      var start;
+      var end;
+
+      if (angle >= 0 && angle < 0.5 * Math.PI) {
+        start = {
+          x: minX,
+          y: minY
+        };
+        end = {
+          x: maxX,
+          y: maxY
+        };
+      } else if (0.5 * Math.PI <= angle && angle < Math.PI) {
+        start = {
+          x: maxX,
+          y: minY
+        };
+        end = {
+          x: minX,
+          y: maxY
+        };
+      } else if (Math.PI <= angle && angle < 1.5 * Math.PI) {
+        start = {
+          x: maxX,
+          y: maxY
+        };
+        end = {
+          x: minX,
+          y: minY
+        };
+      } else {
+        start = {
+          x: minX,
+          y: maxY
+        };
+        end = {
+          x: maxX,
+          y: minY
+        };
+      }
+
+      var tanTheta = Math.tan(angle);
+      var tanTheta2 = tanTheta * tanTheta;
+      var x = (end.x - start.x + tanTheta * (end.y - start.y)) / (tanTheta2 + 1) + start.x;
+      var y = tanTheta * (end.x - start.x + tanTheta * (end.y - start.y)) / (tanTheta2 + 1) + start.y;
+      var gradient = context.createLinearGradient(start.x, start.y, x, y);
+
+      _addStop(steps, gradient);
+
+      return gradient;
+    } // the string format: 'r(0.5, 0.5, 0.1) 0:#ffffff 1:#1890ff'
+
+
+    function _parseRadialGradient(color, shape, context) {
+      var arr = color.split(' ');
+      var circleCfg = arr[0].slice(2, arr[0].length - 1);
+      circleCfg = circleCfg.split(',');
+      var fx = parseFloat(circleCfg[0]);
+      var fy = parseFloat(circleCfg[1]);
+      var fr = parseFloat(circleCfg[2]);
+      var steps = arr.slice(1); // if radius is 0, no gradient, stroke with the last color
+
+      if (fr === 0) {
+        var _color = steps[steps.length - 1];
+        return _color.split(':')[1];
+      }
+
+      var _shape$getBBox2 = shape.getBBox(),
+          width = _shape$getBBox2.width,
+          height = _shape$getBBox2.height,
+          minX = _shape$getBBox2.minX,
+          minY = _shape$getBBox2.minY;
+
+      var r = Math.sqrt(width * width + height * height) / 2;
+      var gradient = context.createRadialGradient(minX + width * fx, minY + height * fy, fr * r, minX + width / 2, minY + height / 2, r);
+
+      _addStop(steps, gradient);
+
+      return gradient;
+    }
+
+    function parseStyle(color, shape, context) {
+      if (color[1] === '(') {
+        try {
+          var firstCode = color[0];
+
+          if (firstCode === 'l') {
+            return _parseLineGradient(color, shape, context);
+          } else if (firstCode === 'r') {
+            return _parseRadialGradient(color, shape, context);
+          }
+        } catch (ev) {
+          console.error('error in parsing gradient string, please check if there are any extra whitespaces.');
+          console.error(ev);
+        }
+      }
+
+      return color;
+    }
+
+    var _default = {
+      parseStyle: parseStyle
+    };
+    exports["default"] = _default;
+    });
+
+    unwrapExports(styleParse);
+    var styleParse_1 = styleParse.parseStyle;
+
+    var element = createCommonjsModule(function (module, exports) {
+
+    exports.__esModule = true;
+    exports["default"] = void 0;
+
+
+
+    var _matrix = _interopRequireDefault(matrix);
+
+    var _vector = _interopRequireDefault(vector2);
+
+
+
+    function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
+
+    var ALIAS_ATTRS_MAP = {
+      stroke: 'strokeStyle',
+      fill: 'fillStyle',
+      opacity: 'globalAlpha'
+    };
+    var SHAPE_ATTRS = ['fillStyle', 'font', 'globalAlpha', 'lineCap', 'lineWidth', 'lineJoin', 'miterLimit', 'shadowBlur', 'shadowColor', 'shadowOffsetX', 'shadowOffsetY', 'strokeStyle', 'textAlign', 'textBaseline', 'lineDash', 'shadow' // 兼容支付宝小程序
+    ];
+    var CLIP_SHAPES = ['circle', 'sector', 'polygon', 'rect', 'polyline'];
+
+    var Element = /*#__PURE__*/function () {
+      var _proto = Element.prototype;
+
+      _proto._initProperties = function _initProperties() {
+        this._attrs = {
+          zIndex: 0,
+          visible: true,
+          destroyed: false
+        };
+      };
+
+      function Element(cfg) {
+        this._initProperties();
+
+        (0, common.mix)(this._attrs, cfg);
+        var attrs = this._attrs.attrs;
+
+        if (attrs) {
+          this.initAttrs(attrs);
+        }
+
+        this.initTransform();
+      }
+
+      _proto.get = function get(name) {
+        return this._attrs[name];
+      };
+
+      _proto.set = function set(name, value) {
+        this._attrs[name] = value;
+      };
+
+      _proto.isGroup = function isGroup() {
+        return this.get('isGroup');
+      };
+
+      _proto.isShape = function isShape() {
+        return this.get('isShape');
+      };
+
+      _proto.initAttrs = function initAttrs(attrs) {
+        this.attr((0, common.mix)(this.getDefaultAttrs(), attrs));
+      };
+
+      _proto.getDefaultAttrs = function getDefaultAttrs() {
+        return {};
+      };
+
+      _proto._setAttr = function _setAttr(name, value) {
+        var attrs = this._attrs.attrs;
+
+        if (name === 'clip') {
+          value = this._setAttrClip(value);
+        } else {
+          var alias = ALIAS_ATTRS_MAP[name];
+
+          if (alias) {
+            attrs[alias] = value;
+          }
+        }
+
+        attrs[name] = value;
+      };
+
+      _proto._getAttr = function _getAttr(name) {
+        return this._attrs.attrs[name];
+      } // _afterAttrsSet() {}
+      ;
+
+      _proto._setAttrClip = function _setAttrClip(clip) {
+        if (clip && CLIP_SHAPES.indexOf(clip._attrs.type) > -1) {
+          if (clip.get('canvas') === null) {
+            clip = Object.assign({}, clip);
+          }
+
+          clip.set('parent', this.get('parent'));
+          clip.set('context', this.get('context'));
+          return clip;
+        }
+
+        return null;
+      };
+
+      _proto.attr = function attr(name, value) {
+        var self = this;
+        if (self.get('destroyed')) return null;
+        var argumentsLen = arguments.length;
+
+        if (argumentsLen === 0) {
+          return self._attrs.attrs;
+        }
+
+        if ((0, common.isObject)(name)) {
+          this._attrs.bbox = null;
+
+          for (var k in name) {
+            self._setAttr(k, name[k]);
+          }
+
+          if (self._afterAttrsSet) {
+            self._afterAttrsSet();
+          }
+
+          return self;
+        }
+
+        if (argumentsLen === 2) {
+          this._attrs.bbox = null;
+
+          self._setAttr(name, value);
+
+          if (self._afterAttrsSet) {
+            self._afterAttrsSet();
+          }
+
+          return self;
+        }
+
+        return self._getAttr(name);
+      };
+
+      _proto.getParent = function getParent() {
+        return this.get('parent');
+      };
+
+      _proto.draw = function draw(context) {
+        if (this.get('destroyed')) {
+          return;
+        }
+
+        if (this.get('visible')) {
+          this.setContext(context);
+          this.drawInner(context);
+          this.restoreContext(context);
+        }
+      };
+
+      _proto.setContext = function setContext(context) {
+        var clip = this._attrs.attrs.clip;
+        context.save();
+
+        if (clip) {
+          clip.resetTransform(context);
+          clip.createPath(context);
+          context.clip();
+        }
+
+        this.resetContext(context);
+        this.resetTransform(context);
+      };
+
+      _proto.restoreContext = function restoreContext(context) {
+        context.restore();
+      };
+
+      _proto.resetContext = function resetContext(context) {
+        var elAttrs = this._attrs.attrs;
+
+        if (!this._attrs.isGroup) {
+          for (var k in elAttrs) {
+            if (SHAPE_ATTRS.indexOf(k) > -1) {
+              var v = elAttrs[k];
+
+              if (k === 'fillStyle' || k === 'strokeStyle') {
+                v = (0, styleParse.parseStyle)(v, this, context);
+              }
+
+              if (k === 'lineDash' && context.setLineDash && (0, common.isArray)(v)) {
+                context.setLineDash(v);
+              } else {
+                context[k] = v;
+              }
+            }
+          }
+        }
+      };
+
+      _proto.hasFill = function hasFill() {
+        return this.get('canFill') && this._attrs.attrs.fillStyle;
+      };
+
+      _proto.hasStroke = function hasStroke() {
+        return this.get('canStroke') && this._attrs.attrs.strokeStyle;
+      };
+
+      _proto.drawInner = function drawInner()
+      /* context */
+      {};
+
+      _proto.show = function show() {
+        this.set('visible', true);
+        return this;
+      };
+
+      _proto.hide = function hide() {
+        this.set('visible', false);
+        return this;
+      };
+
+      _proto.isVisible = function isVisible() {
+        return this.get('visible');
+      };
+
+      _proto._removeFromParent = function _removeFromParent() {
+        var parent = this.get('parent');
+
+        if (parent) {
+          var children = parent.get('children');
+
+          common.Array.remove(children, this);
+        }
+
+        return this;
+      };
+
+      _proto.remove = function remove(destroy) {
+        if (destroy) {
+          this.destroy();
+        } else {
+          this._removeFromParent();
+        }
+      };
+
+      _proto.destroy = function destroy() {
+        var destroyed = this.get('destroyed');
+
+        if (destroyed) {
+          return null;
+        }
+
+        this._removeFromParent();
+
+        this._attrs = {};
+        this.set('destroyed', true);
+      };
+
+      _proto.getBBox = function getBBox() {
+        return {
+          minX: 0,
+          maxX: 0,
+          minY: 0,
+          maxY: 0,
+          width: 0,
+          height: 0
+        };
+      };
+
+      _proto.initTransform = function initTransform() {
+        var attrs = this._attrs.attrs || {};
+
+        if (!attrs.matrix) {
+          attrs.matrix = [1, 0, 0, 1, 0, 0];
+        }
+
+        this._attrs.attrs = attrs;
+      };
+
+      _proto.getMatrix = function getMatrix() {
+        return this._attrs.attrs.matrix;
+      };
+
+      _proto.setMatrix = function setMatrix(m) {
+        this._attrs.attrs.matrix = [m[0], m[1], m[2], m[3], m[4], m[5]];
+      };
+
+      _proto.transform = function transform(actions) {
+        var matrix = this._attrs.attrs.matrix;
+        this._attrs.attrs.matrix = _matrix["default"].transform(matrix, actions);
+        return this;
+      };
+
+      _proto.setTransform = function setTransform(actions) {
+        this._attrs.attrs.matrix = [1, 0, 0, 1, 0, 0];
+        return this.transform(actions);
+      };
+
+      _proto.translate = function translate(x, y) {
+        var matrix = this._attrs.attrs.matrix;
+
+        _matrix["default"].translate(matrix, matrix, [x, y]);
+      };
+
+      _proto.rotate = function rotate(rad) {
+        var matrix = this._attrs.attrs.matrix;
+
+        _matrix["default"].rotate(matrix, matrix, rad);
+      };
+
+      _proto.scale = function scale(sx, sy) {
+        var matrix = this._attrs.attrs.matrix;
+
+        _matrix["default"].scale(matrix, matrix, [sx, sy]);
+      };
+
+      _proto.moveTo = function moveTo(x, y) {
+        var cx = this._attrs.x || 0;
+        var cy = this._attrs.y || 0;
+        this.translate(x - cx, y - cy);
+        this.set('x', x);
+        this.set('y', y);
+      };
+
+      _proto.apply = function apply(v) {
+        var m = this._attrs.attrs.matrix;
+
+        _vector["default"].transformMat2d(v, v, m);
+
+        return this;
+      };
+
+      _proto.resetTransform = function resetTransform(context) {
+        var mo = this._attrs.attrs.matrix;
+
+        if (_matrix["default"].isChanged(mo)) {
+          context.transform(mo[0], mo[1], mo[2], mo[3], mo[4], mo[5]);
+        }
+      };
+
+      _proto.isDestroyed = function isDestroyed() {
+        return this.get('destroyed');
+      };
+
+      return Element;
+    }();
+
+    var _default = Element;
+    exports["default"] = _default;
+    });
+
+    unwrapExports(element);
+
+    var shape = createCommonjsModule(function (module, exports) {
+
+    exports.__esModule = true;
+    exports["default"] = void 0;
+
+
+
+    var _element = _interopRequireDefault(element);
+
+    function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
+
+    function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; }
+
+    var Shape = /*#__PURE__*/function (_Element) {
+      _inheritsLoose(Shape, _Element);
+
+      function Shape() {
+        return _Element.apply(this, arguments) || this;
+      }
+
+      var _proto = Shape.prototype;
+
+      _proto._initProperties = function _initProperties() {
+        this._attrs = {
+          zIndex: 0,
+          visible: true,
+          destroyed: false,
+          isShape: true,
+          attrs: {}
+        };
+      };
+
+      _proto.getType = function getType() {
+        return this._attrs.type;
+      };
+
+      _proto.drawInner = function drawInner(context) {
+        var self = this;
+        var attrs = self.get('attrs');
+        self.createPath(context);
+        var originOpacity = context.globalAlpha;
+
+        if (self.hasFill()) {
+          var fillOpacity = attrs.fillOpacity;
+
+          if (!(0, common.isNil)(fillOpacity) && fillOpacity !== 1) {
+            context.globalAlpha = fillOpacity;
+            context.fill();
+            context.globalAlpha = originOpacity;
+          } else {
+            context.fill();
+          }
+        }
+
+        if (self.hasStroke()) {
+          var lineWidth = attrs.lineWidth;
+
+          if (lineWidth > 0) {
+            var strokeOpacity = attrs.strokeOpacity;
+
+            if (!(0, common.isNil)(strokeOpacity) && strokeOpacity !== 1) {
+              context.globalAlpha = strokeOpacity;
+            }
+
+            context.stroke();
+          }
+        }
+      };
+
+      _proto.getBBox = function getBBox() {
+        var bbox = this._attrs.bbox;
+
+        if (!bbox) {
+          bbox = this.calculateBox();
+
+          if (bbox) {
+            bbox.x = bbox.minX;
+            bbox.y = bbox.minY;
+            bbox.width = bbox.maxX - bbox.minX;
+            bbox.height = bbox.maxY - bbox.minY;
+          }
+
+          this._attrs.bbox = bbox;
+        }
+
+        return bbox;
+      };
+
+      _proto.calculateBox = function calculateBox() {
+        return null;
+      };
+
+      _proto.createPath = function createPath() {};
+
+      return Shape;
+    }(_element["default"]);
+
+    var _default = Shape;
+    exports["default"] = _default;
+    });
+
+    unwrapExports(shape);
+
+    var container = createCommonjsModule(function (module, exports) {
+
+    exports.__esModule = true;
+    exports["default"] = void 0;
+
+
+
+    var _shape = _interopRequireDefault(shape);
+
+    function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
+
+    var SHAPE_MAP = {};
+    var INDEX = '_INDEX';
+
+    function getComparer(compare) {
+      return function (left, right) {
+        var result = compare(left, right);
+        return result === 0 ? left[INDEX] - right[INDEX] : result;
+      };
+    }
+
+    var _default = {
+      getGroupClass: function getGroupClass() {},
+      getChildren: function getChildren() {
+        return this.get('children');
+      },
+      addShape: function addShape(type, cfg) {
+        if (cfg === void 0) {
+          cfg = {};
+        }
+
+        var canvas = this.get('canvas');
+        var shapeType = SHAPE_MAP[type];
+
+        if (!shapeType) {
+          shapeType = (0, common.upperFirst)(type);
+          SHAPE_MAP[type] = shapeType;
+        }
+
+        cfg.canvas = canvas;
+
+        if (shapeType === 'Text' && canvas && canvas.get('fontFamily')) {
+          cfg.attrs.fontFamily = cfg.attrs.fontFamily || canvas.get('fontFamily');
+        }
+
+        var shape = new _shape["default"][shapeType](cfg);
+        this.add(shape);
+        return shape;
+      },
+      addGroup: function addGroup(cfg) {
+        var canvas = this.get('canvas');
+        var groupClass = this.getGroupClass();
+        cfg = (0, common.mix)({}, cfg);
+        cfg.canvas = canvas;
+        cfg.parent = this;
+        var rst = new groupClass(cfg);
+        this.add(rst);
+        return rst;
+      },
+      contain: function contain(item) {
+        var children = this.get('children');
+        return children.indexOf(item) > -1;
+      },
+      sort: function sort() {
+        var children = this.get('children');
+
+        for (var i = 0, len = children.length; i < len; i++) {
+          var child = children[i];
+          child[INDEX] = i;
+        }
+
+        children.sort(getComparer(function (obj1, obj2) {
+          return obj1.get('zIndex') - obj2.get('zIndex');
+        }));
+        return this;
+      },
+      drawInner: function drawInner(context) {
+        var children = this.get('children');
+
+        for (var i = 0, len = children.length; i < len; i++) {
+          var child = children[i];
+          child.draw(context);
+        }
+
+        return this;
+      },
+      clear: function clear() {
+        var children = this.get('children');
+
+        while (children.length !== 0) {
+          children[children.length - 1].remove(true);
+        }
+
+        return this;
+      },
+      add: function add(items) {
+        var self = this;
+        var children = self.get('children');
+
+        if (!(0, common.isArray)(items)) {
+          items = [items];
+        }
+
+        for (var i = 0, len = items.length; i < len; i++) {
+          var item = items[i];
+          var parent = item.get('parent');
+
+          if (parent) {
+            var descendants = parent.get('children');
+
+            common.Array.remove(descendants, item);
+          }
+
+          self._setEvn(item);
+
+          children.push(item);
+        }
+
+        return self;
+      },
+      _setEvn: function _setEvn(item) {
+        var self = this;
+        item._attrs.parent = self;
+        item._attrs.context = self._attrs.context;
+        item._attrs.canvas = self._attrs.canvas;
+        var clip = item._attrs.attrs.clip;
+
+        if (clip) {
+          clip.set('parent', self);
+          clip.set('context', self.get('context'));
+        }
+
+        if (item._attrs.isGroup) {
+          var children = item._attrs.children;
+
+          for (var i = 0, len = children.length; i < len; i++) {
+            item._setEvn(children[i]);
+          }
+        }
+      }
+    };
+    exports["default"] = _default;
+    });
+
+    unwrapExports(container);
+
+    var group$2 = createCommonjsModule(function (module, exports) {
+
+    exports.__esModule = true;
+    exports["default"] = void 0;
+
+
+
+    var _element = _interopRequireDefault(element);
+
+    var _container = _interopRequireDefault(container);
+
+    var _vector = _interopRequireDefault(vector2);
+
+    function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
+
+    function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; }
+
+    var Group = /*#__PURE__*/function (_Element) {
+      _inheritsLoose(Group, _Element);
+
+      function Group() {
+        return _Element.apply(this, arguments) || this;
+      }
+
+      var _proto = Group.prototype;
+
+      _proto._initProperties = function _initProperties() {
+        this._attrs = {
+          zIndex: 0,
+          visible: true,
+          destroyed: false,
+          isGroup: true,
+          children: []
+        };
+      };
+
+      _proto.getBBox = function getBBox() {
+        var self = this;
+        var minX = Infinity;
+        var maxX = -Infinity;
+        var minY = Infinity;
+        var maxY = -Infinity;
+        var children = self.get('children');
+
+        for (var i = 0, length = children.length; i < length; i++) {
+          var child = children[i];
+
+          if (child.get('visible')) {
+            var box = child.getBBox();
+
+            if (!box) {
+              continue;
+            }
+
+            var leftTop = [box.minX, box.minY];
+            var leftBottom = [box.minX, box.maxY];
+            var rightTop = [box.maxX, box.minY];
+            var rightBottom = [box.maxX, box.maxY];
+            var matrix = child.attr('matrix');
+
+            _vector["default"].transformMat2d(leftTop, leftTop, matrix);
+
+            _vector["default"].transformMat2d(leftBottom, leftBottom, matrix);
+
+            _vector["default"].transformMat2d(rightTop, rightTop, matrix);
+
+            _vector["default"].transformMat2d(rightBottom, rightBottom, matrix);
+
+            minX = Math.min(leftTop[0], leftBottom[0], rightTop[0], rightBottom[0], minX);
+            maxX = Math.max(leftTop[0], leftBottom[0], rightTop[0], rightBottom[0], maxX);
+            minY = Math.min(leftTop[1], leftBottom[1], rightTop[1], rightBottom[1], minY);
+            maxY = Math.max(leftTop[1], leftBottom[1], rightTop[1], rightBottom[1], maxY);
+          }
+        }
+
+        return {
+          minX: minX,
+          minY: minY,
+          maxX: maxX,
+          maxY: maxY,
+          x: minX,
+          y: minY,
+          width: maxX - minX,
+          height: maxY - minY
+        };
+      };
+
+      _proto.destroy = function destroy() {
+        if (this.get('destroyed')) {
+          return;
+        }
+
+        this.clear();
+
+        _Element.prototype.destroy.call(this);
+      };
+
+      return Group;
+    }(_element["default"]);
+
+    (0, common.mix)(Group.prototype, _container["default"], {
+      getGroupClass: function getGroupClass() {
+        return Group;
+      }
+    });
+    var _default = Group;
+    exports["default"] = _default;
+    });
+
+    unwrapExports(group$2);
+
+    var requestAnimationFrame_1 = createCommonjsModule(function (module, exports) {
+
+    exports.__esModule = true;
+    exports.requestAnimationFrame = void 0;
+    var requestAnimationFrame = typeof window === 'object' && window.requestAnimationFrame ? window.requestAnimationFrame : function (fn) {
+      return setTimeout(fn, 16);
+    };
+    exports.requestAnimationFrame = requestAnimationFrame;
+    });
+
+    unwrapExports(requestAnimationFrame_1);
+    var requestAnimationFrame_2 = requestAnimationFrame_1.requestAnimationFrame;
+
+    var canvas = createCommonjsModule(function (module, exports) {
+
+    exports.__esModule = true;
+    exports["default"] = void 0;
+
+    var _emit = _interopRequireDefault(emit);
+
+    var _controller = _interopRequireDefault(controller);
+
+    var _canvasElement = _interopRequireDefault(canvasElement);
+
+
+
+    var _container = _interopRequireDefault(container);
+
+    var _group = _interopRequireDefault(group$2);
+
+
+
+    function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
+
+    function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; }
+
+    var Canvas = /*#__PURE__*/function (_EventEmit) {
+      _inheritsLoose(Canvas, _EventEmit);
+
+      var _proto = Canvas.prototype;
+
+      _proto.get = function get(name) {
+        return this._attrs[name];
+      };
+
+      _proto.set = function set(name, value) {
+        this._attrs[name] = value;
+      };
+
+      function Canvas(cfg) {
+        var _this;
+
+        _this = _EventEmit.call(this) || this;
+        _this._attrs = (0, common.mix)({
+          type: 'canvas',
+          children: []
+        }, cfg);
+
+        _this._initPixelRatio();
+
+        _this._initCanvas();
+
+        return _this;
+      }
+
+      _proto._initPixelRatio = function _initPixelRatio() {
+        var pixelRatio = this.get('pixelRatio');
+
+        if (!pixelRatio) {
+          this.set('pixelRatio', (0, common.getPixelRatio)());
+        }
+      };
+
+      _proto.beforeDraw = function beforeDraw() {
+        var context = this._attrs.context;
+        var el = this._attrs.el;
+        context && context.clearRect && context.clearRect(0, 0, el.width, el.height);
+      };
+
+      _proto._initCanvas = function _initCanvas() {
+        var self = this;
+        var el = self.get('el');
+        var context = self.get('context');
+
+        if (!el && !context) {
+          throw new Error('Please specify the id, el or context of the chart!');
+        }
+
+        var canvas;
+
+        if (el) {
+          // DOMElement or String
+          canvas = (0, common.isString)(el) ? (0, common.getDomById)(el) : el;
+        } else {
+          // 说明没有指定el
+          canvas = _canvasElement["default"].create(context);
+        }
+
+        if (context && canvas && !canvas.getContext) {
+          canvas.getContext = function () {
+            return context;
+          };
+        }
+
+        var width = self.get('width');
+
+        if (!width) {
+          width = (0, common.getWidth)(canvas);
+        }
+
+        var height = self.get('height');
+
+        if (!height) {
+          height = (0, common.getHeight)(canvas);
+        }
+
+        self.set('canvas', this);
+        self.set('el', canvas);
+        self.set('context', context || canvas.getContext('2d'));
+        self.changeSize(width, height); // 初始化事件控制器
+
+        var eventController = new _controller["default"]({
+          canvas: this,
+          el: canvas
+        });
+        self.set('eventController', eventController);
+      };
+
+      _proto.changeSize = function changeSize(width, height) {
+        var pixelRatio = this.get('pixelRatio');
+        var canvasDOM = this.get('el'); // HTMLCanvasElement or canvasElement
+        // 浏览器环境设置style样式
+
+        if (canvasDOM.style) {
+          canvasDOM.style.width = width + 'px';
+          canvasDOM.style.height = height + 'px';
+        }
+
+        if ((0, common.isCanvasElement)(canvasDOM)) {
+          canvasDOM.width = width * pixelRatio;
+          canvasDOM.height = height * pixelRatio;
+
+          if (pixelRatio !== 1) {
+            var ctx = this.get('context');
+            ctx.scale(pixelRatio, pixelRatio);
+          }
+        }
+
+        this.set('width', width);
+        this.set('height', height);
+      };
+
+      _proto.getWidth = function getWidth() {
+        var pixelRatio = this.get('pixelRatio');
+        var width = this.get('width');
+        return width * pixelRatio;
+      };
+
+      _proto.getHeight = function getHeight() {
+        var pixelRatio = this.get('pixelRatio');
+        var height = this.get('height');
+        return height * pixelRatio;
+      };
+
+      _proto.getPointByClient = function getPointByClient(clientX, clientY) {
+        var el = this.get('el');
+        var bbox = el.getBoundingClientRect();
+        var width = bbox.right - bbox.left;
+        var height = bbox.bottom - bbox.top;
+        return {
+          x: (clientX - bbox.left) * (el.width / width),
+          y: (clientY - bbox.top) * (el.height / height)
+        };
+      };
+
+      _proto._beginDraw = function _beginDraw() {
+        this._attrs.toDraw = true;
+      };
+
+      _proto._endDraw = function _endDraw() {
+        this._attrs.toDraw = false;
+      };
+
+      _proto.draw = function draw() {
+        var self = this;
+
+        function drawInner() {
+          self.set('animateHandler', (0, requestAnimationFrame_1.requestAnimationFrame)(function () {
+            self.set('animateHandler', undefined);
+
+            if (self.get('toDraw')) {
+              drawInner();
+            }
+          }));
+          self.beforeDraw();
+
+          try {
+            var context = self._attrs.context;
+            self.drawInner(context); // 支付宝,微信小程序,需要调context.draw才能完成绘制, 所以这里直接判断是否有.draw方法
+
+            if (context.draw) {
+              context.draw();
+            }
+          } catch (ev) {
+            console.warn('error in draw canvas, detail as:');
+            console.warn(ev);
+
+            self._endDraw();
+          }
+
+          self._endDraw();
+        }
+
+        if (self.get('destroyed')) {
+          return;
+        }
+
+        if (self.get('animateHandler')) {
+          this._beginDraw();
+        } else {
+          drawInner();
+        }
+      };
+
+      _proto.destroy = function destroy() {
+        if (this.get('destroyed')) {
+          return;
+        } // 需要清理 canvas 画布内容,否则会导致 spa 应用 ios 下 canvas 白屏
+        // https://stackoverflow.com/questions/52532614/total-canvas-memory-use-exceeds-the-maximum-limit-safari-12
+        // https://github.com/antvis/F2/issues/630
+
+
+        var el = this.get('el');
+        el.width = 0;
+        el.height = 0;
+        this.clear();
+        this._attrs = {};
+        this.set('destroyed', true);
+      };
+
+      _proto.isDestroyed = function isDestroyed() {
+        return this.get('destroyed');
+      };
+
+      return Canvas;
+    }(_emit["default"]);
+
+    (0, common.mix)(Canvas.prototype, _container["default"], {
+      getGroupClass: function getGroupClass() {
+        return _group["default"];
+      }
+    });
+    var _default = Canvas;
+    exports["default"] = _default;
+    });
+
+    unwrapExports(canvas);
+
+    var rect = createCommonjsModule(function (module, exports) {
+
+    exports.__esModule = true;
+    exports["default"] = void 0;
+
+
+
+    var _shape = _interopRequireDefault(shape);
+
+    function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
+
+    function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; }
+
+    // 为了处理radius 大于 width 或 height 的场景
+    function parseRadius(radius, width, height) {
+      radius = (0, common.parsePadding)(radius); // 都为0
+
+      if (!radius[0] && !radius[1] && !radius[2] && !radius[3]) {
+        return radius;
+      }
+
+      var minWidth = Math.max(radius[0] + radius[1], radius[2] + radius[3]);
+      var minHeight = Math.max(radius[0] + radius[3], radius[1] + radius[2]);
+      var scale = Math.min(width / minWidth, height / minHeight);
+
+      if (scale < 1) {
+        return radius.map(function (r) {
+          return r * scale;
+        });
+      }
+
+      return radius;
+    }
+
+    var Rect = /*#__PURE__*/function (_Shape) {
+      _inheritsLoose(Rect, _Shape);
+
+      function Rect() {
+        return _Shape.apply(this, arguments) || this;
+      }
+
+      var _proto = Rect.prototype;
+
+      _proto._initProperties = function _initProperties() {
+        _Shape.prototype._initProperties.call(this);
+
+        this._attrs.canFill = true;
+        this._attrs.canStroke = true;
+        this._attrs.type = 'rect';
+      };
+
+      _proto.getDefaultAttrs = function getDefaultAttrs() {
+        return {
+          x: 0,
+          y: 0,
+          width: 0,
+          height: 0,
+          radius: 0,
+          lineWidth: 0
+        };
+      };
+
+      _proto.createPath = function createPath(context) {
+        var self = this;
+        var attrs = self.get('attrs');
+        var x = attrs.x,
+            y = attrs.y,
+            width = attrs.width,
+            height = attrs.height,
+            radius = attrs.radius;
+        context.beginPath();
+
+        if (!radius || !(width * height)) {
+          context.rect(x, y, width, height);
+        } else {
+          radius = parseRadius(radius, width, height);
+          context.moveTo(x + radius[0], y);
+          context.lineTo(x + width - radius[1], y);
+          context.arc(x + width - radius[1], y + radius[1], radius[1], -Math.PI / 2, 0, false);
+          context.lineTo(x + width, y + height - radius[2]);
+          context.arc(x + width - radius[2], y + height - radius[2], radius[2], 0, Math.PI / 2, false);
+          context.lineTo(x + radius[3], y + height);
+          context.arc(x + radius[3], y + height - radius[3], radius[3], Math.PI / 2, Math.PI, false);
+          context.lineTo(x, y + radius[0]);
+          context.arc(x + radius[0], y + radius[0], radius[0], Math.PI, Math.PI * 3 / 2, false);
+          context.closePath();
+        }
+      };
+
+      _proto.calculateBox = function calculateBox() {
+        var attrs = this.get('attrs');
+        var x = attrs.x,
+            y = attrs.y,
+            width = attrs.width,
+            height = attrs.height;
+        return {
+          minX: x,
+          minY: y,
+          maxX: x + width,
+          maxY: y + height
+        };
+      };
+
+      return Rect;
+    }(_shape["default"]);
+
+    _shape["default"].Rect = Rect;
+    var _default = Rect;
+    exports["default"] = _default;
+    });
+
+    unwrapExports(rect);
+
+    var image = createCommonjsModule(function (module, exports) {
+
+    exports.__esModule = true;
+    exports["default"] = void 0;
+
+
+
+    var _shape = _interopRequireDefault(shape);
+
+    function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
+
+    function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; }
+
+    var ImageShape = /*#__PURE__*/function (_Shape) {
+      _inheritsLoose(ImageShape, _Shape);
+
+      function ImageShape() {
+        return _Shape.apply(this, arguments) || this;
+      }
+
+      var _proto = ImageShape.prototype;
+
+      _proto._initProperties = function _initProperties() {
+        _Shape.prototype._initProperties.call(this);
+
+        this._attrs.canFill = false;
+        this._attrs.canStroke = false;
+        this._attrs.loading = false;
+        this._attrs.image = null;
+        this._attrs.type = 'image';
+      };
+
+      _proto.getDefaultAttrs = function getDefaultAttrs() {
+        return {
+          x: 0,
+          y: 0,
+          width: 0,
+          height: 0
+        };
+      };
+
+      _proto.createPath = function createPath(context) {
+        var _this = this;
+
+        var attrs = this.get('attrs');
+        var src = attrs.src;
+
+        if (this.get('loading')) {
+          return;
+        }
+
+        var image = this.get('image');
+
+        if (image) {
+          this.drawImage(context, image);
+        } else {
+          if (src && Image) {
+            this.set('loading', true);
+
+            var _image = new Image();
+
+            _image.src = src; // 设置跨域
+
+            _image.crossOrigin = 'Anonymous';
+
+            _image.onload = function () {
+              _this.set('loading', false);
+
+              _this.set('image', _image);
+
+              _this.drawImage(context, _image);
+            };
+          }
+        }
+      };
+
+      _proto.drawImage = function drawImage(context, image) {
+        var attrs = this.get('attrs');
+        var x = attrs.x,
+            y = attrs.y,
+            width = attrs.width,
+            height = attrs.height,
+            sx = attrs.sx,
+            sy = attrs.sy,
+            swidth = attrs.swidth,
+            sheight = attrs.sheight;
+
+        if (!(0, common.isNil)(sx) && !(0, common.isNil)(sy) && !(0, common.isNil)(swidth) && !(0, common.isNil)(sheight)) {
+          context.drawImage(image, sx, sy, swidth, sheight, x, y, width, height);
+        } else {
+          context.drawImage(image, x, y, width, height);
+        }
+      };
+
+      _proto.calculateBox = function calculateBox() {
+        var attrs = this.get('attrs');
+        var x = attrs.x,
+            y = attrs.y,
+            width = attrs.width,
+            height = attrs.height; // 和rect一样
+
+        return {
+          minX: x,
+          minY: y,
+          maxX: x + width,
+          maxY: y + height
+        };
+      };
+
+      return ImageShape;
+    }(_shape["default"]);
+
+    _shape["default"].Image = ImageShape;
+    var _default = ImageShape;
+    exports["default"] = _default;
+    });
+
+    unwrapExports(image);
+
+    var circle = createCommonjsModule(function (module, exports) {
+
+    exports.__esModule = true;
+    exports["default"] = void 0;
+
+    var _shape = _interopRequireDefault(shape);
+
+    function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
+
+    function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; }
+
+    var Circle = /*#__PURE__*/function (_Shape) {
+      _inheritsLoose(Circle, _Shape);
+
+      function Circle() {
+        return _Shape.apply(this, arguments) || this;
+      }
+
+      var _proto = Circle.prototype;
+
+      _proto._initProperties = function _initProperties() {
+        _Shape.prototype._initProperties.call(this);
+
+        this._attrs.canFill = true;
+        this._attrs.canStroke = true;
+        this._attrs.type = 'circle';
+      };
+
+      _proto.getDefaultAttrs = function getDefaultAttrs() {
+        return {
+          x: 0,
+          y: 0,
+          r: 0,
+          lineWidth: 0
+        };
+      };
+
+      _proto.createPath = function createPath(context) {
+        var attrs = this.get('attrs');
+        var x = attrs.x,
+            y = attrs.y,
+            r = attrs.r;
+        context.beginPath();
+        context.arc(x, y, r, 0, Math.PI * 2, false);
+        context.closePath();
+      };
+
+      _proto.calculateBox = function calculateBox() {
+        var attrs = this.get('attrs');
+        var x = attrs.x,
+            y = attrs.y,
+            r = attrs.r;
+        return {
+          minX: x - r,
+          maxX: x + r,
+          minY: y - r,
+          maxY: y + r
+        };
+      };
+
+      return Circle;
+    }(_shape["default"]);
+
+    _shape["default"].Circle = Circle;
+    var _default = Circle;
+    exports["default"] = _default;
+    });
+
+    unwrapExports(circle);
+
+    var bbox = createCommonjsModule(function (module, exports) {
+
+    exports.__esModule = true;
+    exports.getBBoxFromPoints = getBBoxFromPoints;
+    exports.getBBoxFromLine = getBBoxFromLine;
+    exports.getBBoxFromArc = getBBoxFromArc;
+    exports.getBBoxFromBezierGroup = getBBoxFromBezierGroup;
+
+    var _vector = _interopRequireDefault(vector2);
+
+    function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
+
+    var start = _vector["default"].create();
+
+    var end = _vector["default"].create();
+
+    var extremity = _vector["default"].create();
+
+    function getCubicBezierXYatT(startPt, controlPt1, controlPt2, endPt, T) {
+      var x = CubicN(T, startPt.x, controlPt1.x, controlPt2.x, endPt.x);
+      var y = CubicN(T, startPt.y, controlPt1.y, controlPt2.y, endPt.y);
+      return {
+        x: x,
+        y: y
+      };
+    } // cubic helper formula at T distance
+
+
+    function CubicN(T, a, b, c, d) {
+      var t2 = T * T;
+      var t3 = t2 * T;
+      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;
+    }
+
+    function cubicBezierBounds(c) {
+      var minX = Infinity;
+      var maxX = -Infinity;
+      var minY = Infinity;
+      var maxY = -Infinity;
+      var s = {
+        x: c[0],
+        y: c[1]
+      };
+      var c1 = {
+        x: c[2],
+        y: c[3]
+      };
+      var c2 = {
+        x: c[4],
+        y: c[5]
+      };
+      var e = {
+        x: c[6],
+        y: c[7]
+      };
+
+      for (var t = 0; t < 100; t++) {
+        var pt = getCubicBezierXYatT(s, c1, c2, e, t / 100);
+
+        if (pt.x < minX) {
+          minX = pt.x;
+        }
+
+        if (pt.x > maxX) {
+          maxX = pt.x;
+        }
+
+        if (pt.y < minY) {
+          minY = pt.y;
+        }
+
+        if (pt.y > maxY) {
+          maxY = pt.y;
+        }
+      }
+
+      return {
+        minX: minX,
+        minY: minY,
+        maxX: maxX,
+        maxY: maxY
+      };
+    }
+
+    function getBBoxFromPoints(points, lineWidth) {
+      if (points.length === 0) {
+        return;
+      }
+
+      var p = points[0];
+      var left = p.x;
+      var right = p.x;
+      var top = p.y;
+      var bottom = p.y;
+      var len = points.length;
+
+      for (var i = 1; i < len; i++) {
+        p = points[i];
+        left = Math.min(left, p.x);
+        right = Math.max(right, p.x);
+        top = Math.min(top, p.y);
+        bottom = Math.max(bottom, p.y);
+      }
+
+      lineWidth = lineWidth / 2 || 0;
+      return {
+        minX: left - lineWidth,
+        minY: top - lineWidth,
+        maxX: right + lineWidth,
+        maxY: bottom + lineWidth
+      };
+    }
+
+    function getBBoxFromLine(x0, y0, x1, y1, lineWidth) {
+      lineWidth = lineWidth / 2 || 0;
+      return {
+        minX: Math.min(x0, x1) - lineWidth,
+        minY: Math.min(y0, y1) - lineWidth,
+        maxX: Math.max(x0, x1) + lineWidth,
+        maxY: Math.max(y0, y1) + lineWidth
+      };
+    }
+
+    function getBBoxFromArc(x, y, r, startAngle, endAngle, anticlockwise) {
+      var diff = Math.abs(startAngle - endAngle);
+
+      if (diff % (Math.PI * 2) < 1e-4 && diff > 1e-4) {
+        // Is a circle
+        return {
+          minX: x - r,
+          minY: y - r,
+          maxX: x + r,
+          maxY: y + r
+        };
+      }
+
+      start[0] = Math.cos(startAngle) * r + x;
+      start[1] = Math.sin(startAngle) * r + y;
+      end[0] = Math.cos(endAngle) * r + x;
+      end[1] = Math.sin(endAngle) * r + y;
+      var min = [0, 0];
+      var max = [0, 0];
+
+      _vector["default"].min(min, start, end);
+
+      _vector["default"].max(max, start, end); // Thresh to [0, Math.PI * 2]
+
+
+      startAngle = startAngle % (Math.PI * 2);
+
+      if (startAngle < 0) {
+        startAngle = startAngle + Math.PI * 2;
+      }
+
+      endAngle = endAngle % (Math.PI * 2);
+
+      if (endAngle < 0) {
+        endAngle = endAngle + Math.PI * 2;
+      }
+
+      if (startAngle > endAngle && !anticlockwise) {
+        endAngle += Math.PI * 2;
+      } else if (startAngle < endAngle && anticlockwise) {
+        startAngle += Math.PI * 2;
+      }
+
+      if (anticlockwise) {
+        var tmp = endAngle;
+        endAngle = startAngle;
+        startAngle = tmp;
+      }
+
+      for (var angle = 0; angle < endAngle; angle += Math.PI / 2) {
+        if (angle > startAngle) {
+          extremity[0] = Math.cos(angle) * r + x;
+          extremity[1] = Math.sin(angle) * r + y;
+
+          _vector["default"].min(min, extremity, min);
+
+          _vector["default"].max(max, extremity, max);
+        }
+      }
+
+      return {
+        minX: min[0],
+        minY: min[1],
+        maxX: max[0],
+        maxY: max[1]
+      };
+    }
+
+    function getBBoxFromBezierGroup(points, lineWidth) {
+      var minX = Infinity;
+      var maxX = -Infinity;
+      var minY = Infinity;
+      var maxY = -Infinity;
+
+      for (var i = 0, len = points.length; i < len; i++) {
+        var bbox = cubicBezierBounds(points[i]);
+
+        if (bbox.minX < minX) {
+          minX = bbox.minX;
+        }
+
+        if (bbox.maxX > maxX) {
+          maxX = bbox.maxX;
+        }
+
+        if (bbox.minY < minY) {
+          minY = bbox.minY;
+        }
+
+        if (bbox.maxY > maxY) {
+          maxY = bbox.maxY;
+        }
+      }
+
+      lineWidth = lineWidth / 2 || 0;
+      return {
+        minX: minX - lineWidth,
+        minY: minY - lineWidth,
+        maxX: maxX + lineWidth,
+        maxY: maxY + lineWidth
+      };
+    }
+    });
+
+    unwrapExports(bbox);
+    var bbox_1 = bbox.getBBoxFromPoints;
+    var bbox_2 = bbox.getBBoxFromLine;
+    var bbox_3 = bbox.getBBoxFromArc;
+    var bbox_4 = bbox.getBBoxFromBezierGroup;
+
+    var line = createCommonjsModule(function (module, exports) {
+
+    exports.__esModule = true;
+    exports["default"] = void 0;
+
+    var _shape = _interopRequireDefault(shape);
+
+
+
+    function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
+
+    function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; }
+
+    var Line = /*#__PURE__*/function (_Shape) {
+      _inheritsLoose(Line, _Shape);
+
+      function Line() {
+        return _Shape.apply(this, arguments) || this;
+      }
+
+      var _proto = Line.prototype;
+
+      _proto._initProperties = function _initProperties() {
+        _Shape.prototype._initProperties.call(this);
+
+        this._attrs.canStroke = true;
+        this._attrs.type = 'line';
+      };
+
+      _proto.getDefaultAttrs = function getDefaultAttrs() {
+        return {
+          x1: 0,
+          y1: 0,
+          x2: 0,
+          y2: 0,
+          lineWidth: 1
+        };
+      };
+
+      _proto.createPath = function createPath(context) {
+        var attrs = this.get('attrs');
+        var x1 = attrs.x1,
+            y1 = attrs.y1,
+            x2 = attrs.x2,
+            y2 = attrs.y2;
+        context.beginPath();
+        context.moveTo(x1, y1);
+        context.lineTo(x2, y2);
+      };
+
+      _proto.calculateBox = function calculateBox() {
+        var attrs = this.get('attrs');
+        var x1 = attrs.x1,
+            y1 = attrs.y1,
+            x2 = attrs.x2,
+            y2 = attrs.y2,
+            lineWidth = attrs.lineWidth;
+        return (0, bbox.getBBoxFromLine)(x1, y1, x2, y2, lineWidth);
+      };
+
+      return Line;
+    }(_shape["default"]);
+
+    _shape["default"].Line = Line;
+    var _default = Line;
+    exports["default"] = _default;
+    });
+
+    unwrapExports(line);
+
+    var polygon = createCommonjsModule(function (module, exports) {
+
+    exports.__esModule = true;
+    exports["default"] = void 0;
+
+    var _shape = _interopRequireDefault(shape);
+
+
+
+    function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
+
+    function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; }
+
+    var Polygon = /*#__PURE__*/function (_Shape) {
+      _inheritsLoose(Polygon, _Shape);
+
+      function Polygon() {
+        return _Shape.apply(this, arguments) || this;
+      }
+
+      var _proto = Polygon.prototype;
+
+      _proto._initProperties = function _initProperties() {
+        _Shape.prototype._initProperties.call(this);
+
+        this._attrs.canFill = true;
+        this._attrs.canStroke = true;
+        this._attrs.type = 'polygon';
+      };
+
+      _proto.getDefaultAttrs = function getDefaultAttrs() {
+        return {
+          points: null,
+          lineWidth: 0
+        };
+      };
+
+      _proto.createPath = function createPath(context) {
+        var self = this;
+        var attrs = self.get('attrs');
+        var points = attrs.points;
+        context.beginPath();
+
+        for (var i = 0, len = points.length; i < len; i++) {
+          var point = points[i];
+
+          if (i === 0) {
+            context.moveTo(point.x, point.y);
+          } else {
+            context.lineTo(point.x, point.y);
+          }
+        }
+
+        context.closePath();
+      };
+
+      _proto.calculateBox = function calculateBox() {
+        var attrs = this.get('attrs');
+        var points = attrs.points;
+        return (0, bbox.getBBoxFromPoints)(points);
+      };
+
+      return Polygon;
+    }(_shape["default"]);
+
+    _shape["default"].Polygon = Polygon;
+    var _default = Polygon;
+    exports["default"] = _default;
+    });
+
+    unwrapExports(polygon);
+
+    var smooth = createCommonjsModule(function (module, exports) {
+
+    exports.__esModule = true;
+    exports.smooth = catmullRom2bezier;
+
+    var _vector = _interopRequireDefault(vector2);
+
+    function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
+
+    /**
+     * @fileOverview convert the line to curve
+     * @author dxq613@gmail.com
+     */
+    function getPoint(v) {
+      return [v.x, v.y];
+    }
+
+    function smoothBezier(points, smooth, isLoop, constraint) {
+      var cps = [];
+      var prevPoint;
+      var nextPoint;
+      var hasConstraint = !!constraint;
+      var min;
+      var max;
+      var point;
+      var len;
+      var l;
+      var i;
+
+      if (hasConstraint) {
+        min = [Infinity, Infinity];
+        max = [-Infinity, -Infinity];
+
+        for (i = 0, l = points.length; i < l; i++) {
+          point = getPoint(points[i]);
+
+          _vector["default"].min(min, min, point);
+
+          _vector["default"].max(max, max, point);
+        }
+
+        _vector["default"].min(min, min, constraint[0]);
+
+        _vector["default"].max(max, max, constraint[1]);
+      }
+
+      for (i = 0, len = points.length; i < len; i++) {
+        point = getPoint(points[i]);
+
+        if (isLoop) {
+          prevPoint = getPoint(points[i ? i - 1 : len - 1]);
+          nextPoint = getPoint(points[(i + 1) % len]);
+        } else {
+          if (i === 0 || i === len - 1) {
+            cps.push([point[0], point[1]]);
+            continue;
+          } else {
+            prevPoint = getPoint(points[i - 1]);
+            nextPoint = getPoint(points[i + 1]);
+          }
+        }
+
+        var v = _vector["default"].sub([], nextPoint, prevPoint);
+
+        _vector["default"].scale(v, v, smooth);
+
+        var d0 = _vector["default"].distance(point, prevPoint);
+
+        var d1 = _vector["default"].distance(point, nextPoint);
+
+        var sum = d0 + d1;
+
+        if (sum !== 0) {
+          d0 /= sum;
+          d1 /= sum;
+        }
+
+        var v1 = _vector["default"].scale([], v, -d0);
+
+        var v2 = _vector["default"].scale([], v, d1);
+
+        var cp0 = _vector["default"].add([], point, v1);
+
+        var cp1 = _vector["default"].add([], point, v2);
+
+        if (hasConstraint) {
+          _vector["default"].max(cp0, cp0, min);
+
+          _vector["default"].min(cp0, cp0, max);
+
+          _vector["default"].max(cp1, cp1, min);
+
+          _vector["default"].min(cp1, cp1, max);
+        }
+
+        cps.push([cp0[0], cp0[1]]);
+        cps.push([cp1[0], cp1[1]]);
+      }
+
+      if (isLoop) {
+        cps.push(cps.shift());
+      }
+
+      return cps;
+    }
+
+    function catmullRom2bezier(pointList, z, constraint) {
+      var isLoop = !!z;
+      var controlPointList = smoothBezier(pointList, 0.4, isLoop, constraint);
+      var len = pointList.length;
+      var d1 = [];
+      var cp1;
+      var cp2;
+      var p;
+
+      for (var i = 0; i < len - 1; i++) {
+        cp1 = controlPointList[i * 2];
+        cp2 = controlPointList[i * 2 + 1];
+        p = pointList[i + 1];
+        d1.push(['C', cp1[0], cp1[1], cp2[0], cp2[1], p.x, p.y]);
+      }
+
+      if (isLoop) {
+        cp1 = controlPointList[len];
+        cp2 = controlPointList[len + 1];
+        p = pointList[0];
+        d1.push(['C', cp1[0], cp1[1], cp2[0], cp2[1], p.x, p.y]);
+      }
+
+      return d1;
+    }
+    });
+
+    unwrapExports(smooth);
+    var smooth_1 = smooth.smooth;
+
+    var polyline = createCommonjsModule(function (module, exports) {
+
+    exports.__esModule = true;
+    exports["default"] = void 0;
+
+    var _shape = _interopRequireDefault(shape);
+
+
+
+    var Smooth = _interopRequireWildcard(smooth);
+
+    function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; }
+
+    function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
+
+    function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
+
+    function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; }
+
+    // filter the point which x or y is NaN
+    function _filterPoints(points) {
+      var filteredPoints = [];
+
+      for (var i = 0, len = points.length; i < len; i++) {
+        var point = points[i];
+
+        if (!isNaN(point.x) && !isNaN(point.y)) {
+          filteredPoints.push(point);
+        }
+      }
+
+      return filteredPoints;
+    }
+
+    var Polyline = /*#__PURE__*/function (_Shape) {
+      _inheritsLoose(Polyline, _Shape);
+
+      function Polyline() {
+        return _Shape.apply(this, arguments) || this;
+      }
+
+      var _proto = Polyline.prototype;
+
+      _proto._initProperties = function _initProperties() {
+        _Shape.prototype._initProperties.call(this);
+
+        this._attrs.canFill = true;
+        this._attrs.canStroke = true;
+        this._attrs.type = 'polyline';
+      };
+
+      _proto.getDefaultAttrs = function getDefaultAttrs() {
+        return {
+          points: null,
+          lineWidth: 1,
+          smooth: false
+        };
+      };
+
+      _proto.createPath = function createPath(context) {
+        var self = this;
+        var attrs = self.get('attrs');
+        var points = attrs.points,
+            smooth = attrs.smooth;
+
+        var filteredPoints = _filterPoints(points);
+
+        context.beginPath();
+
+        if (filteredPoints.length) {
+          context.moveTo(filteredPoints[0].x, filteredPoints[0].y);
+
+          if (smooth) {
+            var constaint = [[0, 0], [1, 1]];
+            var sps = Smooth.smooth(filteredPoints, false, constaint);
+
+            for (var i = 0, n = sps.length; i < n; i++) {
+              var sp = sps[i];
+              context.bezierCurveTo(sp[1], sp[2], sp[3], sp[4], sp[5], sp[6]);
+            }
+          } else {
+            var _i;
+
+            var l;
+
+            for (_i = 1, l = filteredPoints.length - 1; _i < l; _i++) {
+              context.lineTo(filteredPoints[_i].x, filteredPoints[_i].y);
+            }
+
+            context.lineTo(filteredPoints[l].x, filteredPoints[l].y);
+          }
+        }
+      };
+
+      _proto.calculateBox = function calculateBox() {
+        var attrs = this.get('attrs');
+        var points = attrs.points,
+            smooth = attrs.smooth,
+            lineWidth = attrs.lineWidth;
+
+        var filteredPoints = _filterPoints(points);
+
+        if (smooth) {
+          var newPoints = [];
+          var constaint = [[0, 0], [1, 1]];
+          var sps = Smooth.smooth(filteredPoints, false, constaint);
+
+          for (var i = 0, n = sps.length; i < n; i++) {
+            var sp = sps[i];
+
+            if (i === 0) {
+              newPoints.push([filteredPoints[0].x, filteredPoints[0].y, sp[1], sp[2], sp[3], sp[4], sp[5], sp[6]]);
+            } else {
+              var lastPoint = sps[i - 1];
+              newPoints.push([lastPoint[5], lastPoint[6], sp[1], sp[2], sp[3], sp[4], sp[5], sp[6]]);
+            }
+          }
+
+          return (0, bbox.getBBoxFromBezierGroup)(newPoints, lineWidth);
+        }
+
+        return (0, bbox.getBBoxFromPoints)(filteredPoints, lineWidth);
+      };
+
+      return Polyline;
+    }(_shape["default"]);
+
+    _shape["default"].Polyline = Polyline;
+    var _default = Polyline;
+    exports["default"] = _default;
+    });
+
+    unwrapExports(polyline);
+
+    var arc = createCommonjsModule(function (module, exports) {
+
+    exports.__esModule = true;
+    exports["default"] = void 0;
+
+    var _shape = _interopRequireDefault(shape);
+
+
+
+    function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
+
+    function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; }
+
+    var Arc = /*#__PURE__*/function (_Shape) {
+      _inheritsLoose(Arc, _Shape);
+
+      function Arc() {
+        return _Shape.apply(this, arguments) || this;
+      }
+
+      var _proto = Arc.prototype;
+
+      _proto._initProperties = function _initProperties() {
+        _Shape.prototype._initProperties.call(this);
+
+        this._attrs.canStroke = true;
+        this._attrs.canFill = true;
+        this._attrs.type = 'arc';
+      };
+
+      _proto.getDefaultAttrs = function getDefaultAttrs() {
+        return {
+          x: 0,
+          y: 0,
+          r: 0,
+          startAngle: 0,
+          endAngle: Math.PI * 2,
+          anticlockwise: false,
+          lineWidth: 1
+        };
+      };
+
+      _proto.createPath = function createPath(context) {
+        var attrs = this.get('attrs');
+        var x = attrs.x,
+            y = attrs.y,
+            r = attrs.r,
+            startAngle = attrs.startAngle,
+            endAngle = attrs.endAngle,
+            anticlockwise = attrs.anticlockwise;
+        context.beginPath();
+
+        if (startAngle !== endAngle) {
+          context.arc(x, y, r, startAngle, endAngle, anticlockwise);
+        }
+      };
+
+      _proto.calculateBox = function calculateBox() {
+        var attrs = this.get('attrs');
+        var x = attrs.x,
+            y = attrs.y,
+            r = attrs.r,
+            startAngle = attrs.startAngle,
+            endAngle = attrs.endAngle,
+            anticlockwise = attrs.anticlockwise;
+        return (0, bbox.getBBoxFromArc)(x, y, r, startAngle, endAngle, anticlockwise);
+      };
+
+      return Arc;
+    }(_shape["default"]);
+
+    _shape["default"].Arc = Arc;
+    var _default = Arc;
+    exports["default"] = _default;
+    });
+
+    unwrapExports(arc);
+
+    var sector = createCommonjsModule(function (module, exports) {
+
+    exports.__esModule = true;
+    exports["default"] = void 0;
+
+    var _shape = _interopRequireDefault(shape);
+
+
+
+    function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
+
+    function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; }
+
+    var Sector = /*#__PURE__*/function (_Shape) {
+      _inheritsLoose(Sector, _Shape);
+
+      function Sector() {
+        return _Shape.apply(this, arguments) || this;
+      }
+
+      var _proto = Sector.prototype;
+
+      _proto._initProperties = function _initProperties() {
+        _Shape.prototype._initProperties.call(this);
+
+        this._attrs.canFill = true;
+        this._attrs.canStroke = true;
+        this._attrs.type = 'sector';
+      };
+
+      _proto.getDefaultAttrs = function getDefaultAttrs() {
+        return {
+          x: 0,
+          y: 0,
+          lineWidth: 0,
+          r: 0,
+          r0: 0,
+          startAngle: 0,
+          endAngle: Math.PI * 2,
+          anticlockwise: false
+        };
+      };
+
+      _proto.createPath = function createPath(context) {
+        var attrs = this.get('attrs');
+        var x = attrs.x,
+            y = attrs.y,
+            startAngle = attrs.startAngle,
+            endAngle = attrs.endAngle,
+            r = attrs.r,
+            r0 = attrs.r0,
+            anticlockwise = attrs.anticlockwise;
+        context.beginPath();
+        var unitX = Math.cos(startAngle);
+        var unitY = Math.sin(startAngle);
+        context.moveTo(unitX * r0 + x, unitY * r0 + y);
+        context.lineTo(unitX * r + x, unitY * r + y); // 当扇形的角度非常小的时候,就不进行弧线的绘制;或者整个只有1个扇形时,会出现end<0的情况不绘制
+
+        if (Math.abs(endAngle - startAngle) > 0.0001 || startAngle === 0 && endAngle < 0) {
+          context.arc(x, y, r, startAngle, endAngle, anticlockwise);
+          context.lineTo(Math.cos(endAngle) * r0 + x, Math.sin(endAngle) * r0 + y);
+
+          if (r0 !== 0) {
+            context.arc(x, y, r0, endAngle, startAngle, !anticlockwise);
+          }
+        }
+
+        context.closePath();
+      };
+
+      _proto.calculateBox = function calculateBox() {
+        var attrs = this.get('attrs');
+        var x = attrs.x,
+            y = attrs.y,
+            r = attrs.r,
+            r0 = attrs.r0,
+            startAngle = attrs.startAngle,
+            endAngle = attrs.endAngle,
+            anticlockwise = attrs.anticlockwise;
+        var outerBBox = (0, bbox.getBBoxFromArc)(x, y, r, startAngle, endAngle, anticlockwise);
+        var innerBBox = (0, bbox.getBBoxFromArc)(x, y, r0, startAngle, endAngle, anticlockwise);
+        return {
+          minX: Math.min(outerBBox.minX, innerBBox.minX),
+          minY: Math.min(outerBBox.minY, innerBBox.minY),
+          maxX: Math.max(outerBBox.maxX, innerBBox.maxX),
+          maxY: Math.max(outerBBox.maxY, innerBBox.maxY)
+        };
+      };
+
+      return Sector;
+    }(_shape["default"]);
+
+    _shape["default"].Sector = Sector;
+    var _default = Sector;
+    exports["default"] = _default;
+    });
+
+    unwrapExports(sector);
+
+    var rect$1 = createCommonjsModule(function (module, exports) {
+
+    exports.__esModule = true;
+    exports["default"] = void 0;
+    var Rect = {
+      calcRotatedBox: function calcRotatedBox(_ref) {
+        var width = _ref.width,
+            height = _ref.height,
+            rotate = _ref.rotate;
+        var absRotate = Math.abs(rotate);
+        return {
+          width: Math.abs(width * Math.cos(absRotate) + height * Math.sin(absRotate)),
+          height: Math.abs(height * Math.cos(absRotate) + width * Math.sin(absRotate))
+        };
+      }
+    };
+    var _default = Rect;
+    exports["default"] = _default;
+    });
+
+    unwrapExports(rect$1);
+
+    var text = createCommonjsModule(function (module, exports) {
+
+    exports.__esModule = true;
+    exports["default"] = void 0;
+
+
+
+    var _shape = _interopRequireDefault(shape);
+
+    var _rect = _interopRequireDefault(rect$1);
+
+    function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
+
+    function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; }
+
+    var textWidthCacheCounter = 0;
+    var textWidthCache = {};
+    var TEXT_CACHE_MAX = 5000;
+
+    var Text = /*#__PURE__*/function (_Shape) {
+      _inheritsLoose(Text, _Shape);
+
+      function Text() {
+        return _Shape.apply(this, arguments) || this;
+      }
+
+      var _proto = Text.prototype;
+
+      _proto._initProperties = function _initProperties() {
+        _Shape.prototype._initProperties.call(this);
+
+        this._attrs.canFill = true;
+        this._attrs.canStroke = true;
+        this._attrs.type = 'text';
+      };
+
+      _proto.getDefaultAttrs = function getDefaultAttrs() {
+        return {
+          lineWidth: 0,
+          lineCount: 1,
+          fontSize: 12,
+          fontFamily: 'sans-serif',
+          fontStyle: 'normal',
+          fontWeight: 'normal',
+          fontVariant: 'normal',
+          textAlign: 'start',
+          textBaseline: 'bottom',
+          lineHeight: null,
+          textArr: null
+        };
+      };
+
+      _proto._getFontStyle = function _getFontStyle() {
+        var attrs = this._attrs.attrs;
+        var fontSize = attrs.fontSize,
+            fontFamily = attrs.fontFamily,
+            fontWeight = attrs.fontWeight,
+            fontStyle = attrs.fontStyle,
+            fontVariant = attrs.fontVariant;
+        return fontStyle + " " + fontVariant + " " + fontWeight + " " + fontSize + "px " + fontFamily;
+      };
+
+      _proto._afterAttrsSet = function _afterAttrsSet() {
+        var attrs = this._attrs.attrs;
+        attrs.font = this._getFontStyle();
+
+        if (attrs.text) {
+          var text = attrs.text;
+          var textArr = null;
+          var lineCount = 1;
+
+          if ((0, common.isString)(text) && text.indexOf('\n') !== -1) {
+            textArr = text.split('\n');
+            lineCount = textArr.length;
+          }
+
+          attrs.lineCount = lineCount;
+          attrs.textArr = textArr;
+        }
+
+        this.set('attrs', attrs);
+      };
+
+      _proto._getTextHeight = function _getTextHeight() {
+        var attrs = this._attrs.attrs;
+
+        if (attrs.height) {
+          return attrs.height;
+        }
+
+        var lineCount = attrs.lineCount;
+        var fontSize = attrs.fontSize * 1;
+
+        if (lineCount > 1) {
+          var spaceingY = this._getSpaceingY();
+
+          return fontSize * lineCount + spaceingY * (lineCount - 1);
+        }
+
+        return fontSize;
+      };
+
+      _proto._getSpaceingY = function _getSpaceingY() {
+        var attrs = this._attrs.attrs;
+        var lineHeight = attrs.lineHeight;
+        var fontSize = attrs.fontSize * 1;
+        return lineHeight ? lineHeight - fontSize : fontSize * 0.14;
+      };
+
+      _proto.drawInner = function drawInner(context) {
+        var self = this;
+        var attrs = self._attrs.attrs;
+        var text = attrs.text;
+        var x = attrs.x;
+        var y = attrs.y;
+
+        if ((0, common.isNil)(text) || isNaN(x) || isNaN(y)) {
+          // text will be 0
+          return;
+        }
+
+        var textArr = attrs.textArr;
+        var fontSize = attrs.fontSize * 1;
+
+        var spaceingY = self._getSpaceingY();
+
+        if (attrs.rotate) {
+          // do rotation
+          context.translate(x, y);
+          context.rotate(attrs.rotate);
+          x = 0;
+          y = 0;
+        }
+
+        var textBaseline = attrs.textBaseline;
+        var height;
+
+        if (textArr) {
+          height = self._getTextHeight();
+        }
+
+        var subY; // context.beginPath();
+
+        if (self.hasFill()) {
+          var fillOpacity = attrs.fillOpacity;
+
+          if (!(0, common.isNil)(fillOpacity) && fillOpacity !== 1) {
+            context.globalAlpha = fillOpacity;
+          }
+
+          if (textArr) {
+            for (var i = 0, len = textArr.length; i < len; i++) {
+              var subText = textArr[i];
+              subY = y + i * (spaceingY + fontSize) - height + fontSize; // bottom;
+
+              if (textBaseline === 'middle') {
+                subY += height - fontSize - (height - fontSize) / 2;
+              }
+
+              if (textBaseline === 'top') {
+                subY += height - fontSize;
+              }
+
+              context.fillText(subText, x, subY);
+            }
+          } else {
+            context.fillText(text, x, y);
+          }
+        }
+
+        if (self.hasStroke()) {
+          if (textArr) {
+            for (var _i = 0, _len = textArr.length; _i < _len; _i++) {
+              var _subText = textArr[_i];
+              subY = y + _i * (spaceingY + fontSize) - height + fontSize; // bottom;
+
+              if (textBaseline === 'middle') {
+                subY += height - fontSize - (height - fontSize) / 2;
+              }
+
+              if (textBaseline === 'top') {
+                subY += height - fontSize;
+              }
+
+              context.strokeText(_subText, x, subY);
+            }
+          } else {
+            context.strokeText(text, x, y);
+          }
+        }
+      };
+
+      _proto.calculateBox = function calculateBox() {
+        var self = this;
+        var attrs = self._attrs.attrs;
+        var x = attrs.x,
+            y = attrs.y,
+            textAlign = attrs.textAlign,
+            textBaseline = attrs.textBaseline;
+
+        var width = self._getTextWidth(); // attrs.width
+
+
+        if (!width) {
+          return {
+            minX: x,
+            minY: y,
+            maxX: x,
+            maxY: y
+          };
+        }
+
+        var height = self._getTextHeight(); // attrs.height
+
+
+        if (attrs.rotate) {
+          var rotatedBox = _rect["default"].calcRotatedBox({
+            width: width,
+            height: height,
+            rotate: attrs.rotate
+          });
+
+          width = rotatedBox.width;
+          height = rotatedBox.height;
+        }
+
+        var point = {
+          x: x,
+          y: y - height
+        }; // default textAlign: start, textBaseline: bottom
+
+        if (textAlign) {
+          if (textAlign === 'end' || textAlign === 'right') {
+            point.x -= width;
+          } else if (textAlign === 'center') {
+            point.x -= width / 2;
+          }
+        }
+
+        if (textBaseline) {
+          if (textBaseline === 'top') {
+            point.y += height;
+          } else if (textBaseline === 'middle') {
+            point.y += height / 2;
+          }
+        }
+
+        return {
+          minX: point.x,
+          minY: point.y,
+          maxX: point.x + width,
+          maxY: point.y + height
+        };
+      };
+
+      _proto._getTextWidth = function _getTextWidth() {
+        var attrs = this._attrs.attrs;
+
+        if (attrs.width) {
+          return attrs.width;
+        }
+
+        var text = attrs.text;
+        var context = this.get('context');
+        if ((0, common.isNil)(text)) return undefined;
+        var font = attrs.font;
+        var textArr = attrs.textArr;
+        var key = text + '' + font;
+
+        if (textWidthCache[key]) {
+          return textWidthCache[key];
+        }
+
+        var width = 0;
+
+        if (textArr) {
+          for (var i = 0, length = textArr.length; i < length; i++) {
+            var subText = textArr[i];
+            width = Math.max(width, (0, common.measureText)(subText, font, context).width);
+          }
+        } else {
+          width = (0, common.measureText)(text, font, context).width;
+        }
+
+        if (textWidthCacheCounter > TEXT_CACHE_MAX) {
+          textWidthCacheCounter = 0;
+          textWidthCache = {};
+        }
+
+        textWidthCacheCounter++;
+        textWidthCache[key] = width;
+        return width;
+      };
+
+      return Text;
+    }(_shape["default"]);
+
+    _shape["default"].Text = Text;
+    var _default = Text;
+    exports["default"] = _default;
+    });
+
+    unwrapExports(text);
+
+    var custom = createCommonjsModule(function (module, exports) {
+
+    exports.__esModule = true;
+    exports["default"] = void 0;
+
+    var _shape = _interopRequireDefault(shape);
+
+    function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
+
+    function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; }
+
+    var Custom = /*#__PURE__*/function (_Shape) {
+      _inheritsLoose(Custom, _Shape);
+
+      function Custom() {
+        return _Shape.apply(this, arguments) || this;
+      }
+
+      var _proto = Custom.prototype;
+
+      _proto._initProperties = function _initProperties() {
+        _Shape.prototype._initProperties.call(this);
+
+        this._attrs.canFill = true;
+        this._attrs.canStroke = true;
+        this._attrs.createPath = null;
+        this._attrs.type = 'custom';
+      };
+
+      _proto.createPath = function createPath(context) {
+        var createPath = this.get('createPath');
+        createPath && createPath.call(this, context);
+      };
+
+      _proto.calculateBox = function calculateBox() {
+        var calculateBox = this.get('calculateBox');
+        return calculateBox && calculateBox.call(this);
+      };
+
+      return Custom;
+    }(_shape["default"]);
+
+    _shape["default"].Custom = Custom;
+    var _default = Custom;
+    exports["default"] = _default;
+    });
+
+    unwrapExports(custom);
+
+    var graphic = createCommonjsModule(function (module, exports) {
+
+    exports.__esModule = true;
+
+    var _canvas = _interopRequireDefault(canvas);
+
+    exports.Canvas = _canvas["default"];
+
+    var _group = _interopRequireDefault(group$2);
+
+    exports.Group = _group["default"];
+
+    var _shape = _interopRequireDefault(shape);
+
+    exports.Shape = _shape["default"];
+
+    var _matrix = _interopRequireDefault(matrix);
+
+    exports.Matrix = _matrix["default"];
+
+    var _vector = _interopRequireDefault(vector2);
+
+    exports.Vector2 = _vector["default"];
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
+    });
+
+    unwrapExports(graphic);
+    var graphic_1 = graphic.Canvas;
+    var graphic_2 = graphic.Group;
+    var graphic_3 = graphic.Shape;
+    var graphic_4 = graphic.Matrix;
+    var graphic_5 = graphic.Vector2;
+
+    var pieLabel = createCommonjsModule(function (module, exports) {
+
+    exports.__esModule = true;
+    exports.init = init;
+    exports.afterGeomDraw = afterGeomDraw;
+    exports.clearInner = clearInner;
+    exports["default"] = void 0;
+
+
+
+
+
+    function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
+
+    var DEFAULT_CFG = {
+      anchorOffset: 5,
+      // 锚点的偏移量
+      inflectionOffset: 15,
+      // 拐点的偏移量
+      sidePadding: 20,
+      // 文本距离画布四边的距离
+      lineHeight: 32,
+      // 文本的行高
+      adjustOffset: 15,
+      // 发生调整时的偏移量
+      skipOverlapLabels: false,
+      // 是否不展示重叠的文本
+      triggerOn: 'touchstart',
+      // 点击行为触发的时间类型
+      activeShape: false,
+      // 当有图形被选中的时候,是否激活图形
+      activeStyle: {
+        offset: 1,
+        appendRadius: 8,
+        fillOpacity: 0.5
+      },
+      label1OffsetY: -1,
+      label2OffsetY: 1
+    };
+
+    function getEndPoint(center, angle, r) {
+      return {
+        x: center.x + r * Math.cos(angle),
+        y: center.y + r * Math.sin(angle)
+      };
+    } // 计算中间角度
+
+
+    function getMiddleAngle(startAngle, endAngle) {
+      if (endAngle < startAngle) {
+        endAngle += Math.PI * 2;
+      }
+
+      return (endAngle + startAngle) / 2;
+    } // 判断两个矩形是否相交
+
+
+    function isOverlap(label1, label2) {
+      var label1BBox = label1.getBBox();
+      var label2BBox = label2.getBBox();
+      return Math.max(label1BBox.minX, label2BBox.minX) <= Math.min(label1BBox.maxX, label2BBox.maxX) && Math.max(label1BBox.minY, label2BBox.minY) <= Math.min(label1BBox.maxY, label2BBox.maxY);
+    }
+
+    var controller = /*#__PURE__*/function () {
+      function controller(cfg) {
+        var _this = this;
+
+        _defineProperty(this, "_handleEvent", function (ev) {
+          var self = _this;
+          var chart = self.chart,
+              drawnLabels = self.drawnLabels,
+              pieLabelCfg = self.pieLabelCfg;
+          var onClick = pieLabelCfg.onClick,
+              activeShape = pieLabelCfg.activeShape;
+          var canvasEvent = (0, common.createEvent)(ev, chart);
+          var x = canvasEvent.x,
+              y = canvasEvent.y; // 查找被点击的 label
+
+          var clickedShape;
+
+          for (var i = 0, len = drawnLabels.length; i < len; i++) {
+            var shape = drawnLabels[i];
+            var bbox = shape.getBBox(); // 通过最小包围盒来判断击中情况
+
+            if (x >= bbox.minX && x <= bbox.maxX && y >= bbox.minY && y <= bbox.maxY) {
+              clickedShape = shape;
+              break;
+            }
+          }
+
+          var pieData = chart.getSnapRecords({
+            x: x,
+            y: y
+          });
+
+          if (clickedShape) {
+            canvasEvent.data = clickedShape.get('data');
+          } else if (pieData.length) {
+            // 击中饼图扇形区域
+            canvasEvent.data = pieData[0]._origin;
+          }
+
+          onClick && onClick(canvasEvent);
+          canvasEvent.data && activeShape && _this._activeShape(canvasEvent.data);
+        });
+
+        (0, common.mix)(this, cfg);
+        var _chart = this.chart;
+        this.canvasDom = _chart.get('canvas').get('el');
+      }
+
+      var _proto = controller.prototype;
+
+      _proto.renderLabels = function renderLabels() {
+        var self = this;
+        var chart = self.chart,
+            pieLabelCfg = self.pieLabelCfg,
+            labelGroup = self.labelGroup;
+        var halves = [[], // left
+        [] // right
+        ]; // 存储左右 labels
+
+        var geom = chart.get('geoms')[0];
+        var shapes = geom.get('container').get('children');
+        var anchorOffset = pieLabelCfg.anchorOffset,
+            inflectionOffset = pieLabelCfg.inflectionOffset,
+            label1 = pieLabelCfg.label1,
+            label2 = pieLabelCfg.label2,
+            lineHeight = pieLabelCfg.lineHeight,
+            skipOverlapLabels = pieLabelCfg.skipOverlapLabels,
+            label1OffsetY = pieLabelCfg.label1OffsetY,
+            label2OffsetY = pieLabelCfg.label2OffsetY;
+        var coord = chart.get('coord');
+        var center = coord.center,
+            radius = coord.circleRadius;
+        shapes.forEach(function (shape) {
+          var _shape$_attrs$attrs = shape._attrs.attrs,
+              startAngle = _shape$_attrs$attrs.startAngle,
+              endAngle = _shape$_attrs$attrs.endAngle;
+          var middleAngle = getMiddleAngle(startAngle, endAngle);
+          var anchorPoint = getEndPoint(center, middleAngle, radius + anchorOffset);
+          var inflectionPoint = getEndPoint(center, middleAngle, radius + inflectionOffset);
+          var origin = shape.get('origin');
+          var _origin = origin._origin,
+              color = origin.color;
+          var label = {
+            _anchor: anchorPoint,
+            _inflection: inflectionPoint,
+            _data: _origin,
+            x: inflectionPoint.x,
+            y: inflectionPoint.y,
+            r: radius + inflectionOffset,
+            fill: color
+          };
+          var textGroup = new graphic.Group({
+            context: chart.get('canvas').get('context'),
+            // 兼容 node、小程序环境
+            data: _origin // 存储原始数据
+
+          });
+          var textAttrs = {
+            x: 0,
+            y: 0,
+            fontSize: 12,
+            lineHeight: 12,
+            fill: '#808080'
+          };
+
+          if ((0, common.isFunction)(label1)) {
+            textGroup.addShape('Text', {
+              attrs: (0, common.mix)({
+                textBaseline: 'bottom'
+              }, textAttrs, label1(_origin, color)),
+              data: _origin,
+              // 存储原始数据
+              offsetY: label1OffsetY
+            });
+          }
+
+          if ((0, common.isFunction)(label2)) {
+            textGroup.addShape('Text', {
+              attrs: (0, common.mix)({
+                textBaseline: 'top'
+              }, textAttrs, label2(_origin, color)),
+              data: _origin,
+              // 存储原始数据
+              offsetY: label2OffsetY
+            });
+          }
+
+          label.textGroup = textGroup; // 判断文本的方向
+
+          if (anchorPoint.x < center.x) {
+            label._side = 'left';
+            halves[0].push(label);
+          } else {
+            label._side = 'right';
+            halves[1].push(label);
+          }
+        });
+        var drawnLabels = [];
+
+        if (skipOverlapLabels) {
+          var lastLabel; // 存储上一个 label 对象,用于检测文本是否重叠
+
+          var labels = halves[1].concat(halves[0]); // 顺时针
+
+          for (var i = 0, len = labels.length; i < len; i++) {
+            var label = labels[i];
+
+            var textGroup = self._drawLabel(label);
+
+            if (lastLabel) {
+              if (isOverlap(textGroup, lastLabel)) {
+                // 重叠了就不绘制
+                continue;
+              }
+            }
+
+            labelGroup.add(textGroup);
+
+            self._drawLabelLine(label);
+
+            lastLabel = textGroup;
+            drawnLabels.push(textGroup);
+          }
+        } else {
+          var height = chart.get('height');
+          var maxCountForOneSide = parseInt(height / lineHeight, 10);
+          halves.forEach(function (half) {
+            if (half.length > maxCountForOneSide) {
+              half.splice(maxCountForOneSide, half.length - maxCountForOneSide);
+            }
+
+            half.sort(function (a, b) {
+              return a.y - b.y;
+            });
+
+            var labels = self._antiCollision(half);
+
+            drawnLabels = drawnLabels.concat(labels);
+          });
+        }
+
+        this.drawnLabels = drawnLabels;
+      };
+
+      _proto.bindEvents = function bindEvents() {
+        var pieLabelCfg = this.pieLabelCfg;
+        var triggerOn = pieLabelCfg.triggerOn || 'touchstart';
+        (0, common.addEventListener)(this.canvasDom, triggerOn, this._handleEvent);
+      };
+
+      _proto.unBindEvents = function unBindEvents() {
+        var pieLabelCfg = this.pieLabelCfg;
+        var triggerOn = pieLabelCfg.triggerOn || 'touchstart';
+        (0, common.removeEventListener)(this.canvasDom, triggerOn, this._handleEvent);
+      };
+
+      _proto.clear = function clear() {
+        this.labelGroup && this.labelGroup.clear();
+        this.halo && this.halo.remove(true);
+        this.lastSelectedData = null;
+        this.drawnLabels = [];
+        this.unBindEvents();
+      };
+
+      _proto._drawLabel = function _drawLabel(label) {
+        var pieLabelCfg = this.pieLabelCfg,
+            chart = this.chart;
+        var canvasWidth = chart.get('width');
+        var sidePadding = pieLabelCfg.sidePadding;
+        var y = label.y,
+            textGroup = label.textGroup;
+        var children = textGroup.get('children');
+        var textAttrs = {
+          textAlign: label._side === 'left' ? 'left' : 'right',
+          x: label._side === 'left' ? sidePadding : canvasWidth - sidePadding
+        };
+        children.forEach(function (child) {
+          child.attr(textAttrs);
+          child.attr('y', y + child.get('offsetY'));
+        });
+        return textGroup;
+      };
+
+      _proto._drawLabelLine = function _drawLabelLine(label, maxLabelWidth) {
+        var chart = this.chart,
+            pieLabelCfg = this.pieLabelCfg,
+            labelGroup = this.labelGroup;
+        var canvasWidth = chart.get('width');
+        var sidePadding = pieLabelCfg.sidePadding,
+            adjustOffset = pieLabelCfg.adjustOffset,
+            lineStyle = pieLabelCfg.lineStyle,
+            anchorStyle = pieLabelCfg.anchorStyle,
+            skipOverlapLabels = pieLabelCfg.skipOverlapLabels;
+        var _anchor = label._anchor,
+            _inflection = label._inflection,
+            fill = label.fill,
+            y = label.y;
+        var lastPoint = {
+          x: label._side === 'left' ? sidePadding : canvasWidth - sidePadding,
+          y: y
+        };
+        var points = [_anchor, _inflection, lastPoint];
+
+        if (!skipOverlapLabels && _inflection.y !== y) {
+          // 展示全部文本文本位置做过调整
+          if (_inflection.y < y) {
+            // 文本被调整下去了,则添加拐点连接线
+            var point1 = _inflection;
+            var point2 = {
+              x: label._side === 'left' ? lastPoint.x + maxLabelWidth + adjustOffset : lastPoint.x - maxLabelWidth - adjustOffset,
+              y: _inflection.y
+            };
+            var point3 = {
+              x: label._side === 'left' ? lastPoint.x + maxLabelWidth : lastPoint.x - maxLabelWidth,
+              y: lastPoint.y
+            };
+            points = [_anchor, point1, point2, point3, lastPoint];
+
+            if (label._side === 'right' && point2.x < point1.x || label._side === 'left' && point2.x > point1.x) {
+              points = [_anchor, point3, lastPoint];
+            }
+          } else {
+            points = [_anchor, {
+              x: _inflection.x,
+              y: y
+            }, lastPoint];
+          }
+        }
+
+        labelGroup.addShape('Polyline', {
+          attrs: (0, common.mix)({
+            points: points,
+            lineWidth: 1,
+            stroke: fill
+          }, lineStyle)
+        }); // 绘制锚点
+
+        labelGroup.addShape('Circle', {
+          attrs: (0, common.mix)({
+            x: _anchor.x,
+            y: _anchor.y,
+            r: 2,
+            fill: fill
+          }, anchorStyle)
+        });
+      };
+
+      _proto._antiCollision = function _antiCollision(half) {
+        var self = this;
+        var chart = self.chart,
+            pieLabelCfg = self.pieLabelCfg;
+        var coord = chart.get('coord');
+        var canvasHeight = chart.get('height');
+        var center = coord.center,
+            r = coord.circleRadius;
+        var inflectionOffset = pieLabelCfg.inflectionOffset,
+            lineHeight = pieLabelCfg.lineHeight;
+        var startY = center.y - r - inflectionOffset - lineHeight;
+        var overlapping = true;
+        var totalH = canvasHeight;
+        var i;
+        var maxY = 0;
+        var minY = Number.MIN_VALUE;
+        var maxLabelWidth = 0;
+        var boxes = half.map(function (label) {
+          var labelY = label.y;
+
+          if (labelY > maxY) {
+            maxY = labelY;
+          }
+
+          if (labelY < minY) {
+            minY = labelY;
+          }
+
+          var textGroup = label.textGroup;
+          var labelWidth = textGroup.getBBox().width;
+
+          if (labelWidth >= maxLabelWidth) {
+            maxLabelWidth = labelWidth;
+          }
+
+          return {
+            size: lineHeight,
+            targets: [labelY - startY]
+          };
+        });
+
+        if (maxY - startY > totalH) {
+          totalH = maxY - startY;
+        }
+
+        var iteratorBoxed = function iteratorBoxed(boxes) {
+          boxes.forEach(function (box) {
+            var target = (Math.min.apply(minY, box.targets) + Math.max.apply(minY, box.targets)) / 2;
+            box.pos = Math.min(Math.max(minY, target - box.size / 2), totalH - box.size);
+          });
+        };
+
+        while (overlapping) {
+          iteratorBoxed(boxes); // detect overlapping and join boxes
+
+          overlapping = false;
+          i = boxes.length;
+
+          while (i--) {
+            if (i > 0) {
+              var previousBox = boxes[i - 1];
+              var box = boxes[i];
+
+              if (previousBox.pos + previousBox.size > box.pos) {
+                // overlapping
+                previousBox.size += box.size;
+                previousBox.targets = previousBox.targets.concat(box.targets); // overflow, shift up
+
+                if (previousBox.pos + previousBox.size > totalH) {
+                  previousBox.pos = totalH - previousBox.size;
+                }
+
+                boxes.splice(i, 1); // removing box
+
+                overlapping = true;
+              }
+            }
+          }
+        }
+
+        i = 0;
+        boxes.forEach(function (b) {
+          var posInCompositeBox = startY; // middle of the label
+
+          b.targets.forEach(function () {
+            half[i].y = b.pos + posInCompositeBox + lineHeight / 2;
+            posInCompositeBox += lineHeight;
+            i++;
+          });
+        });
+        var drawnLabels = [];
+        half.forEach(function (label) {
+          var textGroup = self._drawLabel(label);
+
+          var labelGroup = self.labelGroup;
+          labelGroup.add(textGroup);
+
+          self._drawLabelLine(label, maxLabelWidth);
+
+          drawnLabels.push(textGroup);
+        });
+        return drawnLabels;
+      };
+
+      _proto._getSelectedShapeByData = function _getSelectedShapeByData(data) {
+        var selectedShape = null;
+        var chart = this.chart;
+        var geom = chart.get('geoms')[0];
+        var container = geom.get('container');
+        var children = container.get('children');
+        (0, common.each)(children, function (child) {
+          if (child.get('isShape') && child.get('className') === geom.get('type')) {
+            // get geometry's shape
+            var shapeData = child.get('origin')._origin;
+
+            if ((0, common.isObjectValueEqual)(shapeData, data)) {
+              selectedShape = child;
+              return false;
+            }
+          }
+        });
+        return selectedShape;
+      };
+
+      _proto._activeShape = function _activeShape(data) {
+        var chart = this.chart,
+            lastSelectedData = this.lastSelectedData,
+            pieLabelCfg = this.pieLabelCfg;
+
+        if (data === lastSelectedData) {
+          return;
+        }
+
+        this.lastSelectedData = data;
+        var activeStyle = pieLabelCfg.activeStyle;
+
+        var selectedShape = this._getSelectedShapeByData(data);
+
+        var _selectedShape$_attrs = selectedShape._attrs.attrs,
+            x = _selectedShape$_attrs.x,
+            y = _selectedShape$_attrs.y,
+            startAngle = _selectedShape$_attrs.startAngle,
+            endAngle = _selectedShape$_attrs.endAngle,
+            r = _selectedShape$_attrs.r,
+            fill = _selectedShape$_attrs.fill;
+        var frontPlot = chart.get('frontPlot');
+        this.halo && this.halo.remove(true);
+        var halo = frontPlot.addShape('sector', {
+          attrs: (0, common.mix)({
+            x: x,
+            y: y,
+            r: r + activeStyle.offset + activeStyle.appendRadius,
+            r0: r + activeStyle.offset,
+            fill: fill,
+            startAngle: startAngle,
+            endAngle: endAngle
+          }, activeStyle)
+        });
+        this.halo = halo;
+        chart.get('canvas').draw();
+      };
+
+      return controller;
+    }();
+
+    function init(chart) {
+      var frontPlot = chart.get('frontPlot');
+      var labelGroup = frontPlot.addGroup({
+        className: 'pie-label',
+        zIndex: 0
+      });
+      var pieLabelController = new controller({
+        chart: chart,
+        labelGroup: labelGroup
+      });
+      chart.set('pieLabelController', pieLabelController);
+
+      chart.pieLabel = function (cfg) {
+        cfg = (0, common.deepMix)({}, DEFAULT_CFG, cfg);
+        pieLabelController.pieLabelCfg = cfg;
+        return this;
+      };
+    }
+
+    function afterGeomDraw(chart) {
+      var controller = chart.get('pieLabelController');
+
+      if (controller.pieLabelCfg) {
+        // 用户配置了饼图文本
+        controller.renderLabels();
+        controller.bindEvents(); // 绑定事件
+      }
+    }
+
+    function clearInner(chart) {
+      var controller = chart.get('pieLabelController');
+
+      if (controller.pieLabelCfg) {
+        // 用户配置了饼图文本
+        controller.clear();
+      }
+    }
+
+    var _default = {
+      init: init,
+      afterGeomDraw: afterGeomDraw,
+      clearInner: clearInner
+    };
+    exports["default"] = _default;
+    });
+
+    var PieLabel = unwrapExports(pieLabel);
+    var pieLabel_1 = pieLabel.init;
+    var pieLabel_2 = pieLabel.afterGeomDraw;
+    var pieLabel_3 = pieLabel.clearInner;
+
+    F2.Chart.plugins.register(PieLabel);
+    function wrapEvent(e) {
+      if (!e) return;
+      if (!e.preventDefault) {
+        e.preventDefault = function() {};
+      }
+      return e;
+    }
+
+    Component({
+      /**
+       * 组件的属性列表
+       */
+      properties: {
+        onInit: {
+          type: 'Function',
+          value: () => {}
+        }
+      },
+
+      /**
+       * 组件的初始数据
+       */
+      data: {
+
+      },
+
+      ready() {
+        const query = wx.createSelectorQuery().in(this);
+        query.select('.f2-canvas')
+          .fields({
+            node: true,
+            size: true
+          })
+          .exec(res => {
+            const { node, width, height } = res[0];
+            const context = node.getContext('2d');
+            const pixelRatio = wx.getSystemInfoSync().pixelRatio;
+            // 高清设置
+            node.width = width * pixelRatio;
+            node.height = height * pixelRatio;
+
+            const config = { context, width, height, pixelRatio };
+            const chart = this.data.onInit(F2, config);
+            if (chart) {
+              this.chart = chart;
+              this.canvasEl = chart.get('el');
+            }
+          });
+      },
+
+      /**
+       * 组件的方法列表
+       */
+      methods: {
+        touchStart(e) {
+          const canvasEl = this.canvasEl;
+          if (!canvasEl) {
+            return;
+          }
+          canvasEl.dispatchEvent('touchstart', wrapEvent(e));
+        },
+        touchMove(e) {
+          const canvasEl = this.canvasEl;
+          if (!canvasEl) {
+            return;
+          }
+          canvasEl.dispatchEvent('touchmove', wrapEvent(e));
+        },
+        touchEnd(e) {
+          const canvasEl = this.canvasEl;
+          if (!canvasEl) {
+            return;
+          }
+          canvasEl.dispatchEvent('touchend', wrapEvent(e));
+        }
+      }
+    });
+
+})));

Разлика између датотеке није приказан због своје велике величине
+ 0 - 0
miniprogram/miniprogram_npm/@antv/wx-f2/index.js.map


+ 4 - 0
miniprogram/miniprogram_npm/@antv/wx-f2/index.json

@@ -0,0 +1,4 @@
+{
+  "component": true,
+  "usingComponents": {}
+}

+ 8 - 0
miniprogram/miniprogram_npm/@antv/wx-f2/index.wxml

@@ -0,0 +1,8 @@
+<canvas
+  type="2d"
+  class="f2-canvas"
+  bindtouchstart="touchStart"
+  bindtouchmove="touchMove"
+  bindtouchend="touchEnd"
+>
+</canvas>

+ 4 - 0
miniprogram/miniprogram_npm/@antv/wx-f2/index.wxss

@@ -0,0 +1,4 @@
+.f2-canvas {
+  width: 100%;
+  height: 100%;
+}

+ 1 - 0
miniprogram/miniprogram_npm/@vant/weapp/action-sheet/index.d.ts

@@ -0,0 +1 @@
+export {};

+ 73 - 0
miniprogram/miniprogram_npm/@vant/weapp/action-sheet/index.js

@@ -0,0 +1,73 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var component_1 = require("../common/component");
+var button_1 = require("../mixins/button");
+(0, component_1.VantComponent)({
+    mixins: [button_1.button],
+    props: {
+        show: Boolean,
+        title: String,
+        cancelText: String,
+        description: String,
+        round: {
+            type: Boolean,
+            value: true,
+        },
+        zIndex: {
+            type: Number,
+            value: 100,
+        },
+        actions: {
+            type: Array,
+            value: [],
+        },
+        overlay: {
+            type: Boolean,
+            value: true,
+        },
+        closeOnClickOverlay: {
+            type: Boolean,
+            value: true,
+        },
+        closeOnClickAction: {
+            type: Boolean,
+            value: true,
+        },
+        safeAreaInsetBottom: {
+            type: Boolean,
+            value: true,
+        },
+    },
+    methods: {
+        onSelect: function (event) {
+            var _this = this;
+            var index = event.currentTarget.dataset.index;
+            var _a = this.data, actions = _a.actions, closeOnClickAction = _a.closeOnClickAction, canIUseGetUserProfile = _a.canIUseGetUserProfile;
+            var item = actions[index];
+            if (item) {
+                this.$emit('select', item);
+                if (closeOnClickAction) {
+                    this.onClose();
+                }
+                if (item.openType === 'getUserInfo' && canIUseGetUserProfile) {
+                    wx.getUserProfile({
+                        desc: item.getUserProfileDesc || '  ',
+                        complete: function (userProfile) {
+                            _this.$emit('getuserinfo', userProfile);
+                        },
+                    });
+                }
+            }
+        },
+        onCancel: function () {
+            this.$emit('cancel');
+        },
+        onClose: function () {
+            this.$emit('close');
+        },
+        onClickOverlay: function () {
+            this.$emit('click-overlay');
+            this.onClose();
+        },
+    },
+});

+ 8 - 0
miniprogram/miniprogram_npm/@vant/weapp/action-sheet/index.json

@@ -0,0 +1,8 @@
+{
+  "component": true,
+  "usingComponents": {
+    "van-icon": "../icon/index",
+    "van-popup": "../popup/index",
+    "van-loading": "../loading/index"
+  }
+}

+ 69 - 0
miniprogram/miniprogram_npm/@vant/weapp/action-sheet/index.wxml

@@ -0,0 +1,69 @@
+<wxs src="../wxs/utils.wxs" module="utils" />
+
+<van-popup
+  show="{{ show }}"
+  position="bottom"
+  round="{{ round }}"
+  z-index="{{ zIndex }}"
+  overlay="{{ overlay }}"
+  custom-class="van-action-sheet"
+  safe-area-inset-bottom="{{ safeAreaInsetBottom }}"
+  close-on-click-overlay="{{ closeOnClickOverlay }}"
+  bind:close="onClickOverlay"
+>
+  <view wx:if="{{ title }}" class="van-action-sheet__header">
+    {{ title }}
+    <van-icon
+      name="cross"
+      custom-class="van-action-sheet__close"
+      bind:click="onClose"
+    />
+  </view>
+  <view wx:if="{{ description }}" class="van-action-sheet__description van-hairline--bottom">
+    {{ description }}
+  </view>
+  <view wx:if="{{ actions && actions.length }}">
+    <!-- button外包一层view,防止actions动态变化,导致渲染时button被打散 -->
+    <button
+      wx:for="{{ actions }}"
+      wx:key="index"
+      open-type="{{ item.disabled || item.loading || (canIUseGetUserProfile && item.openType === 'getUserInfo') ? '' : item.openType }}"
+      style="{{ item.color ? 'color: ' + item.color : '' }}"
+      class="{{ utils.bem('action-sheet__item', { disabled: item.disabled || item.loading }) }} {{ item.className || '' }}"
+      hover-class="van-action-sheet__item--hover"
+      data-index="{{ index }}"
+      bindtap="{{ item.disabled || item.loading ? '' : 'onSelect' }}"
+      bindgetuserinfo="onGetUserInfo"
+      bindcontact="onContact"
+      bindgetphonenumber="onGetPhoneNumber"
+      binderror="onError"
+      bindlaunchapp="onLaunchApp"
+      bindopensetting="onOpenSetting"
+      lang="{{ lang }}"
+      session-from="{{ sessionFrom }}"
+      send-message-title="{{ sendMessageTitle }}"
+      send-message-path="{{ sendMessagePath }}"
+      send-message-img="{{ sendMessageImg }}"
+      show-message-card="{{ showMessageCard }}"
+      app-parameter="{{ appParameter }}"
+    >
+      <block wx:if="{{ !item.loading }}">
+        {{ item.name }}
+        <view wx:if="{{ item.subname }}" class="van-action-sheet__subname" >{{ item.subname }}</view>
+      </block>
+      <van-loading wx:else custom-class="van-action-sheet__loading" size="22px" />
+    </button>
+  </view>
+  <slot />
+  <block wx:if="{{ cancelText }}">
+    <view class="van-action-sheet__gap" />
+    <view
+      class="van-action-sheet__cancel"
+      hover-class="van-action-sheet__cancel--hover"
+      hover-stay-time="70"
+      bind:tap="onCancel"
+    >
+      {{ cancelText }}
+    </view>
+  </block>
+</van-popup>

+ 1 - 0
miniprogram/miniprogram_npm/@vant/weapp/action-sheet/index.wxss

@@ -0,0 +1 @@
+@import '../common/index.wxss';.van-action-sheet{color:var(--action-sheet-item-text-color,#323233);max-height:var(--action-sheet-max-height,90%)!important}.van-action-sheet__cancel,.van-action-sheet__item{background-color:var(--action-sheet-item-background,#fff);font-size:var(--action-sheet-item-font-size,16px);line-height:var(--action-sheet-item-line-height,22px);padding:14px 16px;text-align:center}.van-action-sheet__cancel--hover,.van-action-sheet__item--hover{background-color:#f2f3f5}.van-action-sheet__cancel:after,.van-action-sheet__item:after{border-width:0}.van-action-sheet__cancel{color:var(--action-sheet-cancel-text-color,#646566)}.van-action-sheet__gap{background-color:var(--action-sheet-cancel-padding-color,#f7f8fa);display:block;height:var(--action-sheet-cancel-padding-top,8px)}.van-action-sheet__item--disabled{color:var(--action-sheet-item-disabled-text-color,#c8c9cc)}.van-action-sheet__item--disabled.van-action-sheet__item--hover{background-color:var(--action-sheet-item-background,#fff)}.van-action-sheet__subname{color:var(--action-sheet-subname-color,#969799);font-size:var(--action-sheet-subname-font-size,12px);line-height:var(--action-sheet-subname-line-height,20px);margin-top:var(--padding-xs,8px)}.van-action-sheet__header{font-size:var(--action-sheet-header-font-size,16px);font-weight:var(--font-weight-bold,500);line-height:var(--action-sheet-header-height,48px);text-align:center}.van-action-sheet__description{color:var(--action-sheet-description-color,#969799);font-size:var(--action-sheet-description-font-size,14px);line-height:var(--action-sheet-description-line-height,20px);padding:20px var(--padding-md,16px);text-align:center}.van-action-sheet__close{color:var(--action-sheet-close-icon-color,#c8c9cc);font-size:var(--action-sheet-close-icon-size,22px)!important;line-height:inherit!important;padding:var(--action-sheet-close-icon-padding,0 16px);position:absolute!important;right:0;top:0}.van-action-sheet__loading{display:flex!important}

+ 1 - 0
miniprogram/miniprogram_npm/@vant/weapp/area/index.d.ts

@@ -0,0 +1 @@
+export {};

+ 232 - 0
miniprogram/miniprogram_npm/@vant/weapp/area/index.js

@@ -0,0 +1,232 @@
+"use strict";
+var __assign = (this && this.__assign) || function () {
+    __assign = Object.assign || function(t) {
+        for (var s, i = 1, n = arguments.length; i < n; i++) {
+            s = arguments[i];
+            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
+                t[p] = s[p];
+        }
+        return t;
+    };
+    return __assign.apply(this, arguments);
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var component_1 = require("../common/component");
+var shared_1 = require("../picker/shared");
+var utils_1 = require("../common/utils");
+var EMPTY_CODE = '000000';
+(0, component_1.VantComponent)({
+    classes: ['active-class', 'toolbar-class', 'column-class'],
+    props: __assign(__assign({}, shared_1.pickerProps), { value: {
+            type: String,
+            observer: function (value) {
+                this.code = value;
+                this.setValues();
+            },
+        }, areaList: {
+            type: Object,
+            value: {},
+            observer: 'setValues',
+        }, columnsNum: {
+            type: null,
+            value: 3,
+        }, columnsPlaceholder: {
+            type: Array,
+            observer: function (val) {
+                this.setData({
+                    typeToColumnsPlaceholder: {
+                        province: val[0] || '',
+                        city: val[1] || '',
+                        county: val[2] || '',
+                    },
+                });
+            },
+        } }),
+    data: {
+        columns: [{ values: [] }, { values: [] }, { values: [] }],
+        typeToColumnsPlaceholder: {},
+    },
+    mounted: function () {
+        var _this = this;
+        (0, utils_1.requestAnimationFrame)(function () {
+            _this.setValues();
+        });
+    },
+    methods: {
+        getPicker: function () {
+            if (this.picker == null) {
+                this.picker = this.selectComponent('.van-area__picker');
+            }
+            return this.picker;
+        },
+        onCancel: function (event) {
+            this.emit('cancel', event.detail);
+        },
+        onConfirm: function (event) {
+            var index = event.detail.index;
+            var value = event.detail.value;
+            value = this.parseValues(value);
+            this.emit('confirm', { value: value, index: index });
+        },
+        emit: function (type, detail) {
+            detail.values = detail.value;
+            delete detail.value;
+            this.$emit(type, detail);
+        },
+        parseValues: function (values) {
+            var columnsPlaceholder = this.data.columnsPlaceholder;
+            return values.map(function (value, index) {
+                if (value &&
+                    (!value.code || value.name === columnsPlaceholder[index])) {
+                    return __assign(__assign({}, value), { code: '', name: '' });
+                }
+                return value;
+            });
+        },
+        onChange: function (event) {
+            var _this = this;
+            var _a;
+            var _b = event.detail, index = _b.index, picker = _b.picker, value = _b.value;
+            this.code = value[index].code;
+            (_a = this.setValues()) === null || _a === void 0 ? void 0 : _a.then(function () {
+                _this.$emit('change', {
+                    picker: picker,
+                    values: _this.parseValues(picker.getValues()),
+                    index: index,
+                });
+            });
+        },
+        getConfig: function (type) {
+            var areaList = this.data.areaList;
+            return (areaList && areaList["".concat(type, "_list")]) || {};
+        },
+        getList: function (type, code) {
+            if (type !== 'province' && !code) {
+                return [];
+            }
+            var typeToColumnsPlaceholder = this.data.typeToColumnsPlaceholder;
+            var list = this.getConfig(type);
+            var result = Object.keys(list).map(function (code) { return ({
+                code: code,
+                name: list[code],
+            }); });
+            if (code != null) {
+                // oversea code
+                if (code[0] === '9' && type === 'city') {
+                    code = '9';
+                }
+                result = result.filter(function (item) { return item.code.indexOf(code) === 0; });
+            }
+            if (typeToColumnsPlaceholder[type] && result.length) {
+                // set columns placeholder
+                var codeFill = type === 'province'
+                    ? ''
+                    : type === 'city'
+                        ? EMPTY_CODE.slice(2, 4)
+                        : EMPTY_CODE.slice(4, 6);
+                result.unshift({
+                    code: "".concat(code).concat(codeFill),
+                    name: typeToColumnsPlaceholder[type],
+                });
+            }
+            return result;
+        },
+        getIndex: function (type, code) {
+            var compareNum = type === 'province' ? 2 : type === 'city' ? 4 : 6;
+            var list = this.getList(type, code.slice(0, compareNum - 2));
+            // oversea code
+            if (code[0] === '9' && type === 'province') {
+                compareNum = 1;
+            }
+            code = code.slice(0, compareNum);
+            for (var i = 0; i < list.length; i++) {
+                if (list[i].code.slice(0, compareNum) === code) {
+                    return i;
+                }
+            }
+            return 0;
+        },
+        setValues: function () {
+            var picker = this.getPicker();
+            if (!picker) {
+                return;
+            }
+            var code = this.code || this.getDefaultCode();
+            var provinceList = this.getList('province');
+            var cityList = this.getList('city', code.slice(0, 2));
+            var stack = [];
+            var indexes = [];
+            var columnsNum = this.data.columnsNum;
+            if (columnsNum >= 1) {
+                stack.push(picker.setColumnValues(0, provinceList, false));
+                indexes.push(this.getIndex('province', code));
+            }
+            if (columnsNum >= 2) {
+                stack.push(picker.setColumnValues(1, cityList, false));
+                indexes.push(this.getIndex('city', code));
+                if (cityList.length && code.slice(2, 4) === '00') {
+                    code = cityList[0].code;
+                }
+            }
+            if (columnsNum === 3) {
+                stack.push(picker.setColumnValues(2, this.getList('county', code.slice(0, 4)), false));
+                indexes.push(this.getIndex('county', code));
+            }
+            return Promise.all(stack)
+                .catch(function () { })
+                .then(function () { return picker.setIndexes(indexes); })
+                .catch(function () { });
+        },
+        getDefaultCode: function () {
+            var columnsPlaceholder = this.data.columnsPlaceholder;
+            if (columnsPlaceholder.length) {
+                return EMPTY_CODE;
+            }
+            var countyCodes = Object.keys(this.getConfig('county'));
+            if (countyCodes[0]) {
+                return countyCodes[0];
+            }
+            var cityCodes = Object.keys(this.getConfig('city'));
+            if (cityCodes[0]) {
+                return cityCodes[0];
+            }
+            return '';
+        },
+        getValues: function () {
+            var picker = this.getPicker();
+            if (!picker) {
+                return [];
+            }
+            return this.parseValues(picker.getValues().filter(function (value) { return !!value; }));
+        },
+        getDetail: function () {
+            var values = this.getValues();
+            var area = {
+                code: '',
+                country: '',
+                province: '',
+                city: '',
+                county: '',
+            };
+            if (!values.length) {
+                return area;
+            }
+            var names = values.map(function (item) { return item.name; });
+            area.code = values[values.length - 1].code;
+            if (area.code[0] === '9') {
+                area.country = names[1] || '';
+                area.province = names[2] || '';
+            }
+            else {
+                area.province = names[0] || '';
+                area.city = names[1] || '';
+                area.county = names[2] || '';
+            }
+            return area;
+        },
+        reset: function (code) {
+            this.code = code || '';
+            return this.setValues();
+        },
+    },
+});

+ 6 - 0
miniprogram/miniprogram_npm/@vant/weapp/area/index.json

@@ -0,0 +1,6 @@
+{
+  "component": true,
+  "usingComponents": {
+    "van-picker": "../picker/index"
+  }
+}

+ 20 - 0
miniprogram/miniprogram_npm/@vant/weapp/area/index.wxml

@@ -0,0 +1,20 @@
+<wxs src="./index.wxs" module="computed" />
+
+<van-picker
+  class="van-area__picker"
+  active-class="active-class"
+  toolbar-class="toolbar-class"
+  column-class="column-class"
+  show-toolbar
+  value-key="name"
+  title="{{ title }}"
+  loading="{{ loading }}"
+  columns="{{ computed.displayColumns(columns, columnsNum) }}"
+  item-height="{{ itemHeight }}"
+  visible-item-count="{{ visibleItemCount }}"
+  cancel-button-text="{{ cancelButtonText }}"
+  confirm-button-text="{{ confirmButtonText }}"
+  bind:change="onChange"
+  bind:confirm="onConfirm"
+  bind:cancel="onCancel"
+/>

+ 8 - 0
miniprogram/miniprogram_npm/@vant/weapp/area/index.wxs

@@ -0,0 +1,8 @@
+/* eslint-disable */
+function displayColumns(columns, columnsNum) {
+  return columns.slice(0, +columnsNum);
+}
+
+module.exports = {
+  displayColumns: displayColumns,
+};

+ 1 - 0
miniprogram/miniprogram_npm/@vant/weapp/area/index.wxss

@@ -0,0 +1 @@
+@import '../common/index.wxss';

+ 1 - 0
miniprogram/miniprogram_npm/@vant/weapp/button/index.d.ts

@@ -0,0 +1 @@
+export {};

+ 67 - 0
miniprogram/miniprogram_npm/@vant/weapp/button/index.js

@@ -0,0 +1,67 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var component_1 = require("../common/component");
+var button_1 = require("../mixins/button");
+var version_1 = require("../common/version");
+var mixins = [button_1.button];
+if ((0, version_1.canIUseFormFieldButton)()) {
+    mixins.push('wx://form-field-button');
+}
+(0, component_1.VantComponent)({
+    mixins: mixins,
+    classes: ['hover-class', 'loading-class'],
+    data: {
+        baseStyle: '',
+    },
+    props: {
+        formType: String,
+        icon: String,
+        classPrefix: {
+            type: String,
+            value: 'van-icon',
+        },
+        plain: Boolean,
+        block: Boolean,
+        round: Boolean,
+        square: Boolean,
+        loading: Boolean,
+        hairline: Boolean,
+        disabled: Boolean,
+        loadingText: String,
+        customStyle: String,
+        loadingType: {
+            type: String,
+            value: 'circular',
+        },
+        type: {
+            type: String,
+            value: 'default',
+        },
+        dataset: null,
+        size: {
+            type: String,
+            value: 'normal',
+        },
+        loadingSize: {
+            type: String,
+            value: '20px',
+        },
+        color: String,
+    },
+    methods: {
+        onClick: function (event) {
+            var _this = this;
+            this.$emit('click', event);
+            var _a = this.data, canIUseGetUserProfile = _a.canIUseGetUserProfile, openType = _a.openType, getUserProfileDesc = _a.getUserProfileDesc, lang = _a.lang;
+            if (openType === 'getUserInfo' && canIUseGetUserProfile) {
+                wx.getUserProfile({
+                    desc: getUserProfileDesc || '  ',
+                    lang: lang || 'en',
+                    complete: function (userProfile) {
+                        _this.$emit('getuserinfo', userProfile);
+                    },
+                });
+            }
+        },
+    },
+});

+ 7 - 0
miniprogram/miniprogram_npm/@vant/weapp/button/index.json

@@ -0,0 +1,7 @@
+{
+  "component": true,
+  "usingComponents": {
+    "van-icon": "../icon/index",
+    "van-loading": "../loading/index"
+  }
+}

+ 53 - 0
miniprogram/miniprogram_npm/@vant/weapp/button/index.wxml

@@ -0,0 +1,53 @@
+<wxs src="../wxs/utils.wxs" module="utils" />
+<wxs src="./index.wxs" module="computed" />
+
+<button
+  id="{{ id }}"
+  data-detail="{{ dataset }}"
+  class="custom-class {{ utils.bem('button', [type, size, { block, round, plain, square, loading, disabled, hairline, unclickable: disabled || loading }]) }} {{ hairline ? 'van-hairline--surround' : '' }}"
+  hover-class="van-button--active hover-class"
+  lang="{{ lang }}"
+  form-type="{{ formType }}"
+  style="{{ computed.rootStyle({ plain, color, customStyle }) }}"
+  open-type="{{ disabled || loading || (canIUseGetUserProfile && openType === 'getUserInfo') ? '' : openType }}"
+  business-id="{{ businessId }}"
+  session-from="{{ sessionFrom }}"
+  send-message-title="{{ sendMessageTitle }}"
+  send-message-path="{{ sendMessagePath }}"
+  send-message-img="{{ sendMessageImg }}"
+  show-message-card="{{ showMessageCard }}"
+  app-parameter="{{ appParameter }}"
+  aria-label="{{ ariaLabel }}"
+  bindtap="{{ disabled || loading ? '' : 'onClick' }}"
+  bindgetuserinfo="onGetUserInfo"
+  bindcontact="onContact"
+  bindgetphonenumber="onGetPhoneNumber"
+  binderror="onError"
+  bindlaunchapp="onLaunchApp"
+  bindopensetting="onOpenSetting"
+>
+  <block wx:if="{{ loading }}">
+    <van-loading
+      custom-class="loading-class"
+      size="{{ loadingSize }}"
+      type="{{ loadingType }}"
+      color="{{ computed.loadingColor({ type, color, plain }) }}"
+    />
+    <view wx:if="{{ loadingText }}" class="van-button__loading-text">
+      {{ loadingText }}
+    </view>
+  </block>
+  <block wx:else>
+    <van-icon
+      wx:if="{{ icon }}"
+      size="1.2em"
+      name="{{ icon }}"
+      class-prefix="{{ classPrefix }}"
+      class="van-button__icon"
+      custom-style="line-height: inherit;"
+    />
+    <view class="van-button__text">
+      <slot />
+    </view>
+  </block>
+</button>

+ 39 - 0
miniprogram/miniprogram_npm/@vant/weapp/button/index.wxs

@@ -0,0 +1,39 @@
+/* eslint-disable */
+var style = require('../wxs/style.wxs');
+
+function rootStyle(data) {
+  if (!data.color) {
+    return data.customStyle;
+  }
+
+  var properties = {
+    color: data.plain ? data.color : '#fff',
+    background: data.plain ? null : data.color,
+  };
+
+  // hide border when color is linear-gradient
+  if (data.color.indexOf('gradient') !== -1) {
+    properties.border = 0;
+  } else {
+    properties['border-color'] = data.color;
+  }
+
+  return style([properties, data.customStyle]);
+}
+
+function loadingColor(data) {
+  if (data.plain) {
+    return data.color ? data.color : '#c9c9c9';
+  }
+
+  if (data.type === 'default') {
+    return '#c9c9c9';
+  }
+
+  return '#fff';
+}
+
+module.exports = {
+  rootStyle: rootStyle,
+  loadingColor: loadingColor,
+};

Разлика између датотеке није приказан због своје велике величине
+ 0 - 0
miniprogram/miniprogram_npm/@vant/weapp/button/index.wxss


+ 68 - 0
miniprogram/miniprogram_npm/@vant/weapp/calendar/calendar.wxml

@@ -0,0 +1,68 @@
+<view class="van-calendar">
+  <header
+    title="{{ title }}"
+    showTitle="{{ showTitle }}"
+    subtitle="{{ subtitle }}"
+    showSubtitle="{{ showSubtitle }}"
+    firstDayOfWeek="{{ firstDayOfWeek }}"
+    bind:click-subtitle="onClickSubtitle"
+  >
+    <slot name="title" slot="title"></slot>
+  </header>
+
+  <scroll-view
+    class="van-calendar__body"
+    scroll-y
+    scroll-into-view="{{ scrollIntoView }}"
+  >
+    <month
+      wx:for="{{ computed.getMonths(minDate, maxDate) }}"
+      wx:key="index"
+      id="month{{ index }}"
+      class="month"
+      data-date="{{ item }}"
+      date="{{ item }}"
+      type="{{ type }}"
+      color="{{ color }}"
+      minDate="{{ minDate }}"
+      maxDate="{{ maxDate }}"
+      showMark="{{ showMark }}"
+      formatter="{{ formatter }}"
+      rowHeight="{{ rowHeight }}"
+      currentDate="{{ currentDate }}"
+      showSubtitle="{{ showSubtitle }}"
+      allowSameDay="{{ allowSameDay }}"
+      showMonthTitle="{{ index !== 0 || !showSubtitle }}"
+      firstDayOfWeek="{{ firstDayOfWeek }}"
+      bind:click="onClickDay"
+    />
+  </scroll-view>
+
+  <view
+    class="{{ utils.bem('calendar__footer', { safeAreaInsetBottom }) }}"
+  >
+    <slot name="footer"></slot>
+  </view>
+
+  <view
+    class="{{ utils.bem('calendar__footer', { safeAreaInsetBottom }) }}"
+  >
+    <van-button
+      wx:if="{{ showConfirm }}"
+      round
+      block
+      type="danger"
+      color="{{ color }}"
+      custom-class="van-calendar__confirm"
+      disabled="{{ computed.getButtonDisabled(type, currentDate) }}"
+      nativeType="text"
+      bind:click="onConfirm"
+    >
+      {{
+        computed.getButtonDisabled(type, currentDate)
+          ? confirmDisabledText
+          : confirmText
+      }}
+    </van-button>
+  </view>
+</view>

+ 1 - 0
miniprogram/miniprogram_npm/@vant/weapp/calendar/components/header/index.d.ts

@@ -0,0 +1 @@
+export {};

+ 45 - 0
miniprogram/miniprogram_npm/@vant/weapp/calendar/components/header/index.js

@@ -0,0 +1,45 @@
+"use strict";
+var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
+    if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
+        if (ar || !(i in from)) {
+            if (!ar) ar = Array.prototype.slice.call(from, 0, i);
+            ar[i] = from[i];
+        }
+    }
+    return to.concat(ar || Array.prototype.slice.call(from));
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var component_1 = require("../../../common/component");
+(0, component_1.VantComponent)({
+    props: {
+        title: {
+            type: String,
+            value: '日期选择',
+        },
+        subtitle: String,
+        showTitle: Boolean,
+        showSubtitle: Boolean,
+        firstDayOfWeek: {
+            type: Number,
+            observer: 'initWeekDay',
+        },
+    },
+    data: {
+        weekdays: [],
+    },
+    created: function () {
+        this.initWeekDay();
+    },
+    methods: {
+        initWeekDay: function () {
+            var defaultWeeks = ['日', '一', '二', '三', '四', '五', '六'];
+            var firstDayOfWeek = this.data.firstDayOfWeek || 0;
+            this.setData({
+                weekdays: __spreadArray(__spreadArray([], defaultWeeks.slice(firstDayOfWeek, 7), true), defaultWeeks.slice(0, firstDayOfWeek), true),
+            });
+        },
+        onClickSubtitle: function (event) {
+            this.$emit('click-subtitle', event);
+        },
+    },
+});

+ 3 - 0
miniprogram/miniprogram_npm/@vant/weapp/calendar/components/header/index.json

@@ -0,0 +1,3 @@
+{
+  "component": true
+}

+ 16 - 0
miniprogram/miniprogram_npm/@vant/weapp/calendar/components/header/index.wxml

@@ -0,0 +1,16 @@
+<view class="van-calendar__header">
+  <block wx:if="{{ showTitle }}">
+    <view class="van-calendar__header-title"><slot name="title"></slot></view>
+    <view class="van-calendar__header-title">{{ title }}</view>
+  </block>
+
+  <view wx:if="{{ showSubtitle }}" class="van-calendar__header-subtitle" bind:tap="onClickSubtitle">
+    {{ subtitle }}
+  </view>
+
+  <view class="van-calendar__weekdays">
+    <view wx:for="{{ weekdays }}" wx:key="index" class="van-calendar__weekday">
+      {{ item }}
+    </view>
+  </view>
+</view>

+ 1 - 0
miniprogram/miniprogram_npm/@vant/weapp/calendar/components/header/index.wxss

@@ -0,0 +1 @@
+@import '../../../common/index.wxss';.van-calendar__header{box-shadow:var(--calendar-header-box-shadow,0 2px 10px hsla(220,1%,50%,.16));flex-shrink:0}.van-calendar__header-subtitle,.van-calendar__header-title{font-weight:var(--font-weight-bold,500);height:var(--calendar-header-title-height,44px);line-height:var(--calendar-header-title-height,44px);text-align:center}.van-calendar__header-title+.van-calendar__header-title,.van-calendar__header-title:empty{display:none}.van-calendar__header-title:empty+.van-calendar__header-title{display:block!important}.van-calendar__weekdays{display:flex}.van-calendar__weekday{flex:1;font-size:var(--calendar-weekdays-font-size,12px);line-height:var(--calendar-weekdays-height,30px);text-align:center}

+ 6 - 0
miniprogram/miniprogram_npm/@vant/weapp/calendar/components/month/index.d.ts

@@ -0,0 +1,6 @@
+export interface Day {
+    date: Date;
+    type: string;
+    text: number;
+    bottomInfo?: string;
+}

+ 158 - 0
miniprogram/miniprogram_npm/@vant/weapp/calendar/components/month/index.js

@@ -0,0 +1,158 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var component_1 = require("../../../common/component");
+var utils_1 = require("../../utils");
+(0, component_1.VantComponent)({
+    props: {
+        date: {
+            type: null,
+            observer: 'setDays',
+        },
+        type: {
+            type: String,
+            observer: 'setDays',
+        },
+        color: String,
+        minDate: {
+            type: null,
+            observer: 'setDays',
+        },
+        maxDate: {
+            type: null,
+            observer: 'setDays',
+        },
+        showMark: Boolean,
+        rowHeight: null,
+        formatter: {
+            type: null,
+            observer: 'setDays',
+        },
+        currentDate: {
+            type: null,
+            observer: 'setDays',
+        },
+        firstDayOfWeek: {
+            type: Number,
+            observer: 'setDays',
+        },
+        allowSameDay: Boolean,
+        showSubtitle: Boolean,
+        showMonthTitle: Boolean,
+    },
+    data: {
+        visible: true,
+        days: [],
+    },
+    methods: {
+        onClick: function (event) {
+            var index = event.currentTarget.dataset.index;
+            var item = this.data.days[index];
+            if (item.type !== 'disabled') {
+                this.$emit('click', item);
+            }
+        },
+        setDays: function () {
+            var days = [];
+            var startDate = new Date(this.data.date);
+            var year = startDate.getFullYear();
+            var month = startDate.getMonth();
+            var totalDay = (0, utils_1.getMonthEndDay)(startDate.getFullYear(), startDate.getMonth() + 1);
+            for (var day = 1; day <= totalDay; day++) {
+                var date = new Date(year, month, day);
+                var type = this.getDayType(date);
+                var config = {
+                    date: date,
+                    type: type,
+                    text: day,
+                    bottomInfo: this.getBottomInfo(type),
+                };
+                if (this.data.formatter) {
+                    config = this.data.formatter(config);
+                }
+                days.push(config);
+            }
+            this.setData({ days: days });
+        },
+        getMultipleDayType: function (day) {
+            var currentDate = this.data.currentDate;
+            if (!Array.isArray(currentDate)) {
+                return '';
+            }
+            var isSelected = function (date) {
+                return currentDate.some(function (item) { return (0, utils_1.compareDay)(item, date) === 0; });
+            };
+            if (isSelected(day)) {
+                var prevDay = (0, utils_1.getPrevDay)(day);
+                var nextDay = (0, utils_1.getNextDay)(day);
+                var prevSelected = isSelected(prevDay);
+                var nextSelected = isSelected(nextDay);
+                if (prevSelected && nextSelected) {
+                    return 'multiple-middle';
+                }
+                if (prevSelected) {
+                    return 'end';
+                }
+                return nextSelected ? 'start' : 'multiple-selected';
+            }
+            return '';
+        },
+        getRangeDayType: function (day) {
+            var _a = this.data, currentDate = _a.currentDate, allowSameDay = _a.allowSameDay;
+            if (!Array.isArray(currentDate)) {
+                return '';
+            }
+            var startDay = currentDate[0], endDay = currentDate[1];
+            if (!startDay) {
+                return '';
+            }
+            var compareToStart = (0, utils_1.compareDay)(day, startDay);
+            if (!endDay) {
+                return compareToStart === 0 ? 'start' : '';
+            }
+            var compareToEnd = (0, utils_1.compareDay)(day, endDay);
+            if (compareToStart === 0 && compareToEnd === 0 && allowSameDay) {
+                return 'start-end';
+            }
+            if (compareToStart === 0) {
+                return 'start';
+            }
+            if (compareToEnd === 0) {
+                return 'end';
+            }
+            if (compareToStart > 0 && compareToEnd < 0) {
+                return 'middle';
+            }
+            return '';
+        },
+        getDayType: function (day) {
+            var _a = this.data, type = _a.type, minDate = _a.minDate, maxDate = _a.maxDate, currentDate = _a.currentDate;
+            if ((0, utils_1.compareDay)(day, minDate) < 0 || (0, utils_1.compareDay)(day, maxDate) > 0) {
+                return 'disabled';
+            }
+            if (type === 'single') {
+                return (0, utils_1.compareDay)(day, currentDate) === 0 ? 'selected' : '';
+            }
+            if (type === 'multiple') {
+                return this.getMultipleDayType(day);
+            }
+            /* istanbul ignore else */
+            if (type === 'range') {
+                return this.getRangeDayType(day);
+            }
+            return '';
+        },
+        getBottomInfo: function (type) {
+            if (this.data.type === 'range') {
+                if (type === 'start') {
+                    return '开始';
+                }
+                if (type === 'end') {
+                    return '结束';
+                }
+                if (type === 'start-end') {
+                    return '开始/结束';
+                }
+            }
+        },
+    },
+});

+ 3 - 0
miniprogram/miniprogram_npm/@vant/weapp/calendar/components/month/index.json

@@ -0,0 +1,3 @@
+{
+  "component": true
+}

+ 39 - 0
miniprogram/miniprogram_npm/@vant/weapp/calendar/components/month/index.wxml

@@ -0,0 +1,39 @@
+<wxs src="./index.wxs" module="computed"></wxs>
+<wxs src="../../../wxs/utils.wxs" module="utils" />
+
+<view class="van-calendar__month" style="{{ computed.getMonthStyle(visible, date, rowHeight) }}">
+  <view wx:if="{{ showMonthTitle }}" class="van-calendar__month-title">
+    {{ computed.formatMonthTitle(date) }}
+  </view>
+
+  <view wx:if="{{ visible }}" class="van-calendar__days">
+    <view wx:if="{{ showMark }}" class="van-calendar__month-mark">
+      {{ computed.getMark(date) }}
+    </view>
+
+    <view
+      wx:for="{{ days }}"
+      wx:key="index"
+      style="{{ computed.getDayStyle(item.type, index, date, rowHeight, color, firstDayOfWeek) }}"
+      class="{{ utils.bem('calendar__day', [item.type]) }} {{ item.className }}"
+      data-index="{{ index }}"
+      bindtap="onClick"
+    >
+      <view wx:if="{{ item.type === 'selected' }}" class="van-calendar__selected-day" style="width: {{ rowHeight }}px; height: {{ rowHeight }}px; background: {{ color }}">
+        <view wx:if="{{ item.topInfo }}" class="van-calendar__top-info">{{ item.topInfo }}</view>
+        {{ item.text }}
+        <view wx:if="{{ item.bottomInfo }}" class="van-calendar__bottom-info">
+          {{ item.bottomInfo }}
+        </view>
+      </view>
+
+      <view wx:else>
+        <view wx:if="{{ item.topInfo }}" class="van-calendar__top-info">{{ item.topInfo }}</view>
+        {{ item.text }}
+        <view wx:if="{{ item.bottomInfo }}" class="van-calendar__bottom-info">
+          {{ item.bottomInfo }}
+        </view>
+      </view>
+    </view>
+  </view>
+</view>

+ 71 - 0
miniprogram/miniprogram_npm/@vant/weapp/calendar/components/month/index.wxs

@@ -0,0 +1,71 @@
+/* eslint-disable */
+var utils = require('../../utils.wxs');
+
+function getMark(date) {
+  return getDate(date).getMonth() + 1;
+}
+
+var ROW_HEIGHT = 64;
+
+function getDayStyle(type, index, date, rowHeight, color, firstDayOfWeek) {
+  var style = [];
+  var current = getDate(date).getDay() || 7;
+  var offset = current < firstDayOfWeek ? (7 - firstDayOfWeek + current) :
+               current === 7 && firstDayOfWeek === 0 ? 0 :
+               (current - firstDayOfWeek);
+
+  if (index === 0) {
+    style.push(['margin-left', (100 * offset) / 7 + '%']);
+  }
+
+  if (rowHeight !== ROW_HEIGHT) {
+    style.push(['height', rowHeight + 'px']);
+  }
+
+  if (color) {
+    if (
+      type === 'start' ||
+      type === 'end' ||
+      type === 'start-end' ||
+      type === 'multiple-selected' ||
+      type === 'multiple-middle'
+    ) {
+      style.push(['background', color]);
+    } else if (type === 'middle') {
+      style.push(['color', color]);
+    }
+  }
+
+  return style
+    .map(function(item) {
+      return item.join(':');
+    })
+    .join(';');
+}
+
+function formatMonthTitle(date) {
+  date = getDate(date);
+  return date.getFullYear() + '年' + (date.getMonth() + 1) + '月';
+}
+
+function getMonthStyle(visible, date, rowHeight) {
+  if (!visible) {
+    date = getDate(date);
+
+    var totalDay = utils.getMonthEndDay(
+      date.getFullYear(),
+      date.getMonth() + 1
+    );
+    var offset = getDate(date).getDay();
+    var padding = Math.ceil((totalDay + offset) / 7) * rowHeight;
+
+    return 'padding-bottom:' + padding + 'px';
+  }
+}
+
+module.exports = {
+  getMark: getMark,
+  getDayStyle: getDayStyle,
+  formatMonthTitle: formatMonthTitle,
+  getMonthStyle: getMonthStyle
+};

Разлика између датотеке није приказан због своје велике величине
+ 0 - 0
miniprogram/miniprogram_npm/@vant/weapp/calendar/components/month/index.wxss


+ 1 - 0
miniprogram/miniprogram_npm/@vant/weapp/calendar/index.d.ts

@@ -0,0 +1 @@
+export {};

+ 360 - 0
miniprogram/miniprogram_npm/@vant/weapp/calendar/index.js

@@ -0,0 +1,360 @@
+"use strict";
+var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
+    if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
+        if (ar || !(i in from)) {
+            if (!ar) ar = Array.prototype.slice.call(from, 0, i);
+            ar[i] = from[i];
+        }
+    }
+    return to.concat(ar || Array.prototype.slice.call(from));
+};
+var __importDefault = (this && this.__importDefault) || function (mod) {
+    return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+var component_1 = require("../common/component");
+var utils_1 = require("./utils");
+var toast_1 = __importDefault(require("../toast/toast"));
+var utils_2 = require("../common/utils");
+var initialMinDate = (0, utils_1.getToday)().getTime();
+var initialMaxDate = (function () {
+    var now = (0, utils_1.getToday)();
+    return new Date(now.getFullYear(), now.getMonth() + 6, now.getDate()).getTime();
+})();
+var getTime = function (date) {
+    return date instanceof Date ? date.getTime() : date;
+};
+(0, component_1.VantComponent)({
+    props: {
+        title: {
+            type: String,
+            value: '日期选择',
+        },
+        color: String,
+        show: {
+            type: Boolean,
+            observer: function (val) {
+                if (val) {
+                    this.initRect();
+                    this.scrollIntoView();
+                }
+            },
+        },
+        formatter: null,
+        confirmText: {
+            type: String,
+            value: '确定',
+        },
+        confirmDisabledText: {
+            type: String,
+            value: '确定',
+        },
+        rangePrompt: String,
+        showRangePrompt: {
+            type: Boolean,
+            value: true,
+        },
+        defaultDate: {
+            type: null,
+            observer: function (val) {
+                this.setData({ currentDate: val });
+                this.scrollIntoView();
+            },
+        },
+        allowSameDay: Boolean,
+        type: {
+            type: String,
+            value: 'single',
+            observer: 'reset',
+        },
+        minDate: {
+            type: Number,
+            value: initialMinDate,
+        },
+        maxDate: {
+            type: Number,
+            value: initialMaxDate,
+        },
+        position: {
+            type: String,
+            value: 'bottom',
+        },
+        rowHeight: {
+            type: null,
+            value: utils_1.ROW_HEIGHT,
+        },
+        round: {
+            type: Boolean,
+            value: true,
+        },
+        poppable: {
+            type: Boolean,
+            value: true,
+        },
+        showMark: {
+            type: Boolean,
+            value: true,
+        },
+        showTitle: {
+            type: Boolean,
+            value: true,
+        },
+        showConfirm: {
+            type: Boolean,
+            value: true,
+        },
+        showSubtitle: {
+            type: Boolean,
+            value: true,
+        },
+        safeAreaInsetBottom: {
+            type: Boolean,
+            value: true,
+        },
+        closeOnClickOverlay: {
+            type: Boolean,
+            value: true,
+        },
+        maxRange: {
+            type: null,
+            value: null,
+        },
+        firstDayOfWeek: {
+            type: Number,
+            value: 0,
+        },
+        readonly: Boolean,
+    },
+    data: {
+        subtitle: '',
+        currentDate: null,
+        scrollIntoView: '',
+    },
+    created: function () {
+        this.setData({
+            currentDate: this.getInitialDate(this.data.defaultDate),
+        });
+    },
+    mounted: function () {
+        if (this.data.show || !this.data.poppable) {
+            this.initRect();
+            this.scrollIntoView();
+        }
+    },
+    methods: {
+        reset: function () {
+            this.setData({ currentDate: this.getInitialDate() });
+            this.scrollIntoView();
+        },
+        initRect: function () {
+            var _this = this;
+            if (this.contentObserver != null) {
+                this.contentObserver.disconnect();
+            }
+            var contentObserver = this.createIntersectionObserver({
+                thresholds: [0, 0.1, 0.9, 1],
+                observeAll: true,
+            });
+            this.contentObserver = contentObserver;
+            contentObserver.relativeTo('.van-calendar__body');
+            contentObserver.observe('.month', function (res) {
+                if (res.boundingClientRect.top <= res.relativeRect.top) {
+                    // @ts-ignore
+                    _this.setData({ subtitle: (0, utils_1.formatMonthTitle)(res.dataset.date) });
+                }
+            });
+        },
+        limitDateRange: function (date, minDate, maxDate) {
+            if (minDate === void 0) { minDate = null; }
+            if (maxDate === void 0) { maxDate = null; }
+            minDate = minDate || this.data.minDate;
+            maxDate = maxDate || this.data.maxDate;
+            if ((0, utils_1.compareDay)(date, minDate) === -1) {
+                return minDate;
+            }
+            if ((0, utils_1.compareDay)(date, maxDate) === 1) {
+                return maxDate;
+            }
+            return date;
+        },
+        getInitialDate: function (defaultDate) {
+            var _this = this;
+            if (defaultDate === void 0) { defaultDate = null; }
+            var _a = this.data, type = _a.type, minDate = _a.minDate, maxDate = _a.maxDate;
+            var now = (0, utils_1.getToday)().getTime();
+            if (type === 'range') {
+                if (!Array.isArray(defaultDate)) {
+                    defaultDate = [];
+                }
+                var _b = defaultDate || [], startDay = _b[0], endDay = _b[1];
+                var start = this.limitDateRange(startDay || now, minDate, (0, utils_1.getPrevDay)(new Date(maxDate)).getTime());
+                var end = this.limitDateRange(endDay || now, (0, utils_1.getNextDay)(new Date(minDate)).getTime());
+                return [start, end];
+            }
+            if (type === 'multiple') {
+                if (Array.isArray(defaultDate)) {
+                    return defaultDate.map(function (date) { return _this.limitDateRange(date); });
+                }
+                return [this.limitDateRange(now)];
+            }
+            if (!defaultDate || Array.isArray(defaultDate)) {
+                defaultDate = now;
+            }
+            return this.limitDateRange(defaultDate);
+        },
+        scrollIntoView: function () {
+            var _this = this;
+            (0, utils_2.requestAnimationFrame)(function () {
+                var _a = _this.data, currentDate = _a.currentDate, type = _a.type, show = _a.show, poppable = _a.poppable, minDate = _a.minDate, maxDate = _a.maxDate;
+                // @ts-ignore
+                var targetDate = type === 'single' ? currentDate : currentDate[0];
+                var displayed = show || !poppable;
+                if (!targetDate || !displayed) {
+                    return;
+                }
+                var months = (0, utils_1.getMonths)(minDate, maxDate);
+                months.some(function (month, index) {
+                    if ((0, utils_1.compareMonth)(month, targetDate) === 0) {
+                        _this.setData({ scrollIntoView: "month".concat(index) });
+                        return true;
+                    }
+                    return false;
+                });
+            });
+        },
+        onOpen: function () {
+            this.$emit('open');
+        },
+        onOpened: function () {
+            this.$emit('opened');
+        },
+        onClose: function () {
+            this.$emit('close');
+        },
+        onClosed: function () {
+            this.$emit('closed');
+        },
+        onClickDay: function (event) {
+            if (this.data.readonly) {
+                return;
+            }
+            var date = event.detail.date;
+            var _a = this.data, type = _a.type, currentDate = _a.currentDate, allowSameDay = _a.allowSameDay;
+            if (type === 'range') {
+                // @ts-ignore
+                var startDay_1 = currentDate[0], endDay = currentDate[1];
+                if (startDay_1 && !endDay) {
+                    var compareToStart = (0, utils_1.compareDay)(date, startDay_1);
+                    if (compareToStart === 1) {
+                        var days_1 = this.selectComponent('.month').data.days;
+                        days_1.some(function (day, index) {
+                            var isDisabled = day.type === 'disabled' &&
+                                getTime(startDay_1) < getTime(day.date) &&
+                                getTime(day.date) < getTime(date);
+                            if (isDisabled) {
+                                (date = days_1[index - 1].date);
+                            }
+                            return isDisabled;
+                        });
+                        this.select([startDay_1, date], true);
+                    }
+                    else if (compareToStart === -1) {
+                        this.select([date, null]);
+                    }
+                    else if (allowSameDay) {
+                        this.select([date, date]);
+                    }
+                }
+                else {
+                    this.select([date, null]);
+                }
+            }
+            else if (type === 'multiple') {
+                var selectedIndex_1;
+                // @ts-ignore
+                var selected = currentDate.some(function (dateItem, index) {
+                    var equal = (0, utils_1.compareDay)(dateItem, date) === 0;
+                    if (equal) {
+                        selectedIndex_1 = index;
+                    }
+                    return equal;
+                });
+                if (selected) {
+                    // @ts-ignore
+                    var cancelDate = currentDate.splice(selectedIndex_1, 1);
+                    this.setData({ currentDate: currentDate });
+                    this.unselect(cancelDate);
+                }
+                else {
+                    // @ts-ignore
+                    this.select(__spreadArray(__spreadArray([], currentDate, true), [date], false));
+                }
+            }
+            else {
+                this.select(date, true);
+            }
+        },
+        unselect: function (dateArray) {
+            var date = dateArray[0];
+            if (date) {
+                this.$emit('unselect', (0, utils_1.copyDates)(date));
+            }
+        },
+        select: function (date, complete) {
+            if (complete && this.data.type === 'range') {
+                var valid = this.checkRange(date);
+                if (!valid) {
+                    // auto selected to max range if showConfirm
+                    if (this.data.showConfirm) {
+                        this.emit([
+                            date[0],
+                            (0, utils_1.getDayByOffset)(date[0], this.data.maxRange - 1),
+                        ]);
+                    }
+                    else {
+                        this.emit(date);
+                    }
+                    return;
+                }
+            }
+            this.emit(date);
+            if (complete && !this.data.showConfirm) {
+                this.onConfirm();
+            }
+        },
+        emit: function (date) {
+            this.setData({
+                currentDate: Array.isArray(date) ? date.map(getTime) : getTime(date),
+            });
+            this.$emit('select', (0, utils_1.copyDates)(date));
+        },
+        checkRange: function (date) {
+            var _a = this.data, maxRange = _a.maxRange, rangePrompt = _a.rangePrompt, showRangePrompt = _a.showRangePrompt;
+            if (maxRange && (0, utils_1.calcDateNum)(date) > maxRange) {
+                if (showRangePrompt) {
+                    (0, toast_1.default)({
+                        context: this,
+                        message: rangePrompt || "\u9009\u62E9\u5929\u6570\u4E0D\u80FD\u8D85\u8FC7 ".concat(maxRange, " \u5929"),
+                    });
+                }
+                this.$emit('over-range');
+                return false;
+            }
+            return true;
+        },
+        onConfirm: function () {
+            var _this = this;
+            if (this.data.type === 'range' &&
+                !this.checkRange(this.data.currentDate)) {
+                return;
+            }
+            wx.nextTick(function () {
+                // @ts-ignore
+                _this.$emit('confirm', (0, utils_1.copyDates)(_this.data.currentDate));
+            });
+        },
+        onClickSubtitle: function (event) {
+            this.$emit('click-subtitle', event);
+        },
+    },
+});

+ 10 - 0
miniprogram/miniprogram_npm/@vant/weapp/calendar/index.json

@@ -0,0 +1,10 @@
+{
+  "component": true,
+  "usingComponents": {
+    "header": "./components/header/index",
+    "month": "./components/month/index",
+    "van-button": "../button/index",
+    "van-popup": "../popup/index",
+    "van-toast": "../toast/index"
+  }
+}

+ 25 - 0
miniprogram/miniprogram_npm/@vant/weapp/calendar/index.wxml

@@ -0,0 +1,25 @@
+<wxs src="./index.wxs" module="computed" />
+<wxs src="../wxs/utils.wxs" module="utils" />
+
+<import src="./calendar.wxml" />
+
+<van-popup
+  wx:if="{{ poppable }}"
+  custom-class="van-calendar__popup--{{ position }}"
+  close-icon-class="van-calendar__close-icon"
+  show="{{ show }}"
+  round="{{ round }}"
+  position="{{ position }}"
+  closeable="{{ showTitle || showSubtitle }}"
+  close-on-click-overlay="{{ closeOnClickOverlay }}"
+  bind:enter="onOpen"
+  bind:close="onClose"
+  bind:after-enter="onOpened"
+  bind:after-leave="onClosed"
+>
+  <include src="./calendar.wxml" />
+</van-popup>
+
+<include wx:else src="./calendar.wxml" />
+
+<van-toast id="van-toast" />

+ 38 - 0
miniprogram/miniprogram_npm/@vant/weapp/calendar/index.wxs

@@ -0,0 +1,38 @@
+/* eslint-disable */
+var utils = require('./utils.wxs');
+
+function getMonths(minDate, maxDate) {
+  var months = [];
+  var cursor = getDate(minDate);
+
+  cursor.setDate(1);
+  cursor.setMinutes(cursor.getMinutes() - cursor.getTimezoneOffset());
+
+  do {
+    months.push(cursor.getTime());
+    cursor.setMonth(cursor.getMonth() + 1);
+  } while (utils.compareMonth(cursor, getDate(maxDate)) !== 1);
+
+  return months;
+}
+
+function getButtonDisabled(type, currentDate) {
+  if (currentDate == null) {
+    return true;
+  }
+
+  if (type === 'range') {
+    return !currentDate[0] || !currentDate[1];
+  }
+
+  if (type === 'multiple') {
+    return !currentDate.length;
+  }
+
+  return !currentDate;
+}
+
+module.exports = {
+  getMonths: getMonths,
+  getButtonDisabled: getButtonDisabled
+};

+ 1 - 0
miniprogram/miniprogram_npm/@vant/weapp/calendar/index.wxss

@@ -0,0 +1 @@
+@import '../common/index.wxss';.van-calendar{background-color:var(--calendar-background-color,#fff);display:flex;flex-direction:column;height:var(--calendar-height,100%)}.van-calendar__close-icon{top:11px}.van-calendar__popup--bottom,.van-calendar__popup--top{height:var(--calendar-popup-height,80%)}.van-calendar__popup--left,.van-calendar__popup--right{height:100%}.van-calendar__body{-webkit-overflow-scrolling:touch;flex:1;overflow:auto}.van-calendar__footer{flex-shrink:0;padding:0 var(--padding-md,16px)}.van-calendar__footer--safe-area-inset-bottom{padding-bottom:env(safe-area-inset-bottom)}.van-calendar__footer+.van-calendar__footer,.van-calendar__footer:empty{display:none}.van-calendar__footer:empty+.van-calendar__footer{display:block!important}.van-calendar__confirm{height:var(--calendar-confirm-button-height,36px)!important;line-height:var(--calendar-confirm-button-line-height,34px)!important;margin:var(--calendar-confirm-button-margin,7px 0)!important}

+ 12 - 0
miniprogram/miniprogram_npm/@vant/weapp/calendar/utils.d.ts

@@ -0,0 +1,12 @@
+export declare const ROW_HEIGHT = 64;
+export declare function formatMonthTitle(date: Date): string;
+export declare function compareMonth(date1: Date | number, date2: Date | number): 1 | -1 | 0;
+export declare function compareDay(day1: Date | number, day2: Date | number): 1 | -1 | 0;
+export declare function getDayByOffset(date: Date, offset: number): Date;
+export declare function getPrevDay(date: Date): Date;
+export declare function getNextDay(date: Date): Date;
+export declare function getToday(): Date;
+export declare function calcDateNum(date: [Date, Date]): number;
+export declare function copyDates(dates: Date | Date[]): Date | Date[];
+export declare function getMonthEndDay(year: number, month: number): number;
+export declare function getMonths(minDate: number, maxDate: number): number[];

+ 97 - 0
miniprogram/miniprogram_npm/@vant/weapp/calendar/utils.js

@@ -0,0 +1,97 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.getMonths = exports.getMonthEndDay = exports.copyDates = exports.calcDateNum = exports.getToday = exports.getNextDay = exports.getPrevDay = exports.getDayByOffset = exports.compareDay = exports.compareMonth = exports.formatMonthTitle = exports.ROW_HEIGHT = void 0;
+exports.ROW_HEIGHT = 64;
+function formatMonthTitle(date) {
+    if (!(date instanceof Date)) {
+        date = new Date(date);
+    }
+    return "".concat(date.getFullYear(), "\u5E74").concat(date.getMonth() + 1, "\u6708");
+}
+exports.formatMonthTitle = formatMonthTitle;
+function compareMonth(date1, date2) {
+    if (!(date1 instanceof Date)) {
+        date1 = new Date(date1);
+    }
+    if (!(date2 instanceof Date)) {
+        date2 = new Date(date2);
+    }
+    var year1 = date1.getFullYear();
+    var year2 = date2.getFullYear();
+    var month1 = date1.getMonth();
+    var month2 = date2.getMonth();
+    if (year1 === year2) {
+        return month1 === month2 ? 0 : month1 > month2 ? 1 : -1;
+    }
+    return year1 > year2 ? 1 : -1;
+}
+exports.compareMonth = compareMonth;
+function compareDay(day1, day2) {
+    if (!(day1 instanceof Date)) {
+        day1 = new Date(day1);
+    }
+    if (!(day2 instanceof Date)) {
+        day2 = new Date(day2);
+    }
+    var compareMonthResult = compareMonth(day1, day2);
+    if (compareMonthResult === 0) {
+        var date1 = day1.getDate();
+        var date2 = day2.getDate();
+        return date1 === date2 ? 0 : date1 > date2 ? 1 : -1;
+    }
+    return compareMonthResult;
+}
+exports.compareDay = compareDay;
+function getDayByOffset(date, offset) {
+    date = new Date(date);
+    date.setDate(date.getDate() + offset);
+    return date;
+}
+exports.getDayByOffset = getDayByOffset;
+function getPrevDay(date) {
+    return getDayByOffset(date, -1);
+}
+exports.getPrevDay = getPrevDay;
+function getNextDay(date) {
+    return getDayByOffset(date, 1);
+}
+exports.getNextDay = getNextDay;
+function getToday() {
+    var today = new Date();
+    today.setHours(0, 0, 0, 0);
+    return today;
+}
+exports.getToday = getToday;
+function calcDateNum(date) {
+    var day1 = new Date(date[0]).getTime();
+    var day2 = new Date(date[1]).getTime();
+    return (day2 - day1) / (1000 * 60 * 60 * 24) + 1;
+}
+exports.calcDateNum = calcDateNum;
+function copyDates(dates) {
+    if (Array.isArray(dates)) {
+        return dates.map(function (date) {
+            if (date === null) {
+                return date;
+            }
+            return new Date(date);
+        });
+    }
+    return new Date(dates);
+}
+exports.copyDates = copyDates;
+function getMonthEndDay(year, month) {
+    return 32 - new Date(year, month - 1, 32).getDate();
+}
+exports.getMonthEndDay = getMonthEndDay;
+function getMonths(minDate, maxDate) {
+    var months = [];
+    var cursor = new Date(minDate);
+    cursor.setDate(1);
+    do {
+        months.push(cursor.getTime());
+        cursor.setMonth(cursor.getMonth() + 1);
+    } while (compareMonth(cursor, maxDate) !== 1);
+    return months;
+}
+exports.getMonths = getMonths;

+ 25 - 0
miniprogram/miniprogram_npm/@vant/weapp/calendar/utils.wxs

@@ -0,0 +1,25 @@
+/* eslint-disable */
+function getMonthEndDay(year, month) {
+  return 32 -  getDate(year, month - 1, 32).getDate();
+}
+
+function compareMonth(date1, date2) {
+  date1 = getDate(date1);
+  date2 = getDate(date2);
+
+  var year1 = date1.getFullYear();
+  var year2 = date2.getFullYear();
+  var month1 = date1.getMonth();
+  var month2 = date2.getMonth();
+
+  if (year1 === year2) {
+    return month1 === month2 ? 0 : month1 > month2 ? 1 : -1;
+  }
+
+  return year1 > year2 ? 1 : -1;
+}
+
+module.exports = {
+  getMonthEndDay: getMonthEndDay,
+  compareMonth: compareMonth
+};

+ 1 - 0
miniprogram/miniprogram_npm/@vant/weapp/card/index.d.ts

@@ -0,0 +1 @@
+export {};

+ 51 - 0
miniprogram/miniprogram_npm/@vant/weapp/card/index.js

@@ -0,0 +1,51 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var link_1 = require("../mixins/link");
+var component_1 = require("../common/component");
+(0, component_1.VantComponent)({
+    classes: [
+        'num-class',
+        'desc-class',
+        'thumb-class',
+        'title-class',
+        'price-class',
+        'origin-price-class',
+    ],
+    mixins: [link_1.link],
+    props: {
+        tag: String,
+        num: String,
+        desc: String,
+        thumb: String,
+        title: String,
+        price: {
+            type: String,
+            observer: 'updatePrice',
+        },
+        centered: Boolean,
+        lazyLoad: Boolean,
+        thumbLink: String,
+        originPrice: String,
+        thumbMode: {
+            type: String,
+            value: 'aspectFit',
+        },
+        currency: {
+            type: String,
+            value: '¥',
+        },
+    },
+    methods: {
+        updatePrice: function () {
+            var price = this.data.price;
+            var priceArr = price.toString().split('.');
+            this.setData({
+                integerStr: priceArr[0],
+                decimalStr: priceArr[1] ? ".".concat(priceArr[1]) : '',
+            });
+        },
+        onClickThumb: function () {
+            this.jumpLink('thumbLink');
+        },
+    },
+});

+ 6 - 0
miniprogram/miniprogram_npm/@vant/weapp/card/index.json

@@ -0,0 +1,6 @@
+{
+  "component": true,
+  "usingComponents": {
+    "van-tag": "../tag/index"
+  }
+}

+ 56 - 0
miniprogram/miniprogram_npm/@vant/weapp/card/index.wxml

@@ -0,0 +1,56 @@
+<wxs src="../wxs/utils.wxs" module="utils" />
+
+<view class="custom-class van-card">
+  <view class="{{ utils.bem('card__header', { center: centered }) }}">
+    <view class="van-card__thumb" bind:tap="onClickThumb">
+      <image
+        wx:if="{{ thumb }}"
+        src="{{ thumb }}"
+        mode="{{ thumbMode }}"
+        lazy-load="{{ lazyLoad }}"
+        class="van-card__img thumb-class"
+      />
+      <slot wx:else name="thumb" />
+      <van-tag
+        wx:if="{{ tag }}"
+        mark
+        type="danger"
+        custom-class="van-card__tag"
+      >
+        {{ tag }}
+      </van-tag>
+      <slot wx:else name="tag" />
+    </view>
+
+    <view class="van-card__content {{ utils.bem('card__content', { center: centered }) }}">
+      <view>
+        <view wx:if="{{ title }}" class="van-card__title title-class">{{ title }}</view>
+        <slot wx:else name="title" />
+
+        <view wx:if="{{ desc }}" class="van-card__desc desc-class">{{ desc }}</view>
+        <slot wx:else name="desc" />
+
+        <slot name="tags" />
+      </view>
+
+      <view class="van-card__bottom">
+        <slot name="price-top" />
+        <view wx:if="{{ price || price === 0 }}" class="van-card__price price-class">
+          <text>{{ currency }}</text>
+          <text class="van-card__price-integer">{{ integerStr }}</text>
+          <text class="van-card__price-decimal">{{ decimalStr }}</text>
+        </view>
+        <slot wx:else name="price" />
+        <view wx:if="{{ originPrice || originPrice === 0 }}" class="van-card__origin-price origin-price-class">{{ currency }} {{ originPrice }}</view>
+        <slot wx:else name="origin-price" />
+        <view wx:if="{{ num }}" class="van-card__num num-class">x {{ num }}</view>
+        <slot wx:else  name="num" />
+        <slot name="bottom" />
+      </view>
+    </view>
+  </view>
+
+  <view class="van-card__footer">
+    <slot name="footer" />
+  </view>
+</view>

+ 1 - 0
miniprogram/miniprogram_npm/@vant/weapp/card/index.wxss

@@ -0,0 +1 @@
+@import '../common/index.wxss';.van-card{background-color:var(--card-background-color,#fafafa);box-sizing:border-box;color:var(--card-text-color,#323233);font-size:var(--card-font-size,12px);padding:var(--card-padding,8px 16px);position:relative}.van-card__header{display:flex}.van-card__header--center{align-items:center;justify-content:center}.van-card__thumb{flex:none;height:var(--card-thumb-size,88px);margin-right:var(--padding-xs,8px);position:relative;width:var(--card-thumb-size,88px)}.van-card__thumb:empty{display:none}.van-card__img{border-radius:8px;height:100%;width:100%}.van-card__content{display:flex;flex:1;flex-direction:column;justify-content:space-between;min-height:var(--card-thumb-size,88px);min-width:0;position:relative}.van-card__content--center{justify-content:center}.van-card__desc,.van-card__title{word-wrap:break-word}.van-card__title{font-weight:700;line-height:var(--card-title-line-height,16px)}.van-card__desc{color:var(--card-desc-color,#646566);line-height:var(--card-desc-line-height,20px)}.van-card__bottom{line-height:20px}.van-card__price{color:var(--card-price-color,#ee0a24);display:inline-block;font-size:var(--card-price-font-size,12px);font-weight:700}.van-card__price-integer{font-size:var(--card-price-integer-font-size,16px)}.van-card__price-decimal,.van-card__price-integer{font-family:var(--card-price-font-family,Avenir-Heavy,PingFang SC,Helvetica Neue,Arial,sans-serif)}.van-card__origin-price{color:var(--card-origin-price-color,#646566);display:inline-block;font-size:var(--card-origin-price-font-size,10px);margin-left:5px;text-decoration:line-through}.van-card__num{float:right}.van-card__tag{left:0;position:absolute!important;top:2px}.van-card__footer{flex:none;text-align:right;width:100%}

+ 1 - 0
miniprogram/miniprogram_npm/@vant/weapp/cell-group/index.d.ts

@@ -0,0 +1 @@
+export {};

+ 13 - 0
miniprogram/miniprogram_npm/@vant/weapp/cell-group/index.js

@@ -0,0 +1,13 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var component_1 = require("../common/component");
+(0, component_1.VantComponent)({
+    props: {
+        title: String,
+        border: {
+            type: Boolean,
+            value: true,
+        },
+        inset: Boolean,
+    },
+});

+ 3 - 0
miniprogram/miniprogram_npm/@vant/weapp/cell-group/index.json

@@ -0,0 +1,3 @@
+{
+  "component": true
+}

+ 11 - 0
miniprogram/miniprogram_npm/@vant/weapp/cell-group/index.wxml

@@ -0,0 +1,11 @@
+<wxs src="../wxs/utils.wxs" module="utils" />
+
+<view
+  wx:if="{{ title }}"
+  class="{{ utils.bem('cell-group__title', { inset }) }}"
+>
+  {{ title }}
+</view>
+<view class="custom-class {{ utils.bem('cell-group', { inset }) }} {{ border ? 'van-hairline--top-bottom' : '' }}">
+  <slot />
+</view>

+ 1 - 0
miniprogram/miniprogram_npm/@vant/weapp/cell-group/index.wxss

@@ -0,0 +1 @@
+@import '../common/index.wxss';.van-cell-group--inset{border-radius:var(--cell-group-inset-border-radius,8px);margin:var(--cell-group-inset-padding,0 16px);overflow:hidden}.van-cell-group__title{color:var(--cell-group-title-color,#969799);font-size:var(--cell-group-title-font-size,14px);line-height:var(--cell-group-title-line-height,16px);padding:var(--cell-group-title-padding,16px 16px 8px)}.van-cell-group__title--inset{padding:var(--cell-group-inset-title-padding,16px 16px 8px 32px)}

+ 1 - 0
miniprogram/miniprogram_npm/@vant/weapp/cell/index.d.ts

@@ -0,0 +1 @@
+export {};

+ 40 - 0
miniprogram/miniprogram_npm/@vant/weapp/cell/index.js

@@ -0,0 +1,40 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var link_1 = require("../mixins/link");
+var component_1 = require("../common/component");
+(0, component_1.VantComponent)({
+    classes: [
+        'title-class',
+        'label-class',
+        'value-class',
+        'right-icon-class',
+        'hover-class',
+    ],
+    mixins: [link_1.link],
+    props: {
+        title: null,
+        value: null,
+        icon: String,
+        size: String,
+        label: String,
+        center: Boolean,
+        isLink: Boolean,
+        required: Boolean,
+        clickable: Boolean,
+        titleWidth: String,
+        customStyle: String,
+        arrowDirection: String,
+        useLabelSlot: Boolean,
+        border: {
+            type: Boolean,
+            value: true,
+        },
+        titleStyle: String,
+    },
+    methods: {
+        onClick: function (event) {
+            this.$emit('click', event.detail);
+            this.jumpLink();
+        },
+    },
+});

+ 6 - 0
miniprogram/miniprogram_npm/@vant/weapp/cell/index.json

@@ -0,0 +1,6 @@
+{
+  "component": true,
+  "usingComponents": {
+    "van-icon": "../icon/index"
+  }
+}

+ 47 - 0
miniprogram/miniprogram_npm/@vant/weapp/cell/index.wxml

@@ -0,0 +1,47 @@
+<wxs src="../wxs/utils.wxs" module="utils" />
+<wxs src="./index.wxs" module="computed" />
+
+<view
+  class="custom-class {{ utils.bem('cell', [size, { center, required, borderless: !border, clickable: isLink || clickable }]) }}"
+  hover-class="van-cell--hover hover-class"
+  hover-stay-time="70"
+  style="{{ customStyle }}"
+  bind:tap="onClick"
+>
+  <van-icon
+    wx:if="{{ icon }}"
+    name="{{ icon }}"
+    class="van-cell__left-icon-wrap"
+    custom-class="van-cell__left-icon"
+  />
+  <slot wx:else name="icon" />
+
+  <view
+    style="{{ computed.titleStyle({ titleWidth, titleStyle }) }}"
+    class="van-cell__title title-class"
+  >
+
+    <block wx:if="{{ title }}">{{ title }}</block>
+    <slot wx:else name="title" />
+
+    <view wx:if="{{ label || useLabelSlot }}" class="van-cell__label label-class">
+      <slot wx:if="{{ useLabelSlot }}" name="label" />
+      <block wx:elif="{{ label }}">{{ label }}</block>
+    </view>
+  </view>
+
+  <view class="van-cell__value value-class">
+    <block wx:if="{{ value || value === 0 }}">{{ value }}</block>
+    <slot wx:else />
+  </view>
+
+  <van-icon
+    wx:if="{{ isLink }}"
+    name="{{ arrowDirection ? 'arrow' + '-' + arrowDirection : 'arrow' }}"
+    class="van-cell__right-icon-wrap right-icon-class"
+    custom-class="van-cell__right-icon"
+  />
+  <slot wx:else name="right-icon" />
+
+  <slot name="extra" />
+</view>

+ 17 - 0
miniprogram/miniprogram_npm/@vant/weapp/cell/index.wxs

@@ -0,0 +1,17 @@
+/* eslint-disable */
+var style = require('../wxs/style.wxs');
+var addUnit = require('../wxs/add-unit.wxs');
+
+function titleStyle(data) {
+  return style([
+    {
+      'max-width': addUnit(data.titleWidth),
+      'min-width': addUnit(data.titleWidth),
+    },
+    data.titleStyle,
+  ]);
+}
+
+module.exports = {
+  titleStyle: titleStyle,
+};

Разлика између датотеке није приказан због своје велике величине
+ 0 - 0
miniprogram/miniprogram_npm/@vant/weapp/cell/index.wxss


+ 1 - 0
miniprogram/miniprogram_npm/@vant/weapp/checkbox-group/index.d.ts

@@ -0,0 +1 @@
+export {};

+ 39 - 0
miniprogram/miniprogram_npm/@vant/weapp/checkbox-group/index.js

@@ -0,0 +1,39 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var relation_1 = require("../common/relation");
+var component_1 = require("../common/component");
+(0, component_1.VantComponent)({
+    field: true,
+    relation: (0, relation_1.useChildren)('checkbox', function (target) {
+        this.updateChild(target);
+    }),
+    props: {
+        max: Number,
+        value: {
+            type: Array,
+            observer: 'updateChildren',
+        },
+        disabled: {
+            type: Boolean,
+            observer: 'updateChildren',
+        },
+        direction: {
+            type: String,
+            value: 'vertical',
+        },
+    },
+    methods: {
+        updateChildren: function () {
+            var _this = this;
+            this.children.forEach(function (child) { return _this.updateChild(child); });
+        },
+        updateChild: function (child) {
+            var _a = this.data, value = _a.value, disabled = _a.disabled, direction = _a.direction;
+            child.setData({
+                value: value.indexOf(child.data.name) !== -1,
+                parentDisabled: disabled,
+                direction: direction,
+            });
+        },
+    },
+});

+ 3 - 0
miniprogram/miniprogram_npm/@vant/weapp/checkbox-group/index.json

@@ -0,0 +1,3 @@
+{
+  "component": true
+}

+ 5 - 0
miniprogram/miniprogram_npm/@vant/weapp/checkbox-group/index.wxml

@@ -0,0 +1,5 @@
+<wxs src="../wxs/utils.wxs" module="utils" />
+
+<view class="{{ utils.bem('checkbox-group', [{ horizontal: direction === 'horizontal' }]) }}">
+  <slot />
+</view>

+ 1 - 0
miniprogram/miniprogram_npm/@vant/weapp/checkbox-group/index.wxss

@@ -0,0 +1 @@
+@import '../common/index.wxss';.van-checkbox-group--horizontal{display:flex;flex-wrap:wrap}

+ 1 - 0
miniprogram/miniprogram_npm/@vant/weapp/checkbox/index.d.ts

@@ -0,0 +1 @@
+export {};

+ 79 - 0
miniprogram/miniprogram_npm/@vant/weapp/checkbox/index.js

@@ -0,0 +1,79 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var relation_1 = require("../common/relation");
+var component_1 = require("../common/component");
+function emit(target, value) {
+    target.$emit('input', value);
+    target.$emit('change', value);
+}
+(0, component_1.VantComponent)({
+    field: true,
+    relation: (0, relation_1.useParent)('checkbox-group'),
+    classes: ['icon-class', 'label-class'],
+    props: {
+        value: Boolean,
+        disabled: Boolean,
+        useIconSlot: Boolean,
+        checkedColor: String,
+        labelPosition: {
+            type: String,
+            value: 'right',
+        },
+        labelDisabled: Boolean,
+        shape: {
+            type: String,
+            value: 'round',
+        },
+        iconSize: {
+            type: null,
+            value: 20,
+        },
+    },
+    data: {
+        parentDisabled: false,
+        direction: 'vertical',
+    },
+    methods: {
+        emitChange: function (value) {
+            if (this.parent) {
+                this.setParentValue(this.parent, value);
+            }
+            else {
+                emit(this, value);
+            }
+        },
+        toggle: function () {
+            var _a = this.data, parentDisabled = _a.parentDisabled, disabled = _a.disabled, value = _a.value;
+            if (!disabled && !parentDisabled) {
+                this.emitChange(!value);
+            }
+        },
+        onClickLabel: function () {
+            var _a = this.data, labelDisabled = _a.labelDisabled, parentDisabled = _a.parentDisabled, disabled = _a.disabled, value = _a.value;
+            if (!disabled && !labelDisabled && !parentDisabled) {
+                this.emitChange(!value);
+            }
+        },
+        setParentValue: function (parent, value) {
+            var parentValue = parent.data.value.slice();
+            var name = this.data.name;
+            var max = parent.data.max;
+            if (value) {
+                if (max && parentValue.length >= max) {
+                    return;
+                }
+                if (parentValue.indexOf(name) === -1) {
+                    parentValue.push(name);
+                    emit(parent, parentValue);
+                }
+            }
+            else {
+                var index = parentValue.indexOf(name);
+                if (index !== -1) {
+                    parentValue.splice(index, 1);
+                    emit(parent, parentValue);
+                }
+            }
+        },
+    },
+});

+ 6 - 0
miniprogram/miniprogram_npm/@vant/weapp/checkbox/index.json

@@ -0,0 +1,6 @@
+{
+  "component": true,
+  "usingComponents": {
+    "van-icon": "../icon/index"
+  }
+}

+ 31 - 0
miniprogram/miniprogram_npm/@vant/weapp/checkbox/index.wxml

@@ -0,0 +1,31 @@
+<wxs src="../wxs/utils.wxs" module="utils" />
+<wxs src="./index.wxs" module="computed" />
+
+<view class="{{ utils.bem('checkbox', [{ horizontal: direction === 'horizontal' }]) }} custom-class">
+  <view
+    wx:if="{{ labelPosition === 'left' }}"
+    class="label-class {{ utils.bem('checkbox__label', [labelPosition, { disabled: disabled || parentDisabled }]) }}"
+    bindtap="onClickLabel"
+  >
+    <slot />
+  </view>
+  <view class="van-checkbox__icon-wrap" bindtap="toggle">
+    <slot wx:if="{{ useIconSlot }}" name="icon" />
+    <van-icon
+      wx:else
+      name="success"
+      size="0.8em"
+      class="{{ utils.bem('checkbox__icon', [shape, { disabled: disabled || parentDisabled, checked: value }]) }}"
+      style="{{ computed.iconStyle(checkedColor, value, disabled, parentDisabled, iconSize) }}"
+      custom-class="icon-class"
+      custom-style="line-height: 1.25em;"
+    />
+  </view>
+  <view
+    wx:if="{{ labelPosition === 'right' }}"
+    class="label-class {{ utils.bem('checkbox__label', [labelPosition, { disabled: disabled || parentDisabled }]) }}"
+    bindtap="onClickLabel"
+  >
+    <slot />
+  </view>
+</view>

+ 20 - 0
miniprogram/miniprogram_npm/@vant/weapp/checkbox/index.wxs

@@ -0,0 +1,20 @@
+/* eslint-disable */
+var style = require('../wxs/style.wxs');
+var addUnit = require('../wxs/add-unit.wxs');
+
+function iconStyle(checkedColor, value, disabled, parentDisabled, iconSize) {
+  var styles = {
+    'font-size': addUnit(iconSize),
+  };
+
+  if (checkedColor && value && !disabled && !parentDisabled) {
+    styles['border-color'] = checkedColor;
+    styles['background-color'] = checkedColor;
+  }
+
+  return style(styles);
+}
+
+module.exports = {
+  iconStyle: iconStyle,
+};

+ 1 - 0
miniprogram/miniprogram_npm/@vant/weapp/checkbox/index.wxss

@@ -0,0 +1 @@
+@import '../common/index.wxss';.van-checkbox{align-items:center;display:flex;overflow:hidden;-webkit-user-select:none;user-select:none}.van-checkbox--horizontal{margin-right:12px}.van-checkbox__icon-wrap,.van-checkbox__label{line-height:var(--checkbox-size,20px)}.van-checkbox__icon-wrap{flex:none}.van-checkbox__icon{align-items:center;border:1px solid var(--checkbox-border-color,#c8c9cc);box-sizing:border-box;color:transparent;display:flex;font-size:var(--checkbox-size,20px);height:1em;justify-content:center;text-align:center;transition-duration:var(--checkbox-transition-duration,.2s);transition-property:color,border-color,background-color;width:1em}.van-checkbox__icon--round{border-radius:100%}.van-checkbox__icon--checked{background-color:var(--checkbox-checked-icon-color,#1989fa);border-color:var(--checkbox-checked-icon-color,#1989fa);color:#fff}.van-checkbox__icon--disabled{background-color:var(--checkbox-disabled-background-color,#ebedf0);border-color:var(--checkbox-disabled-icon-color,#c8c9cc)}.van-checkbox__icon--disabled.van-checkbox__icon--checked{color:var(--checkbox-disabled-icon-color,#c8c9cc)}.van-checkbox__label{word-wrap:break-word;color:var(--checkbox-label-color,#323233);padding-left:var(--checkbox-label-margin,10px)}.van-checkbox__label--left{float:left;margin:0 var(--checkbox-label-margin,10px) 0 0}.van-checkbox__label--disabled{color:var(--checkbox-disabled-label-color,#c8c9cc)}.van-checkbox__label:empty{margin:0}

+ 4 - 0
miniprogram/miniprogram_npm/@vant/weapp/circle/canvas.d.ts

@@ -0,0 +1,4 @@
+/// <reference types="miniprogram-api-typings" />
+declare type CanvasContext = WechatMiniprogram.CanvasContext;
+export declare function adaptor(ctx: CanvasContext & Record<string, unknown>): CanvasContext;
+export {};

+ 47 - 0
miniprogram/miniprogram_npm/@vant/weapp/circle/canvas.js

@@ -0,0 +1,47 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.adaptor = void 0;
+function adaptor(ctx) {
+    // @ts-ignore
+    return Object.assign(ctx, {
+        setStrokeStyle: function (val) {
+            ctx.strokeStyle = val;
+        },
+        setLineWidth: function (val) {
+            ctx.lineWidth = val;
+        },
+        setLineCap: function (val) {
+            ctx.lineCap = val;
+        },
+        setFillStyle: function (val) {
+            ctx.fillStyle = val;
+        },
+        setFontSize: function (val) {
+            ctx.font = String(val);
+        },
+        setGlobalAlpha: function (val) {
+            ctx.globalAlpha = val;
+        },
+        setLineJoin: function (val) {
+            ctx.lineJoin = val;
+        },
+        setTextAlign: function (val) {
+            ctx.textAlign = val;
+        },
+        setMiterLimit: function (val) {
+            ctx.miterLimit = val;
+        },
+        setShadow: function (offsetX, offsetY, blur, color) {
+            ctx.shadowOffsetX = offsetX;
+            ctx.shadowOffsetY = offsetY;
+            ctx.shadowBlur = blur;
+            ctx.shadowColor = color;
+        },
+        setTextBaseline: function (val) {
+            ctx.textBaseline = val;
+        },
+        createCircularGradient: function () { },
+        draw: function () { },
+    });
+}
+exports.adaptor = adaptor;

+ 1 - 0
miniprogram/miniprogram_npm/@vant/weapp/circle/index.d.ts

@@ -0,0 +1 @@
+export {};

+ 203 - 0
miniprogram/miniprogram_npm/@vant/weapp/circle/index.js

@@ -0,0 +1,203 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var color_1 = require("../common/color");
+var component_1 = require("../common/component");
+var utils_1 = require("../common/utils");
+var validator_1 = require("../common/validator");
+var version_1 = require("../common/version");
+var canvas_1 = require("./canvas");
+function format(rate) {
+    return Math.min(Math.max(rate, 0), 100);
+}
+var PERIMETER = 2 * Math.PI;
+var BEGIN_ANGLE = -Math.PI / 2;
+var STEP = 1;
+(0, component_1.VantComponent)({
+    props: {
+        text: String,
+        lineCap: {
+            type: String,
+            value: 'round',
+        },
+        value: {
+            type: Number,
+            value: 0,
+            observer: 'reRender',
+        },
+        speed: {
+            type: Number,
+            value: 50,
+        },
+        size: {
+            type: Number,
+            value: 100,
+            observer: function () {
+                this.drawCircle(this.currentValue);
+            },
+        },
+        fill: String,
+        layerColor: {
+            type: String,
+            value: color_1.WHITE,
+        },
+        color: {
+            type: null,
+            value: color_1.BLUE,
+            observer: function () {
+                var _this = this;
+                this.setHoverColor().then(function () {
+                    _this.drawCircle(_this.currentValue);
+                });
+            },
+        },
+        type: {
+            type: String,
+            value: '',
+        },
+        strokeWidth: {
+            type: Number,
+            value: 4,
+        },
+        clockwise: {
+            type: Boolean,
+            value: true,
+        },
+    },
+    data: {
+        hoverColor: color_1.BLUE,
+    },
+    methods: {
+        getContext: function () {
+            var _this = this;
+            var _a = this.data, type = _a.type, size = _a.size;
+            if (type === '' || !(0, version_1.canIUseCanvas2d)()) {
+                var ctx = wx.createCanvasContext('van-circle', this);
+                return Promise.resolve(ctx);
+            }
+            var dpr = (0, utils_1.getSystemInfoSync)().pixelRatio;
+            return new Promise(function (resolve) {
+                wx.createSelectorQuery()
+                    .in(_this)
+                    .select('#van-circle')
+                    .node()
+                    .exec(function (res) {
+                    var canvas = res[0].node;
+                    var ctx = canvas.getContext(type);
+                    if (!_this.inited) {
+                        _this.inited = true;
+                        canvas.width = size * dpr;
+                        canvas.height = size * dpr;
+                        ctx.scale(dpr, dpr);
+                    }
+                    resolve((0, canvas_1.adaptor)(ctx));
+                });
+            });
+        },
+        setHoverColor: function () {
+            var _this = this;
+            var _a = this.data, color = _a.color, size = _a.size;
+            if ((0, validator_1.isObj)(color)) {
+                return this.getContext().then(function (context) {
+                    var LinearColor = context.createLinearGradient(size, 0, 0, 0);
+                    Object.keys(color)
+                        .sort(function (a, b) { return parseFloat(a) - parseFloat(b); })
+                        .map(function (key) {
+                        return LinearColor.addColorStop(parseFloat(key) / 100, color[key]);
+                    });
+                    _this.hoverColor = LinearColor;
+                });
+            }
+            this.hoverColor = color;
+            return Promise.resolve();
+        },
+        presetCanvas: function (context, strokeStyle, beginAngle, endAngle, fill) {
+            var _a = this.data, strokeWidth = _a.strokeWidth, lineCap = _a.lineCap, clockwise = _a.clockwise, size = _a.size;
+            var position = size / 2;
+            var radius = position - strokeWidth / 2;
+            context.setStrokeStyle(strokeStyle);
+            context.setLineWidth(strokeWidth);
+            context.setLineCap(lineCap);
+            context.beginPath();
+            context.arc(position, position, radius, beginAngle, endAngle, !clockwise);
+            context.stroke();
+            if (fill) {
+                context.setFillStyle(fill);
+                context.fill();
+            }
+        },
+        renderLayerCircle: function (context) {
+            var _a = this.data, layerColor = _a.layerColor, fill = _a.fill;
+            this.presetCanvas(context, layerColor, 0, PERIMETER, fill);
+        },
+        renderHoverCircle: function (context, formatValue) {
+            var clockwise = this.data.clockwise;
+            // 结束角度
+            var progress = PERIMETER * (formatValue / 100);
+            var endAngle = clockwise
+                ? BEGIN_ANGLE + progress
+                : 3 * Math.PI - (BEGIN_ANGLE + progress);
+            this.presetCanvas(context, this.hoverColor, BEGIN_ANGLE, endAngle);
+        },
+        drawCircle: function (currentValue) {
+            var _this = this;
+            var size = this.data.size;
+            this.getContext().then(function (context) {
+                context.clearRect(0, 0, size, size);
+                _this.renderLayerCircle(context);
+                var formatValue = format(currentValue);
+                if (formatValue !== 0) {
+                    _this.renderHoverCircle(context, formatValue);
+                }
+                context.draw();
+            });
+        },
+        reRender: function () {
+            var _this = this;
+            // tofector 动画暂时没有想到好的解决方案
+            var _a = this.data, value = _a.value, speed = _a.speed;
+            if (speed <= 0 || speed > 1000) {
+                this.drawCircle(value);
+                return;
+            }
+            this.clearMockInterval();
+            this.currentValue = this.currentValue || 0;
+            var run = function () {
+                _this.interval = setTimeout(function () {
+                    if (_this.currentValue !== value) {
+                        if (Math.abs(_this.currentValue - value) < STEP) {
+                            _this.currentValue = value;
+                        }
+                        else if (_this.currentValue < value) {
+                            _this.currentValue += STEP;
+                        }
+                        else {
+                            _this.currentValue -= STEP;
+                        }
+                        _this.drawCircle(_this.currentValue);
+                        run();
+                    }
+                    else {
+                        _this.clearMockInterval();
+                    }
+                }, 1000 / speed);
+            };
+            run();
+        },
+        clearMockInterval: function () {
+            if (this.interval) {
+                clearTimeout(this.interval);
+                this.interval = null;
+            }
+        },
+    },
+    mounted: function () {
+        var _this = this;
+        this.currentValue = this.data.value;
+        this.setHoverColor().then(function () {
+            _this.drawCircle(_this.currentValue);
+        });
+    },
+    destroyed: function () {
+        this.clearMockInterval();
+    },
+});

+ 3 - 0
miniprogram/miniprogram_npm/@vant/weapp/circle/index.json

@@ -0,0 +1,3 @@
+{
+  "component": true
+}

+ 9 - 0
miniprogram/miniprogram_npm/@vant/weapp/circle/index.wxml

@@ -0,0 +1,9 @@
+<wxs src="../wxs/utils.wxs" module="utils" />
+
+<view class="van-circle">
+  <canvas class="van-circle__canvas" type="{{ type }}" style="width: {{ utils.addUnit(size) }};height:{{ utils.addUnit(size) }}" id="van-circle" canvas-id="van-circle"></canvas>
+  <view wx:if="{{ !text }}" class="van-circle__text">
+    <slot></slot>
+  </view>
+  <cover-view wx:else class="van-circle__text">{{ text }}</cover-view>
+</view>

+ 1 - 0
miniprogram/miniprogram_npm/@vant/weapp/circle/index.wxss

@@ -0,0 +1 @@
+@import '../common/index.wxss';.van-circle{display:inline-block;position:relative;text-align:center}.van-circle__text{color:var(--circle-text-color,#323233);left:0;position:absolute;top:50%;transform:translateY(-50%);width:100%}

+ 1 - 0
miniprogram/miniprogram_npm/@vant/weapp/col/index.d.ts

@@ -0,0 +1 @@
+export {};

+ 11 - 0
miniprogram/miniprogram_npm/@vant/weapp/col/index.js

@@ -0,0 +1,11 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var relation_1 = require("../common/relation");
+var component_1 = require("../common/component");
+(0, component_1.VantComponent)({
+    relation: (0, relation_1.useParent)('row'),
+    props: {
+        span: Number,
+        offset: Number,
+    },
+});

+ 3 - 0
miniprogram/miniprogram_npm/@vant/weapp/col/index.json

@@ -0,0 +1,3 @@
+{
+  "component": true
+}

+ 9 - 0
miniprogram/miniprogram_npm/@vant/weapp/col/index.wxml

@@ -0,0 +1,9 @@
+<wxs src="../wxs/utils.wxs" module="utils" />
+<wxs src="./index.wxs" module="computed" />
+
+<view
+  class="custom-class {{ utils.bem('col', [span]) }} {{ offset ? 'van-col--offset-' + offset : '' }}"
+  style="{{ computed.rootStyle({ gutter }) }}"
+>
+  <slot />
+</view>

+ 18 - 0
miniprogram/miniprogram_npm/@vant/weapp/col/index.wxs

@@ -0,0 +1,18 @@
+/* eslint-disable */
+var style = require('../wxs/style.wxs');
+var addUnit = require('../wxs/add-unit.wxs');
+
+function rootStyle(data) {
+  if (!data.gutter) {
+    return '';
+  }
+
+  return style({
+    'padding-right': addUnit(data.gutter / 2),
+    'padding-left': addUnit(data.gutter / 2),
+  });
+}
+
+module.exports = {
+  rootStyle: rootStyle,
+};

+ 1 - 0
miniprogram/miniprogram_npm/@vant/weapp/col/index.wxss

@@ -0,0 +1 @@
+@import '../common/index.wxss';.van-col{box-sizing:border-box;float:left}.van-col--1{width:4.16666667%}.van-col--offset-1{margin-left:4.16666667%}.van-col--2{width:8.33333333%}.van-col--offset-2{margin-left:8.33333333%}.van-col--3{width:12.5%}.van-col--offset-3{margin-left:12.5%}.van-col--4{width:16.66666667%}.van-col--offset-4{margin-left:16.66666667%}.van-col--5{width:20.83333333%}.van-col--offset-5{margin-left:20.83333333%}.van-col--6{width:25%}.van-col--offset-6{margin-left:25%}.van-col--7{width:29.16666667%}.van-col--offset-7{margin-left:29.16666667%}.van-col--8{width:33.33333333%}.van-col--offset-8{margin-left:33.33333333%}.van-col--9{width:37.5%}.van-col--offset-9{margin-left:37.5%}.van-col--10{width:41.66666667%}.van-col--offset-10{margin-left:41.66666667%}.van-col--11{width:45.83333333%}.van-col--offset-11{margin-left:45.83333333%}.van-col--12{width:50%}.van-col--offset-12{margin-left:50%}.van-col--13{width:54.16666667%}.van-col--offset-13{margin-left:54.16666667%}.van-col--14{width:58.33333333%}.van-col--offset-14{margin-left:58.33333333%}.van-col--15{width:62.5%}.van-col--offset-15{margin-left:62.5%}.van-col--16{width:66.66666667%}.van-col--offset-16{margin-left:66.66666667%}.van-col--17{width:70.83333333%}.van-col--offset-17{margin-left:70.83333333%}.van-col--18{width:75%}.van-col--offset-18{margin-left:75%}.van-col--19{width:79.16666667%}.van-col--offset-19{margin-left:79.16666667%}.van-col--20{width:83.33333333%}.van-col--offset-20{margin-left:83.33333333%}.van-col--21{width:87.5%}.van-col--offset-21{margin-left:87.5%}.van-col--22{width:91.66666667%}.van-col--offset-22{margin-left:91.66666667%}.van-col--23{width:95.83333333%}.van-col--offset-23{margin-left:95.83333333%}.van-col--24{width:100%}.van-col--offset-24{margin-left:100%}

+ 2 - 0
miniprogram/miniprogram_npm/@vant/weapp/collapse-item/animate.d.ts

@@ -0,0 +1,2 @@
+/// <reference types="miniprogram-api-typings" />
+export declare function setContentAnimate(context: WechatMiniprogram.Component.TrivialInstance, expanded: boolean, mounted: boolean): void;

+ 43 - 0
miniprogram/miniprogram_npm/@vant/weapp/collapse-item/animate.js

@@ -0,0 +1,43 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.setContentAnimate = void 0;
+var utils_1 = require("../common/utils");
+function useAnimation(context, expanded, mounted, height) {
+    var animation = wx.createAnimation({
+        duration: 0,
+        timingFunction: 'ease-in-out',
+    });
+    if (expanded) {
+        if (height === 0) {
+            animation.height('auto').top(1).step();
+        }
+        else {
+            animation
+                .height(height)
+                .top(1)
+                .step({
+                duration: mounted ? 300 : 1,
+            })
+                .height('auto')
+                .step();
+        }
+        context.setData({
+            animation: animation.export(),
+        });
+        return;
+    }
+    animation.height(height).top(0).step({ duration: 1 }).height(0).step({
+        duration: 300,
+    });
+    context.setData({
+        animation: animation.export(),
+    });
+}
+function setContentAnimate(context, expanded, mounted) {
+    (0, utils_1.getRect)(context, '.van-collapse-item__content')
+        .then(function (rect) { return rect.height; })
+        .then(function (height) {
+        useAnimation(context, expanded, mounted, height);
+    });
+}
+exports.setContentAnimate = setContentAnimate;

+ 1 - 0
miniprogram/miniprogram_npm/@vant/weapp/collapse-item/index.d.ts

@@ -0,0 +1 @@
+export {};

+ 61 - 0
miniprogram/miniprogram_npm/@vant/weapp/collapse-item/index.js

@@ -0,0 +1,61 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var component_1 = require("../common/component");
+var relation_1 = require("../common/relation");
+var animate_1 = require("./animate");
+(0, component_1.VantComponent)({
+    classes: ['title-class', 'content-class'],
+    relation: (0, relation_1.useParent)('collapse'),
+    props: {
+        name: null,
+        title: null,
+        value: null,
+        icon: String,
+        label: String,
+        disabled: Boolean,
+        clickable: Boolean,
+        border: {
+            type: Boolean,
+            value: true,
+        },
+        isLink: {
+            type: Boolean,
+            value: true,
+        },
+    },
+    data: {
+        expanded: false,
+    },
+    mounted: function () {
+        this.updateExpanded();
+        this.mounted = true;
+    },
+    methods: {
+        updateExpanded: function () {
+            if (!this.parent) {
+                return;
+            }
+            var _a = this.parent.data, value = _a.value, accordion = _a.accordion;
+            var _b = this.parent.children, children = _b === void 0 ? [] : _b;
+            var name = this.data.name;
+            var index = children.indexOf(this);
+            var currentName = name == null ? index : name;
+            var expanded = accordion
+                ? value === currentName
+                : (value || []).some(function (name) { return name === currentName; });
+            if (expanded !== this.data.expanded) {
+                (0, animate_1.setContentAnimate)(this, expanded, this.mounted);
+            }
+            this.setData({ index: index, expanded: expanded });
+        },
+        onClick: function () {
+            if (this.data.disabled) {
+                return;
+            }
+            var _a = this.data, name = _a.name, expanded = _a.expanded;
+            var index = this.parent.children.indexOf(this);
+            var currentName = name == null ? index : name;
+            this.parent.switch(currentName, !expanded);
+        },
+    },
+});

+ 6 - 0
miniprogram/miniprogram_npm/@vant/weapp/collapse-item/index.json

@@ -0,0 +1,6 @@
+{
+  "component": true,
+  "usingComponents": {
+    "van-cell": "../cell/index"
+  }
+}

+ 44 - 0
miniprogram/miniprogram_npm/@vant/weapp/collapse-item/index.wxml

@@ -0,0 +1,44 @@
+<wxs src="../wxs/utils.wxs" module="utils" />
+
+<view class="van-collapse-item custom-class {{ index !== 0 ? 'van-hairline--top' : '' }}">
+  <van-cell
+    title="{{ title }}"
+    title-class="title-class"
+    icon="{{ icon }}"
+    value="{{ value }}"
+    label="{{ label }}"
+    is-link="{{ isLink }}"
+    clickable="{{ clickable }}"
+    border="{{ border && expanded }}"
+    class="{{ utils.bem('collapse-item__title', { disabled, expanded }) }}"
+    right-icon-class="van-cell__right-icon"
+    custom-class="van-cell"
+    hover-class="van-cell--hover"
+    bind:click="onClick"
+  >
+    <slot
+      name="title"
+      slot="title"
+    />
+    <slot
+      name="icon"
+      slot="icon"
+    />
+    <slot name="value" />
+    <slot
+      name="right-icon"
+      slot="right-icon"
+    />
+  </van-cell>
+  <view
+    class="{{ utils.bem('collapse-item__wrapper') }}"
+    style="height: 0;"
+    animation="{{ animation }}"
+  >
+    <view
+      class="van-collapse-item__content content-class"
+    >
+      <slot />
+    </view>
+  </view>
+</view>

+ 1 - 0
miniprogram/miniprogram_npm/@vant/weapp/collapse-item/index.wxss

@@ -0,0 +1 @@
+@import '../common/index.wxss';.van-collapse-item__title .van-cell__right-icon{transform:rotate(90deg);transition:transform var(--collapse-item-transition-duration,.3s)}.van-collapse-item__title--expanded .van-cell__right-icon{transform:rotate(-90deg)}.van-collapse-item__title--disabled .van-cell,.van-collapse-item__title--disabled .van-cell__right-icon{color:var(--collapse-item-title-disabled-color,#c8c9cc)!important}.van-collapse-item__title--disabled .van-cell--hover{background-color:#fff!important}.van-collapse-item__wrapper{overflow:hidden}.van-collapse-item__content{background-color:var(--collapse-item-content-background-color,#fff);color:var(--collapse-item-content-text-color,#969799);font-size:var(--collapse-item-content-font-size,13px);line-height:var(--collapse-item-content-line-height,1.5);padding:var(--collapse-item-content-padding,15px)}

+ 1 - 0
miniprogram/miniprogram_npm/@vant/weapp/collapse/index.d.ts

@@ -0,0 +1 @@
+export {};

+ 48 - 0
miniprogram/miniprogram_npm/@vant/weapp/collapse/index.js

@@ -0,0 +1,48 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+var component_1 = require("../common/component");
+var relation_1 = require("../common/relation");
+(0, component_1.VantComponent)({
+    relation: (0, relation_1.useChildren)('collapse-item'),
+    props: {
+        value: {
+            type: null,
+            observer: 'updateExpanded',
+        },
+        accordion: {
+            type: Boolean,
+            observer: 'updateExpanded',
+        },
+        border: {
+            type: Boolean,
+            value: true,
+        },
+    },
+    methods: {
+        updateExpanded: function () {
+            this.children.forEach(function (child) {
+                child.updateExpanded();
+            });
+        },
+        switch: function (name, expanded) {
+            var _a = this.data, accordion = _a.accordion, value = _a.value;
+            var changeItem = name;
+            if (!accordion) {
+                name = expanded
+                    ? (value || []).concat(name)
+                    : (value || []).filter(function (activeName) { return activeName !== name; });
+            }
+            else {
+                name = expanded ? name : '';
+            }
+            if (expanded) {
+                this.$emit('open', changeItem);
+            }
+            else {
+                this.$emit('close', changeItem);
+            }
+            this.$emit('change', name);
+            this.$emit('input', name);
+        },
+    },
+});

+ 3 - 0
miniprogram/miniprogram_npm/@vant/weapp/collapse/index.json

@@ -0,0 +1,3 @@
+{
+  "component": true
+}

+ 3 - 0
miniprogram/miniprogram_npm/@vant/weapp/collapse/index.wxml

@@ -0,0 +1,3 @@
+<view class="custom-class van-collapse {{ border ? 'van-hairline--top-bottom' : '' }}">
+  <slot />
+</view>

Неке датотеке нису приказане због велике количине промена