Merge branch 'next' of github.com:ecomfe/echarts-examples into next
diff --git a/README.md b/README.md
index 3fbebf3..3af7e82 100644
--- a/README.md
+++ b/README.md
@@ -108,7 +108,7 @@
 For example:
 ```js
 $.when(
-    $.getScript(ROOT_PATH + '/data/asset/js/myTransform.js'),
+    $.getScript(ROOT_PATH + '/data/asset/js/xxxx.js'),
     $.getScript('https://cdn.jsdelivr.net/npm/d3-contour@2.0.0/dist/d3-contour.jXs'),
 ).done(function () {
     // ...
diff --git a/public/data/asset/js/myTransform.js b/public/data/asset/js/myTransform.js
deleted file mode 100644
index a2f97b5..0000000
--- a/public/data/asset/js/myTransform.js
+++ /dev/null
@@ -1,476 +0,0 @@
-(function (global, factory) {
-  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (global = global || self, factory(global.myTransform = {}));
-})(this, function (exports) {
-  'use strict';
-
-  var transform = {
-    type: 'myTransform:id',
-    transform: function (params) {
-      var upstream = params.upstream;
-      var config = params.config;
-      var dimensionIndex = config.dimensionIndex;
-      var dimensionName = config.dimensionName;
-      var dimsDef = upstream.cloneAllDimensionInfo();
-      dimsDef[dimensionIndex] = dimensionName;
-      var data = upstream.cloneRawData();
-
-      for (var i = 0, len = data.length; i < len; i++) {
-        var line = data[i];
-        line[dimensionIndex] = i;
-      }
-
-      return {
-        dimensions: dimsDef,
-        data: data
-      };
-    }
-  };
-  var arrayProto = Array.prototype;
-  var nativeForEach = arrayProto.forEach;
-  var nativeSlice = arrayProto.slice;
-  var nativeMap = arrayProto.map;
-
-  var ctorFunction = function () {}.constructor;
-
-  var protoFunction = ctorFunction ? ctorFunction.prototype : null;
-
-  function each(arr, cb, context) {
-    if (!(arr && cb)) {
-      return;
-    }
-
-    if (arr.forEach && arr.forEach === nativeForEach) {
-      arr.forEach(cb, context);
-    } else if (arr.length === +arr.length) {
-      for (var i = 0, len = arr.length; i < len; i++) {
-        cb.call(context, arr[i], i, arr);
-      }
-    } else {
-      for (var key in arr) {
-        if (arr.hasOwnProperty(key)) {
-          cb.call(context, arr[key], key, arr);
-        }
-      }
-    }
-  }
-
-  function map(arr, cb, context) {
-    if (!arr) {
-      return [];
-    }
-
-    if (!cb) {
-      return slice(arr);
-    }
-
-    if (arr.map && arr.map === nativeMap) {
-      return arr.map(cb, context);
-    } else {
-      var result = [];
-
-      for (var i = 0, len = arr.length; i < len; i++) {
-        result.push(cb.call(context, arr[i], i, arr));
-      }
-
-      return result;
-    }
-  }
-
-  function bindPolyfill(func, context) {
-    var args = [];
-
-    for (var _i = 2; _i < arguments.length; _i++) {
-      args[_i - 2] = arguments[_i];
-    }
-
-    return function () {
-      return func.apply(context, args.concat(nativeSlice.call(arguments)));
-    };
-  }
-
-  var bind = protoFunction && isFunction(protoFunction.bind) ? protoFunction.call.bind(protoFunction.bind) : bindPolyfill;
-
-  function isFunction(value) {
-    return typeof value === 'function';
-  }
-
-  function slice(arr) {
-    var args = [];
-
-    for (var _i = 1; _i < arguments.length; _i++) {
-      args[_i - 1] = arguments[_i];
-    }
-
-    return nativeSlice.apply(arr, args);
-  }
-
-  function assert(condition, message) {
-    if (!condition) {
-      throw new Error(message);
-    }
-  }
-
-  function hasOwn(own, prop) {
-    return own.hasOwnProperty(prop);
-  }
-
-  function quantile(ascArr, p) {
-    var H = (ascArr.length - 1) * p + 1;
-    var h = Math.floor(H);
-    var v = +ascArr[h - 1];
-    var e = H - h;
-    return e ? v + e * (ascArr[h] - v) : v;
-  }
-
-  var METHOD_INTERNAL = {
-    'SUM': true,
-    'COUNT': true,
-    'FIRST': true,
-    'AVERAGE': true,
-    'Q1': true,
-    'Q2': true,
-    'Q3': true,
-    'MIN': true,
-    'MAX': true
-  };
-  var METHOD_NEEDS_COLLECT = {
-    AVERAGE: ['COUNT']
-  };
-  var METHOD_NEEDS_GATHER_VALUES = {
-    Q1: true,
-    Q2: true,
-    Q3: true
-  };
-  var METHOD_ALIAS = {
-    MEDIAN: 'Q2'
-  };
-
-  var ResultDimInfoInternal = function () {
-    function ResultDimInfoInternal(index, indexInUpstream, method, name, needGatherValues) {
-      this.collectionInfoList = [];
-      this.gatheredValuesByGroup = {};
-      this.gatheredValuesNoGroup = [];
-      this.needGatherValues = false;
-      this._collectionInfoMap = {};
-      this.method = method;
-      this.name = name;
-      this.index = index;
-      this.indexInUpstream = indexInUpstream;
-      this.needGatherValues = needGatherValues;
-    }
-
-    ResultDimInfoInternal.prototype.addCollectionInfo = function (item) {
-      this._collectionInfoMap[item.method] = this.collectionInfoList.length;
-      this.collectionInfoList.push(item);
-    };
-
-    ResultDimInfoInternal.prototype.getCollectionInfo = function (method) {
-      return this.collectionInfoList[this._collectionInfoMap[method]];
-    };
-
-    ResultDimInfoInternal.prototype.gatherValue = function (groupByDimInfo, groupVal, value) {
-      value = +value;
-
-      if (groupByDimInfo) {
-        if (groupVal != null) {
-          var groupValStr = groupVal + '';
-          var values = this.gatheredValuesByGroup[groupValStr] || (this.gatheredValuesByGroup[groupValStr] = []);
-          values.push(value);
-        }
-      } else {
-        this.gatheredValuesNoGroup.push(value);
-      }
-    };
-
-    return ResultDimInfoInternal;
-  }();
-
-  var transform$1 = {
-    type: 'myTransform:aggregate',
-    transform: function (params) {
-      var upstream = params.upstream;
-      var config = params.config;
-      var groupByDimInfo = prepareGroupByDimInfo(config, upstream);
-
-      var _a = prepareDimensions(config, upstream, groupByDimInfo),
-          finalResultDimInfoList = _a.finalResultDimInfoList,
-          collectionDimInfoList = _a.collectionDimInfoList;
-
-      var collectionResult;
-
-      if (collectionDimInfoList.length) {
-        collectionResult = travel(groupByDimInfo, upstream, collectionDimInfoList, createCollectionResultLine, updateCollectionResultLine);
-      }
-
-      each(collectionDimInfoList, function (dimInfo) {
-        dimInfo.__collectionResult = collectionResult;
-        asc(dimInfo.gatheredValuesNoGroup);
-        each(dimInfo.gatheredValuesByGroup, function (values) {
-          asc(values);
-        });
-      });
-      var finalResult = travel(groupByDimInfo, upstream, finalResultDimInfoList, createFinalResultLine, updateFinalResultLine);
-      return {
-        dimensions: map(finalResultDimInfoList, function (item) {
-          return item.name;
-        }),
-        data: finalResult.outList
-      };
-    }
-  };
-
-  function prepareDimensions(config, upstream, groupByDimInfo) {
-    var resultDimensionsConfig = config.resultDimensions;
-    var finalResultDimInfoList = [];
-    var collectionDimInfoList = [];
-    var gIndexInLine = 0;
-
-    for (var i = 0; i < resultDimensionsConfig.length; i++) {
-      var resultDimInfoConfig = resultDimensionsConfig[i];
-      var dimInfoInUpstream = upstream.getDimensionInfo(resultDimInfoConfig.from);
-      assert(dimInfoInUpstream, 'Can not find dimension by `from`: ' + resultDimInfoConfig.from);
-      var rawMethod = resultDimInfoConfig.method;
-      assert(groupByDimInfo.index !== dimInfoInUpstream.index || rawMethod == null, "Dimension " + dimInfoInUpstream.name + " is the \"groupBy\" dimension, must not have any \"method\".");
-      var method = normalizeMethod(rawMethod);
-      assert(method, 'method is required');
-      var name_1 = resultDimInfoConfig.name != null ? resultDimInfoConfig.name : dimInfoInUpstream.name;
-      var finalResultDimInfo = new ResultDimInfoInternal(finalResultDimInfoList.length, dimInfoInUpstream.index, method, name_1, hasOwn(METHOD_NEEDS_GATHER_VALUES, method));
-      finalResultDimInfoList.push(finalResultDimInfo);
-      var needCollect = false;
-
-      if (hasOwn(METHOD_NEEDS_COLLECT, method)) {
-        needCollect = true;
-        var collectionTargetMethods = METHOD_NEEDS_COLLECT[method];
-
-        for (var j = 0; j < collectionTargetMethods.length; j++) {
-          finalResultDimInfo.addCollectionInfo({
-            method: collectionTargetMethods[j],
-            indexInLine: gIndexInLine++
-          });
-        }
-      }
-
-      if (hasOwn(METHOD_NEEDS_GATHER_VALUES, method)) {
-        needCollect = true;
-      }
-
-      if (needCollect) {
-        collectionDimInfoList.push(finalResultDimInfo);
-      }
-    }
-
-    return {
-      collectionDimInfoList: collectionDimInfoList,
-      finalResultDimInfoList: finalResultDimInfoList
-    };
-  }
-
-  function prepareGroupByDimInfo(config, upstream) {
-    var groupByConfig = config.groupBy;
-    var groupByDimInfo;
-
-    if (groupByConfig != null) {
-      groupByDimInfo = upstream.getDimensionInfo(groupByConfig);
-      assert(groupByDimInfo, 'Can not find dimension by `groupBy`: ' + groupByConfig);
-    }
-
-    return groupByDimInfo;
-  }
-
-  function travel(groupByDimInfo, upstream, resultDimInfoList, doCreate, doUpdate) {
-    var outList = [];
-    var mapByGroup;
-
-    if (groupByDimInfo) {
-      mapByGroup = {};
-
-      for (var dataIndex = 0, len = upstream.count(); dataIndex < len; dataIndex++) {
-        var groupByVal = upstream.retrieveValue(dataIndex, groupByDimInfo.index);
-
-        if (groupByVal == null) {
-          continue;
-        }
-
-        var groupByValStr = groupByVal + '';
-
-        if (!hasOwn(mapByGroup, groupByValStr)) {
-          var newLine = doCreate(upstream, dataIndex, resultDimInfoList, groupByDimInfo, groupByVal);
-          outList.push(newLine);
-          mapByGroup[groupByValStr] = newLine;
-        } else {
-          var targetLine = mapByGroup[groupByValStr];
-          doUpdate(upstream, dataIndex, targetLine, resultDimInfoList, groupByDimInfo, groupByVal);
-        }
-      }
-    } else {
-      var targetLine = doCreate(upstream, 0, resultDimInfoList);
-      outList.push(targetLine);
-
-      for (var dataIndex = 1, len = upstream.count(); dataIndex < len; dataIndex++) {
-        doUpdate(upstream, dataIndex, targetLine, resultDimInfoList);
-      }
-    }
-
-    return {
-      mapByGroup: mapByGroup,
-      outList: outList
-    };
-  }
-
-  function normalizeMethod(method) {
-    if (method == null) {
-      return 'FIRST';
-    }
-
-    var methodInternal = method.toUpperCase();
-    methodInternal = hasOwn(METHOD_ALIAS, methodInternal) ? METHOD_ALIAS[methodInternal] : methodInternal;
-    assert(hasOwn(METHOD_INTERNAL, methodInternal), "Illegal method " + method + ".");
-    return methodInternal;
-  }
-
-  var createCollectionResultLine = function (upstream, dataIndex, collectionDimInfoList, groupByDimInfo, groupByVal) {
-    var newLine = [];
-
-    for (var i = 0; i < collectionDimInfoList.length; i++) {
-      var dimInfo = collectionDimInfoList[i];
-      var collectionInfoList = dimInfo.collectionInfoList;
-
-      for (var j = 0; j < collectionInfoList.length; j++) {
-        var collectionInfo = collectionInfoList[j];
-        newLine[collectionInfo.indexInLine] = +lineCreator[collectionInfo.method](upstream, dataIndex, dimInfo, groupByDimInfo, groupByVal);
-      }
-
-      if (dimInfo.needGatherValues) {
-        var val = upstream.retrieveValue(dataIndex, dimInfo.indexInUpstream);
-        dimInfo.gatherValue(groupByDimInfo, groupByVal, val);
-      }
-    }
-
-    return newLine;
-  };
-
-  var updateCollectionResultLine = function (upstream, dataIndex, targetLine, collectionDimInfoList, groupByDimInfo, groupByVal) {
-    for (var i = 0; i < collectionDimInfoList.length; i++) {
-      var dimInfo = collectionDimInfoList[i];
-      var collectionInfoList = dimInfo.collectionInfoList;
-
-      for (var j = 0; j < collectionInfoList.length; j++) {
-        var collectionInfo = collectionInfoList[j];
-        var indexInLine = collectionInfo.indexInLine;
-        targetLine[indexInLine] = +lineUpdater[collectionInfo.method](targetLine[indexInLine], upstream, dataIndex, dimInfo, groupByDimInfo, groupByVal);
-      }
-
-      if (dimInfo.needGatherValues) {
-        var val = upstream.retrieveValue(dataIndex, dimInfo.indexInUpstream);
-        dimInfo.gatherValue(groupByDimInfo, groupByVal, val);
-      }
-    }
-  };
-
-  var createFinalResultLine = function (upstream, dataIndex, finalResultDimInfoList, groupByDimInfo, groupByVal) {
-    var newLine = [];
-
-    for (var i = 0; i < finalResultDimInfoList.length; i++) {
-      var dimInfo = finalResultDimInfoList[i];
-      var method = dimInfo.method;
-      newLine[i] = isGroupByDimension(groupByDimInfo, dimInfo) ? groupByVal : lineCreator[method](upstream, dataIndex, dimInfo, groupByDimInfo, groupByVal);
-    }
-
-    return newLine;
-  };
-
-  var updateFinalResultLine = function (upstream, dataIndex, targetLine, finalResultDimInfoList, groupByDimInfo, groupByVal) {
-    for (var i = 0; i < finalResultDimInfoList.length; i++) {
-      var dimInfo = finalResultDimInfoList[i];
-
-      if (isGroupByDimension(groupByDimInfo, dimInfo)) {
-        continue;
-      }
-
-      var method = dimInfo.method;
-      targetLine[i] = lineUpdater[method](targetLine[i], upstream, dataIndex, dimInfo, groupByDimInfo, groupByVal);
-    }
-  };
-
-  function isGroupByDimension(groupByDimInfo, targetDimInfo) {
-    return groupByDimInfo && targetDimInfo.indexInUpstream === groupByDimInfo.index;
-  }
-
-  function asc(list) {
-    list.sort(function (a, b) {
-      return a - b;
-    });
-  }
-
-  var lineCreator = {
-    'SUM': function () {
-      return 0;
-    },
-    'COUNT': function () {
-      return 1;
-    },
-    'FIRST': function (upstream, dataIndex, dimInfo) {
-      return upstream.retrieveValue(dataIndex, dimInfo.indexInUpstream);
-    },
-    'MIN': function (upstream, dataIndex, dimInfo) {
-      return upstream.retrieveValue(dataIndex, dimInfo.indexInUpstream);
-    },
-    'MAX': function (upstream, dataIndex, dimInfo) {
-      return upstream.retrieveValue(dataIndex, dimInfo.indexInUpstream);
-    },
-    'AVERAGE': function (upstream, dataIndex, dimInfo, groupByDimInfo, groupByVal) {
-      var collectLine = groupByDimInfo ? dimInfo.__collectionResult.mapByGroup[groupByVal + ''] : dimInfo.__collectionResult.outList[0];
-      return upstream.retrieveValue(dataIndex, dimInfo.indexInUpstream) / collectLine[dimInfo.getCollectionInfo('COUNT').indexInLine];
-    },
-    'Q1': function (upstream, dataIndex, dimInfo, groupByDimInfo, groupByVal) {
-      return lineCreatorForQ(0.25, dimInfo, groupByDimInfo, groupByVal);
-    },
-    'Q2': function (upstream, dataIndex, dimInfo, groupByDimInfo, groupByVal) {
-      return lineCreatorForQ(0.5, dimInfo, groupByDimInfo, groupByVal);
-    },
-    'Q3': function (upstream, dataIndex, dimInfo, groupByDimInfo, groupByVal) {
-      return lineCreatorForQ(0.75, dimInfo, groupByDimInfo, groupByVal);
-    }
-  };
-  var lineUpdater = {
-    'SUM': function (val, upstream, dataIndex, dimInfo) {
-      return val + upstream.retrieveValue(dataIndex, dimInfo.indexInUpstream);
-    },
-    'COUNT': function (val) {
-      return val + 1;
-    },
-    'FIRST': function (val) {
-      return val;
-    },
-    'MIN': function (val, upstream, dataIndex, dimInfo) {
-      return Math.min(val, upstream.retrieveValue(dataIndex, dimInfo.indexInUpstream));
-    },
-    'MAX': function (val, upstream, dataIndex, dimInfo) {
-      return Math.max(val, upstream.retrieveValue(dataIndex, dimInfo.indexInUpstream));
-    },
-    'AVERAGE': function (val, upstream, dataIndex, dimInfo, groupByDimInfo, groupByVal) {
-      var collectLine = groupByDimInfo ? dimInfo.__collectionResult.mapByGroup[groupByVal + ''] : dimInfo.__collectionResult.outList[0];
-      return val + upstream.retrieveValue(dataIndex, dimInfo.indexInUpstream) / collectLine[dimInfo.getCollectionInfo('COUNT').indexInLine];
-    },
-    'Q1': function (val, upstream, dataIndex, dimInfo) {
-      return val;
-    },
-    'Q2': function (val, upstream, dataIndex, dimInfo) {
-      return val;
-    },
-    'Q3': function (val, upstream, dataIndex, dimInfo) {
-      return val;
-    }
-  };
-
-  function lineCreatorForQ(percent, dimInfo, groupByDimInfo, groupByVal) {
-    var gatheredValues = groupByDimInfo ? dimInfo.gatheredValuesByGroup[groupByVal + ''] : dimInfo.gatheredValuesNoGroup;
-    return quantile(gatheredValues, percent);
-  }
-
-  exports.aggregate = transform$1;
-  exports.id = transform;
-  Object.defineProperty(exports, '__esModule', {
-    value: true
-  });
-});
\ No newline at end of file
diff --git a/public/data/asset/js/transitionPlayer.js b/public/data/asset/js/transitionPlayer.js
deleted file mode 100644
index 6355e99..0000000
--- a/public/data/asset/js/transitionPlayer.js
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
-* Licensed to the Apache Software Foundation (ASF) under one
-* or more contributor license agreements.  See the NOTICE file
-* distributed with this work for additional information
-* regarding copyright ownership.  The ASF licenses this file
-* to you under the Apache License, Version 2.0 (the
-* "License"); you may not use this file except in compliance
-* with the License.  You may obtain a copy of the License at
-*
-*   http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing,
-* software distributed under the License is distributed on an
-* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-* KIND, either express or implied.  See the License for the
-* specific language governing permissions and limitations
-* under the License.
-*/
-
-(function (exports) {
-
-    var transitionPlayer = {};
-
-    /**
-     * @usage
-     * ```js
-     * // Initialize with an array of echarts option info:
-     * var player = transitionPlayer.create({
-     *
-     *     // The echarts instance or chart instance getter.
-     *     chart: function () {
-     *         return myChart;
-     *     },
-     *     seriesIndex: 0,
-     *     replaceMerge: ['xAxis', 'yAxis']
-     *
-     *     // The data meta info used to determine how to
-     *     // make transition mapping.
-     *     // The strategy: If `uniqueDimension` provided and is a common
-     *     // dimension, use `uniqueDimension`.
-     *     dataMeta: {
-     *         aaa: {
-     *             dimensions: ['qqq', 'www', 'eee', 'rrr']
-     *         },
-     *         bbb: {
-     *             dimensions: ['ccc', 'www', 'eee'],
-     *             uniqueDimension: 'www',
-     *             dividingMethod: 'duplicate'
-     *         },
-     *         ...
-     *     },
-     *
-     *     // echarts option collection:
-     *     optionList: [
-     *         // dataMetaKey is the key of 'dataMeta'.
-     *         { key: 'Time_Income_Bar', option: option0, dataMetaKey: 'aaa' },
-     *         { key: 'Population_Income_Scatter', option: option1, dataMetaKey: 'bbb' },
-     *         { key: 'Time_Income_Pie', option: option2, dataMetaKey: 'aaa' },
-     *         ...
-     *     ]
-     * });
-     *
-     * // Then start to play:
-     * player.next(); // Display next option (from the first option).
-     * player.previous(); // Display previous optoin.
-     * player.go('Time_Income_Pie'); // Display the specified option.
-     * player.getOptionKeys(); // return `['Time_Income_Bar', 'Population_Income_Scatter', 'Time_Income_Pie']`
-     * ```
-     *
-     * @parma opt See the constructor of `TransitionPlayer`.
-     */
-    transitionPlayer.create = function (opt) {
-        return new TransitionPlayer(opt);
-    };
-
-    /**
-     * @param opt
-     * @param opt.chart
-     *        (EChartsInstance | () => EChartsInstance)
-     *        echarts instance or echarts instance getter.
-     * @param opt.dataMeta
-     *        {
-     *            [dataMetaKey in string]: {
-     *                dimensions: string[];
-     *                uniqueDimension?: string;
-     *                dividingMethod?: 'split' | 'duplicate'
-     *            }
-     *        }
-     * @param opt.optionList
-     *        {
-     *            key: string;
-     *            option: EChartsOption;
-     *            dataMetaKey: string;
-     *        }[]
-     * @param opt.seriesIndex number
-     *        Target series index to be transitioned.
-     * @param opt.replaceMerge? string[]
-     */
-    function TransitionPlayer(opt) {
-        assert(
-            opt.chart
-            && isObject(opt.dataMeta)
-            && isArray(opt.optionList)
-            && opt.seriesIndex != null
-            && opt.optionList.length
-        );
-
-        this._chart = opt.chart;
-        this._dataMeta = opt.dataMeta;
-        var optionList = this._optionList = opt.optionList;
-        var optionMap = this._optionMap = {};
-        this._replaceMerge = opt.replaceMerge;
-        this._seriesIndex = opt.seriesIndex;
-        this._currOptionIdx = null;
-
-        for (var i = 0; i < optionList.length; i++) {
-            var optionWrap = optionList[i];
-            var optionKey = optionWrap.key;
-            if (optionKey != null) {
-                assert(!hasOwn(optionMap, optionKey), 'option key duplicat: ' + optionKey);
-                optionMap[optionKey] = i;
-            }
-        }
-    }
-
-    var proto = TransitionPlayer.prototype;
-
-    proto.next = function () {
-        var optionList = this._optionList;
-        var newOptionIdx = this._currOptionIdx == null
-            ? 0
-            : Math.min(optionList.length - 1, this._currOptionIdx + 1);
-
-        this._doChangeOption(newOptionIdx);
-    };
-
-    proto.previous = function () {
-        var optionList = this._optionList;
-        var newOptionIdx = this._currOptionIdx == null
-            ? optionList.length - 1
-            : Math.max(0, this._currOptionIdx - 1);
-
-        this._doChangeOption(newOptionIdx);
-    };
-
-    /**
-     * @param optionKey string
-     */
-    proto.go = function (optionKey) {
-        var newOptionIdx = getMapValue(this._optionMap, optionKey);
-        assert(newOptionIdx != null, 'Can not find option by option key: ' + optionKey);
-
-        this._doChangeOption(newOptionIdx);
-    };
-
-    proto._doChangeOption = function (newOptionIdx) {
-        var optionList = this._optionList;
-        var oldOptionWrap = this._currOptionIdx != null ? optionList[this._currOptionIdx] : null;
-        var newOptionWrap = optionList[newOptionIdx];
-        var dataMeta = this._dataMeta;
-        var targetSeriesIndex = this._seriesIndex;
-
-        var transitionOpt = {
-            // If can not find mapped dimensions, do not make transition animation
-            // by default, becuase this transition probably bring about misleading.
-            to: { seriesIndex: targetSeriesIndex }
-        };
-
-        if (oldOptionWrap) {
-            var commonDimension =
-                findCommonDimension(oldOptionWrap, newOptionWrap)
-                || findCommonDimension(newOptionWrap, oldOptionWrap);
-            if (commonDimension != null) {
-                transitionOpt = {
-                    from: {
-                        seriesIndex: targetSeriesIndex,
-                        dimension: commonDimension
-                    },
-                    to: {
-                        seriesIndex: targetSeriesIndex,
-                        dimension: commonDimension,
-                    },
-                    dividingMethod: dataMeta.dividingMethod
-                };
-            }
-        }
-
-        this._currOptionIdx = newOptionIdx;
-
-        this._getChart().setOption(newOptionWrap.option, {
-            replaceMerge: this._replaceMerge,
-            transition: transitionOpt
-        });
-
-        function findCommonDimension(optionWrapA, optionWrapB) {
-            var metaA = getMapValue(dataMeta, optionWrapA.dataMetaKey);
-            var metaB = getMapValue(dataMeta, optionWrapB.dataMetaKey);
-            var uniqueDimensionB = metaB.uniqueDimension;
-            if (uniqueDimensionB != null && metaA.dimensions.indexOf(uniqueDimensionB) >= 0) {
-                return uniqueDimensionB;
-            }
-        }
-
-    };
-
-    proto._getChart = function () {
-        return isFunction(this._chart) ? this._chart() : this._chart;
-    };
-
-    /**
-     * @return string[]
-     */
-    proto.getOptionKeys = function () {
-        var optionKeys = [];
-        var optionList = this._optionList;
-        for (var i = 0; i < optionList.length; i++) {
-            optionKeys.push(optionList[i].key);
-        }
-        return optionKeys;
-    };
-
-
-    function assert(cond, msg) {
-        if (!cond) {
-            throw new Error(msg || 'transition player error');
-        }
-    }
-
-    function isObject(value) {
-        const type = typeof value;
-        return type === 'function' || (!!value && type === 'object');
-    }
-
-    function isArray(value) {
-        if (Array.isArray) {
-            return Array.isArray(value);
-        }
-        return Object.prototype.toString.call(value) === '[object Array]';
-    }
-
-    function isFunction(value) {
-        return typeof value === 'function';
-    }
-
-    function hasOwn(obj, key) {
-        return obj.hasOwnProperty(key);
-    }
-
-    function getMapValue(map, key) {
-        return (key != null && hasOwn(map, key)) ? map[key] : null;
-    }
-
-
-    exports.transitionPlayer = transitionPlayer;
-
-})(this);
diff --git a/public/data/custom-combine-separate-morph.js b/public/data/custom-combine-separate-morph.js
index d5ab6dd..0e3a2f3 100644
--- a/public/data/custom-combine-separate-morph.js
+++ b/public/data/custom-combine-separate-morph.js
@@ -76,7 +76,7 @@
         id: 'mTagSum',
         fromDatasetId: 'raw',
         transform: {
-            type: 'myTransform:aggregate',
+            type: 'ecSimpleTransform:aggregate',
             config: {
                 resultDimensions: [
                     { from: 'ATA', method: 'sum' },
@@ -113,7 +113,7 @@
         id: 'rawClusterCenters',
         fromDatasetId: 'rawClusters',
         transform: {
-            type: 'myTransform:aggregate',
+            type: 'ecSimpleTransform:aggregate',
             // print: true,
             config: {
                 resultDimensions: [
@@ -460,8 +460,8 @@
 
 
 $.when(
-    $.getScript(ROOT_PATH + '/data/asset/js/myTransform.js'),
-    $.getScript(ROOT_PATH + '/data/asset/js/transitionPlayer.js'),
+    $.getScript('https://cdn.jsdelivr.net/npm/echarts-simple-transform/dist/ecSimpleTransform.min.js'),
+    $.getScript('https://cdn.jsdelivr.net/npm/echarts-simple-option-player/dist/ecSimpleOptionPlayer.min.js'),
 ).done(function () {
     run();
 });
@@ -469,10 +469,10 @@
 
 function run() {
 
-    echarts.registerTransform(myTransform.aggregate);
+    echarts.registerTransform(ecSimpleTransform.aggregate);
     echarts.registerTransform(ecStat.transform.clustering);
 
-    _player = transitionPlayer.create({
+    _player = ecSimpleOptionPlayer.create({
         chart: function () {
             return myChart;
         },
diff --git a/public/data/custom-story-transition.js b/public/data/custom-story-transition.js
index 366dce8..c164a88 100644
--- a/public/data/custom-story-transition.js
+++ b/public/data/custom-story-transition.js
@@ -7,7 +7,7 @@
 
 $.when(
     $.get(ROOT_PATH + '/data/asset/data/life-expectancy-table.json'),
-    $.getScript(ROOT_PATH + '/data/asset/js/myTransform.js')
+    $.getScript('https://cdn.jsdelivr.net/npm/echarts-simple-transform/dist/ecSimpleTransform.min.js')
 ).done(function (res) {
     run(res[0]);
 });
@@ -15,8 +15,8 @@
 let _optionList;
 
 function run(_rawData) {
-    echarts.registerTransform(myTransform.aggregate);
-    echarts.registerTransform(myTransform.id);
+    echarts.registerTransform(ecSimpleTransform.aggregate);
+    echarts.registerTransform(ecSimpleTransform.id);
 
 
     const COUNTRY_A = 'Germany';
@@ -54,7 +54,7 @@
                     dimension: 'Year', gte: 1950
                 }
             }, {
-                type: 'myTransform:id',
+                type: 'ecSimpleTransform:id',
                 config: {
                     dimensionIndex: 5,
                     dimensionName: 'Id'
@@ -77,7 +77,7 @@
             id: 'DatasetCountryABSumIncome',
             fromDatasetId: 'DatasetCountryAB',
             transform: {
-                type: 'myTransform:aggregate',
+                type: 'ecSimpleTransform:aggregate',
                 config: {
                     resultDimensions: [
                         { from: 'Income', method: 'sum' },
diff --git a/public/data/data-transform-aggregate.js b/public/data/data-transform-aggregate.js
index 52e6f16..f22ec12 100644
--- a/public/data/data-transform-aggregate.js
+++ b/public/data/data-transform-aggregate.js
@@ -7,14 +7,14 @@
 
 $.when(
     $.get(ROOT_PATH + '/data/asset/data/life-expectancy-table.json'),
-    $.getScript(ROOT_PATH + '/data/asset/js/myTransform.js')
+    $.getScript('https://cdn.jsdelivr.net/npm/echarts-simple-transform/dist/ecSimpleTransform.min.js')
 ).done(function (res) {
     run(res[0]);
 });
 
 function run(_rawData) {
 
-    echarts.registerTransform(window.myTransform.aggregate);
+    echarts.registerTransform(window.ecSimpleTransform.aggregate);
 
     option = {
         dataset: [{
@@ -33,7 +33,7 @@
             id: 'income_aggregate',
             fromDatasetId: 'since_year',
             transform: [{
-                type: 'myTransform:aggregate',
+                type: 'ecSimpleTransform:aggregate',
                 config: {
                     resultDimensions: [
                         { name: 'min', from: 'Income', method: 'min' },