You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@echarts.apache.org by su...@apache.org on 2019/11/29 10:57:59 UTC

[incubator-echarts] branch fix/dim-guess created (now 0b97133)

This is an automated email from the ASF dual-hosted git repository.

sushuang pushed a change to branch fix/dim-guess
in repository https://gitbox.apache.org/repos/asf/incubator-echarts.git.


      at 0b97133  fix: (1) Enhance dataset default encode guess strategy. Fix #11428, Fix #11419, Fix #11735 (2) Support candlestick in dataset encode guess. (3) Some refactor of the code arrangement of dataset encode guess and dimension calculation.

This branch includes the following new commits:

     new 0b97133  fix: (1) Enhance dataset default encode guess strategy. Fix #11428, Fix #11419, Fix #11735 (2) Support candlestick in dataset encode guess. (3) Some refactor of the code arrangement of dataset encode guess and dimension calculation.

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@echarts.apache.org
For additional commands, e-mail: commits-help@echarts.apache.org


[incubator-echarts] 01/01: fix: (1) Enhance dataset default encode guess strategy. Fix #11428, Fix #11419, Fix #11735 (2) Support candlestick in dataset encode guess. (3) Some refactor of the code arrangement of dataset encode guess and dimension calculation.

Posted by su...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

sushuang pushed a commit to branch fix/dim-guess
in repository https://gitbox.apache.org/repos/asf/incubator-echarts.git

commit 0b971338a0ae2a619b7536f2367686fa8b4f30d3
Author: SHUANG SU <su...@gmail.com>
AuthorDate: Fri Nov 29 18:56:34 2019 +0800

    fix:
    (1) Enhance dataset default encode guess strategy. Fix #11428, Fix #11419, Fix #11735
    (2) Support candlestick in dataset encode guess.
    (3) Some refactor of the code arrangement of dataset encode guess and dimension calculation.
---
 src/chart/bar/BaseBarSeries.js                 |   2 +-
 src/chart/effectScatter/EffectScatterSeries.js |   2 +-
 src/chart/funnel/FunnelSeries.js               |   7 +-
 src/chart/helper/createListFromArray.js        |  21 +-
 src/chart/helper/whiskerBoxCommon.js           |  37 +--
 src/chart/line/LineSeries.js                   |   2 +-
 src/chart/map/MapSeries.js                     |   6 +-
 src/chart/pie/PieSeries.js                     |   6 +-
 src/chart/scatter/ScatterSeries.js             |   2 +-
 src/data/DataDimensionInfo.js                  | 135 +++++++++++
 src/data/List.js                               |  12 +-
 src/data/helper/completeDimensions.js          |  78 ++++---
 src/data/helper/createDimensions.js            |   2 +
 src/data/helper/sourceHelper.js                | 286 ++++++++++++++----------
 src/model/referHelper.js                       |  45 +++-
 test/dataset-guess.html                        | 297 +++++++++++++++++++++++++
 16 files changed, 741 insertions(+), 199 deletions(-)

diff --git a/src/chart/bar/BaseBarSeries.js b/src/chart/bar/BaseBarSeries.js
index e27f0a7..184a2a3 100644
--- a/src/chart/bar/BaseBarSeries.js
+++ b/src/chart/bar/BaseBarSeries.js
@@ -25,7 +25,7 @@ export default SeriesModel.extend({
     type: 'series.__base_bar__',
 
     getInitialData: function (option, ecModel) {
-        return createListFromArray(this.getSource(), this);
+        return createListFromArray(this.getSource(), this, {useEncodeDefaulter: true});
     },
 
     getMarkerPosition: function (value) {
diff --git a/src/chart/effectScatter/EffectScatterSeries.js b/src/chart/effectScatter/EffectScatterSeries.js
index f3a2dda..4aae804 100644
--- a/src/chart/effectScatter/EffectScatterSeries.js
+++ b/src/chart/effectScatter/EffectScatterSeries.js
@@ -27,7 +27,7 @@ export default SeriesModel.extend({
     dependencies: ['grid', 'polar'],
 
     getInitialData: function (option, ecModel) {
-        return createListFromArray(this.getSource(), this);
+        return createListFromArray(this.getSource(), this, {useEncodeDefaulter: true});
     },
 
     brushSelector: 'point',
diff --git a/src/chart/funnel/FunnelSeries.js b/src/chart/funnel/FunnelSeries.js
index d241cf8..fbeedbf 100644
--- a/src/chart/funnel/FunnelSeries.js
+++ b/src/chart/funnel/FunnelSeries.js
@@ -18,8 +18,10 @@
 */
 
 import * as echarts from '../../echarts';
+import * as zrUtil from 'zrender/src/core/util';
 import createListSimply from '../helper/createListSimply';
 import {defaultEmphasis} from '../../util/model';
+import {makeSeriesEncodeForNameBased} from '../../data/helper/sourceHelper';
 
 var FunnelSeries = echarts.extendSeriesModel({
 
@@ -38,7 +40,10 @@ var FunnelSeries = echarts.extendSeriesModel({
     },
 
     getInitialData: function (option, ecModel) {
-        return createListSimply(this, ['value']);
+        return createListSimply(this, {
+            coordDimensions: ['value'],
+            encodeDefaulter: zrUtil.curry(makeSeriesEncodeForNameBased, this)
+        });
     },
 
     _defaultLabelLine: function (option) {
diff --git a/src/chart/helper/createListFromArray.js b/src/chart/helper/createListFromArray.js
index 7587928..2b6cadc 100644
--- a/src/chart/helper/createListFromArray.js
+++ b/src/chart/helper/createListFromArray.js
@@ -24,15 +24,17 @@ import {SOURCE_FORMAT_ORIGINAL} from '../../data/helper/sourceType';
 import {getDimensionTypeByAxis} from '../../data/helper/dimensionHelper';
 import {getDataItemValue} from '../../util/model';
 import CoordinateSystem from '../../CoordinateSystem';
-import {getCoordSysDefineBySeries} from '../../model/referHelper';
+import {getCoordSysInfoBySeries} from '../../model/referHelper';
 import Source from '../../data/Source';
 import {enableDataStack} from '../../data/helper/dataStackHelper';
+import {makeSeriesEncodeForAxisCoordSys} from '../../data/helper/sourceHelper';
 
 /**
  * @param {module:echarts/data/Source|Array} source Or raw data.
  * @param {module:echarts/model/Series} seriesModel
  * @param {Object} [opt]
  * @param {string} [opt.generateCoord]
+ * @param {boolean} [opt.useEncodeDefaulter]
  */
 function createListFromArray(source, seriesModel, opt) {
     opt = opt || {};
@@ -44,14 +46,14 @@ function createListFromArray(source, seriesModel, opt) {
     var coordSysName = seriesModel.get('coordinateSystem');
     var registeredCoordSys = CoordinateSystem.get(coordSysName);
 
-    var coordSysDefine = getCoordSysDefineBySeries(seriesModel);
+    var coordSysInfo = getCoordSysInfoBySeries(seriesModel);
 
     var coordSysDimDefs;
 
-    if (coordSysDefine) {
-        coordSysDimDefs = zrUtil.map(coordSysDefine.coordSysDims, function (dim) {
+    if (coordSysInfo) {
+        coordSysDimDefs = zrUtil.map(coordSysInfo.coordSysDims, function (dim) {
             var dimInfo = {name: dim};
-            var axisModel = coordSysDefine.axisMap.get(dim);
+            var axisModel = coordSysInfo.axisMap.get(dim);
             if (axisModel) {
                 var axisType = axisModel.get('type');
                 dimInfo.type = getDimensionTypeByAxis(axisType);
@@ -72,14 +74,17 @@ function createListFromArray(source, seriesModel, opt) {
 
     var dimInfoList = createDimensions(source, {
         coordDimensions: coordSysDimDefs,
-        generateCoord: opt.generateCoord
+        generateCoord: opt.generateCoord,
+        encodeDefaulter: opt.useEncodeDefaulter
+            ? zrUtil.curry(makeSeriesEncodeForAxisCoordSys, coordSysDimDefs, seriesModel)
+            : null
     });
 
     var firstCategoryDimIndex;
     var hasNameEncode;
-    coordSysDefine && zrUtil.each(dimInfoList, function (dimInfo, dimIndex) {
+    coordSysInfo && zrUtil.each(dimInfoList, function (dimInfo, dimIndex) {
         var coordDim = dimInfo.coordDim;
-        var categoryAxisModel = coordSysDefine.categoryAxisMap.get(coordDim);
+        var categoryAxisModel = coordSysInfo.categoryAxisMap.get(coordDim);
         if (categoryAxisModel) {
             if (firstCategoryDimIndex == null) {
                 firstCategoryDimIndex = dimIndex;
diff --git a/src/chart/helper/whiskerBoxCommon.js b/src/chart/helper/whiskerBoxCommon.js
index 9d8643a..7a9a42a 100644
--- a/src/chart/helper/whiskerBoxCommon.js
+++ b/src/chart/helper/whiskerBoxCommon.js
@@ -21,6 +21,7 @@
 import createListSimply from '../helper/createListSimply';
 import * as zrUtil from 'zrender/src/core/util';
 import {getDimensionTypeByAxis} from '../../data/helper/dimensionHelper';
+import {makeSeriesEncodeForAxisCoordSys} from '../../data/helper/sourceHelper';
 
 export var seriesModelMixin = {
 
@@ -47,7 +48,7 @@ export var seriesModelMixin = {
         var addOrdinal;
 
         // FIXME
-        // 考虑时间轴
+        // Consider time axis.
 
         if (xAxisType === 'category') {
             option.layout = 'horizontal';
@@ -95,25 +96,29 @@ export var seriesModelMixin = {
         }
 
         var defaultValueDimensions = this.defaultValueDimensions;
+        var coordDimensions = [{
+            name: baseAxisDim,
+            type: getDimensionTypeByAxis(baseAxisType),
+            ordinalMeta: ordinalMeta,
+            otherDims: {
+                tooltip: false,
+                itemName: 0
+            },
+            dimsDef: ['base']
+        }, {
+            name: otherAxisDim,
+            type: getDimensionTypeByAxis(otherAxisType),
+            dimsDef: defaultValueDimensions.slice()
+        }];
 
         return createListSimply(
             this,
             {
-                coordDimensions: [{
-                    name: baseAxisDim,
-                    type: getDimensionTypeByAxis(baseAxisType),
-                    ordinalMeta: ordinalMeta,
-                    otherDims: {
-                        tooltip: false,
-                        itemName: 0
-                    },
-                    dimsDef: ['base']
-                }, {
-                    name: otherAxisDim,
-                    type: getDimensionTypeByAxis(otherAxisType),
-                    dimsDef: defaultValueDimensions.slice()
-                }],
-                dimensionsCount: defaultValueDimensions.length + 1
+                coordDimensions: coordDimensions,
+                dimensionsCount: defaultValueDimensions.length + 1,
+                encodeDefaulter: zrUtil.curry(
+                    makeSeriesEncodeForAxisCoordSys, coordDimensions, this
+                )
             }
         );
     },
diff --git a/src/chart/line/LineSeries.js b/src/chart/line/LineSeries.js
index 0441d13..8287364 100644
--- a/src/chart/line/LineSeries.js
+++ b/src/chart/line/LineSeries.js
@@ -34,7 +34,7 @@ export default SeriesModel.extend({
                 throw new Error('Line not support coordinateSystem besides cartesian and polar');
             }
         }
-        return createListFromArray(this.getSource(), this);
+        return createListFromArray(this.getSource(), this, {useEncodeDefaulter: true});
     },
 
     defaultOption: {
diff --git a/src/chart/map/MapSeries.js b/src/chart/map/MapSeries.js
index 3404495..606928b 100644
--- a/src/chart/map/MapSeries.js
+++ b/src/chart/map/MapSeries.js
@@ -24,6 +24,7 @@ import {encodeHTML, addCommas} from '../../util/format';
 import dataSelectableMixin from '../../component/helper/selectableMixin';
 import {retrieveRawAttr} from '../../data/helper/dataProvider';
 import geoSourceManager from '../../coord/geo/geoSourceManager';
+import {makeSeriesEncodeForNameBased} from '../../data/helper/sourceHelper';
 
 var MapSeries = SeriesModel.extend({
 
@@ -46,7 +47,10 @@ var MapSeries = SeriesModel.extend({
     seriesGroup: [],
 
     getInitialData: function (option) {
-        var data = createListSimply(this, ['value']);
+        var data = createListSimply(this, {
+            coordDimensions: ['value'],
+            encodeDefaulter: zrUtil.curry(makeSeriesEncodeForNameBased, this)
+        });
         var valueDim = data.mapDimension('value');
         var dataNameMap = zrUtil.createHashMap();
         var selectTargetList = [];
diff --git a/src/chart/pie/PieSeries.js b/src/chart/pie/PieSeries.js
index 0d05716..d9b040c 100644
--- a/src/chart/pie/PieSeries.js
+++ b/src/chart/pie/PieSeries.js
@@ -24,6 +24,7 @@ import * as modelUtil from '../../util/model';
 import {getPercentWithPrecision} from '../../util/number';
 import dataSelectableMixin from '../../component/helper/selectableMixin';
 import {retrieveRawAttr} from '../../data/helper/dataProvider';
+import {makeSeriesEncodeForNameBased} from '../../data/helper/sourceHelper';
 
 
 var PieSeries = echarts.extendSeriesModel({
@@ -53,7 +54,10 @@ var PieSeries = echarts.extendSeriesModel({
     },
 
     getInitialData: function (option, ecModel) {
-        return createListSimply(this, ['value']);
+        return createListSimply(this, {
+            coordDimensions: ['value'],
+            encodeDefaulter: zrUtil.curry(makeSeriesEncodeForNameBased, this)
+        });
     },
 
     _createSelectableList: function () {
diff --git a/src/chart/scatter/ScatterSeries.js b/src/chart/scatter/ScatterSeries.js
index 395f00a..df1e0d1 100644
--- a/src/chart/scatter/ScatterSeries.js
+++ b/src/chart/scatter/ScatterSeries.js
@@ -27,7 +27,7 @@ export default SeriesModel.extend({
     dependencies: ['grid', 'polar', 'geo', 'singleAxis', 'calendar'],
 
     getInitialData: function (option, ecModel) {
-        return createListFromArray(this.getSource(), this);
+        return createListFromArray(this.getSource(), this, {useEncodeDefaulter: true});
     },
 
     brushSelector: 'point',
diff --git a/src/data/DataDimensionInfo.js b/src/data/DataDimensionInfo.js
new file mode 100644
index 0000000..3bda37d
--- /dev/null
+++ b/src/data/DataDimensionInfo.js
@@ -0,0 +1,135 @@
+/*
+* 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.
+*/
+
+import * as zrUtil from 'zrender/src/core/util';
+
+/**
+ * @class
+ * @param {Object|DataDimensionInfo} [opt] All of the fields will be shallow copied.
+ */
+function DataDimensionInfo(opt) {
+    if (opt != null) {
+        zrUtil.extend(this, opt);
+    }
+
+    /**
+     * Dimension name.
+     * Mandatory.
+     * @type {string}
+     */
+    // this.name;
+
+    /**
+     * The origin name in dimsDef, see source helper.
+     * If displayName given, the tooltip will displayed vertically.
+     * Optional.
+     * @type {string}
+     */
+    // this.displayName;
+
+    /**
+     * Which coordSys dimension this dimension mapped to.
+     * A `coordDim` can be a "coordSysDim" that the coordSys required
+     * (for example, an item in `coordSysDims` of `model/referHelper#CoordSysInfo`),
+     * or an generated "extra coord name" if does not mapped to any "coordSysDim"
+     * (That is determined by whether `isExtraCoord` is `true`).
+     * Mandatory.
+     * @type {string}
+     */
+    // this.coordDim;
+
+    /**
+     * The index of this dimension in `series.encode[coordDim]`.
+     * Mandatory.
+     * @type {number}
+     */
+    // this.coordDimIndex;
+
+    /**
+     * Dimension type. The enumerable values are the key of
+     * `dataCtors` of `data/List`.
+     * Optional.
+     * @type {string}
+     */
+    // this.type;
+
+    /**
+     * This index of this dimension info in `data/List#_dimensionInfos`.
+     * Mandatory after added to `data/List`.
+     * @type {number}
+     */
+    // this.index;
+
+    /**
+     * The format of `otherDims` is:
+     * ```js
+     * {
+     *     tooltip: number optional,
+     *     label: number optional,
+     *     itemName: number optional,
+     *     seriesName: number optional,
+     * }
+     * ```
+     *
+     * A `series.encode` can specified these fields:
+     * ```js
+     * encode: {
+     *     // "3, 1, 5" is the index of data dimension.
+     *     tooltip: [3, 1, 5],
+     *     label: [0, 3],
+     *     ...
+     * }
+     * ```
+     * `otherDims` is the parse result of the `series.encode` above, like:
+     * ```js
+     * // Suppose the index of this data dimension is `3`.
+     * this.otherDims = {
+     *     // `3` is at the index `0` of the `encode.tooltip`
+     *     tooltip: 0,
+     *     // `3` is at the index `1` of the `encode.tooltip`
+     *     label: 1
+     * };
+     * ```
+     *
+     * This prop should never be `null`/`undefined` after initialized.
+     * @type {Object}
+     */
+    this.otherDims = {};
+
+    /**
+     * Be `true` if this dimension is not mapped to any "coordSysDim" that the
+     * "coordSys" required.
+     * Mandatory.
+     * @type {boolean}
+     */
+    // this.isExtraCoord;
+
+    /**
+     * @type {module:data/OrdinalMeta}
+     */
+    // this.ordinalMeta;
+
+    /**
+     * Whether to create inverted indices.
+     * @type {boolean}
+     */
+    // this.createInvertedIndices;
+};
+
+export default DataDimensionInfo;
diff --git a/src/data/List.js b/src/data/List.js
index d98c2b6..7ec46e6 100644
--- a/src/data/List.js
+++ b/src/data/List.js
@@ -31,6 +31,7 @@ import DataDiffer from './DataDiffer';
 import Source from './Source';
 import {defaultDimValueGetters, DefaultDataProvider} from './helper/dataProvider';
 import {summarizeDimensions} from './helper/dimensionHelper';
+import DataDimensionInfo from './DataDimensionInfo';
 
 var isObject = zrUtil.isObject;
 
@@ -102,13 +103,9 @@ function transferProperties(target, source) {
  * @constructor
  * @alias module:echarts/data/List
  *
- * @param {Array.<string|Object>} dimensions
+ * @param {Array.<string|Object|module:data/DataDimensionInfo>} dimensions
  *      For example, ['someDimName', {name: 'someDimName', type: 'someDimType'}, ...].
  *      Dimensions should be concrete names like x, y, z, lng, lat, angle, radius
- *      Spetial fields: {
- *          ordinalMeta: <module:echarts/data/OrdinalMeta>
- *          createInvertedIndices: <boolean>
- *      }
  * @param {module:echarts/model/Model} hostModel
  */
 var List = function (dimensions, hostModel) {
@@ -124,7 +121,10 @@ var List = function (dimensions, hostModel) {
         var dimensionInfo = dimensions[i];
 
         if (zrUtil.isString(dimensionInfo)) {
-            dimensionInfo = {name: dimensionInfo};
+            dimensionInfo = new DataDimensionInfo({name: dimensionInfo});
+        }
+        else if (!(dimensionInfo instanceof DataDimensionInfo)) {
+            dimensionInfo = new DataDimensionInfo(dimensionInfo);
         }
 
         var dimensionName = dimensionInfo.name;
diff --git a/src/data/helper/completeDimensions.js b/src/data/helper/completeDimensions.js
index 7bdddd9..85319bf 100644
--- a/src/data/helper/completeDimensions.js
+++ b/src/data/helper/completeDimensions.js
@@ -24,15 +24,20 @@
 
 import {createHashMap, each, isString, defaults, extend, isObject, clone} from 'zrender/src/core/util';
 import {normalizeToArray} from '../../util/model';
-import {guessOrdinal} from './sourceHelper';
+import {guessOrdinal, BE_ORDINAL} from './sourceHelper';
 import Source from '../Source';
 import {OTHER_DIMENSIONS} from './dimensionHelper';
+import DataDimensionInfo from '../DataDimensionInfo';
 
 /**
  * @see {module:echarts/test/ut/spec/data/completeDimensions}
  *
- * Complete the dimensions array, by user defined `dimension` and `encode`,
- * and guessing from the data structure.
+ * This method builds the relationship between:
+ * + "what the coord sys or series requires (see `sysDims`)",
+ * + "what the user defines (in `encode` and `dimensions`, see `opt.dimsDef` and `opt.encodeDef`)"
+ * + "what the data source provids (see `source`)".
+ *
+ * Some guess strategy will be adapted if user does not define something.
  * If no 'value' dimension specified, the first no-named dimension will be
  * named as 'value'.
  *
@@ -48,32 +53,19 @@ import {OTHER_DIMENSIONS} from './dimensionHelper';
  * @param {Array.<Object|string>} [opt.dimsDef] option.series.dimensions User defined dimensions
  *      For example: ['asdf', {name, type}, ...].
  * @param {Object|HashMap} [opt.encodeDef] option.series.encode {x: 2, y: [3, 1], tooltip: [1, 2], label: 3}
+ * @param {Function} [opt.encodeDefaulter] Called if no `opt.encodeDef` exists.
+ *      If not specified, auto find the next available data dim.
+ *      param {module:data/Source}
+ *      return {Object} encode Never be `null/undefined`.
  * @param {string} [opt.generateCoord] Generate coord dim with the given name.
- *                 If not specified, extra dim names will be:
- *                 'value', 'value0', 'value1', ...
+ *      If not specified, extra dim names will be:
+ *      'value', 'value0', 'value1', ...
  * @param {number} [opt.generateCoordCount] By default, the generated dim name is `generateCoord`.
- *                 If `generateCoordCount` specified, the generated dim names will be:
- *                 `generateCoord` + 0, `generateCoord` + 1, ...
- *                 can be Infinity, indicate that use all of the remain columns.
+ *      If `generateCoordCount` specified, the generated dim names will be:
+ *      `generateCoord` + 0, `generateCoord` + 1, ...
+ *      can be Infinity, indicate that use all of the remain columns.
  * @param {number} [opt.dimCount] If not specified, guess by the first data item.
- * @param {number} [opt.encodeDefaulter] If not specified, auto find the next available data dim.
- * @return {Array.<Object>} [{
- *      name: string mandatory,
- *      displayName: string, the origin name in dimsDef, see source helper.
- *                 If displayName given, the tooltip will displayed vertically.
- *      coordDim: string mandatory,
- *      coordDimIndex: number mandatory,
- *      type: string optional,
- *      otherDims: { never null/undefined
- *          tooltip: number optional,
- *          label: number optional,
- *          itemName: number optional,
- *          seriesName: number optional,
- *      },
- *      isExtraCoord: boolean true if coord is generated
- *          (not specified in encode and not series specified)
- *      other props ...
- * }]
+ * @return {Array.<module:data/DataDimensionInfo>}
  */
 function completeDimensions(sysDims, source, opt) {
     if (!Source.isInstance(source)) {
@@ -83,7 +75,6 @@ function completeDimensions(sysDims, source, opt) {
     opt = opt || {};
     sysDims = (sysDims || []).slice();
     var dimsDef = (opt.dimsDef || []).slice();
-    var encodeDef = createHashMap(opt.encodeDef);
     var dataDimNameMap = createHashMap();
     var coordDimNameMap = createHashMap();
     // var valueCandidate;
@@ -97,7 +88,7 @@ function completeDimensions(sysDims, source, opt) {
             {}, isObject(dimsDef[i]) ? dimsDef[i] : {name: dimsDef[i]}
         );
         var userDimName = dimDefItem.name;
-        var resultItem = result[i] = {otherDims: {}};
+        var resultItem = result[i] = new DataDimensionInfo();
         // Name will be applied later for avoiding duplication.
         if (userDimName != null && dataDimNameMap.get(userDimName) == null) {
             // Only if `series.dimensions` is defined in option
@@ -110,6 +101,12 @@ function completeDimensions(sysDims, source, opt) {
         dimDefItem.displayName != null && (resultItem.displayName = dimDefItem.displayName);
     }
 
+    var encodeDef = opt.encodeDef;
+    if (!encodeDef && opt.encodeDefaulter) {
+        encodeDef = opt.encodeDefaulter(source);
+    }
+    encodeDef = createHashMap(encodeDef);
+
     // Set `coordDim` and `coordDimIndex` by `encodeDef` and normalize `encodeDef`.
     encodeDef.each(function (dataDims, coordDim) {
         dataDims = normalizeToArray(dataDims).slice();
@@ -211,7 +208,7 @@ function completeDimensions(sysDims, source, opt) {
 
     // Set dim `name` and other `coordDim` and other props.
     for (var resultDimIdx = 0; resultDimIdx < dimCount; resultDimIdx++) {
-        var resultItem = result[resultDimIdx] = result[resultDimIdx] || {};
+        var resultItem = result[resultDimIdx] = result[resultDimIdx] || new DataDimensionInfo();
         var coordDim = resultItem.coordDim;
 
         if (coordDim == null) {
@@ -230,7 +227,28 @@ function completeDimensions(sysDims, source, opt) {
             dataDimNameMap
         ));
 
-        if (resultItem.type == null && guessOrdinal(source, resultDimIdx, resultItem.name)) {
+        if (resultItem.type == null
+            && (
+                guessOrdinal(source, resultDimIdx, resultItem.name) === BE_ORDINAL.Must
+                // Consider the case:
+                // {
+                //    dataset: {source: [
+                //        ['2001', 123],
+                //        ['2002', 456],
+                //        ...
+                //        ['The others', 987],
+                //    ]},
+                //    series: {type: 'pie'}
+                // }
+                // The first colum should better be traded as a "ordinal" although it
+                // might not able to be detected as an "ordinal" by `guessOrdinal`.
+                || (resultItem.isExtraCoord
+                    && (resultItem.otherDims.itemName != null
+                        || resultItem.otherDims.seriesName != null
+                    )
+                )
+            )
+        ) {
             resultItem.type = 'ordinal';
         }
     }
diff --git a/src/data/helper/createDimensions.js b/src/data/helper/createDimensions.js
index 29f1363..ec52fd5 100644
--- a/src/data/helper/createDimensions.js
+++ b/src/data/helper/createDimensions.js
@@ -32,6 +32,7 @@ import completeDimensions from './completeDimensions';
  * @param {string} [opt.generateCoordCount]
  * @param {Array.<string|Object>} [opt.dimensionsDefine=source.dimensionsDefine] Overwrite source define.
  * @param {Object|HashMap} [opt.encodeDefine=source.encodeDefine] Overwrite source define.
+ * @param {Function} [opt.encodeDefaulter] Make default encode if user not specified.
  * @return {Array.<Object>} dimensionsInfo
  */
 export default function (source, opt) {
@@ -40,6 +41,7 @@ export default function (source, opt) {
         dimsDef: opt.dimensionsDefine || source.dimensionsDefine,
         encodeDef: opt.encodeDefine || source.encodeDefine,
         dimCount: opt.dimensionsCount,
+        encodeDefaulter: opt.encodeDefaulter,
         generateCoord: opt.generateCoord,
         generateCoordCount: opt.generateCoordCount
     });
diff --git a/src/data/helper/sourceHelper.js b/src/data/helper/sourceHelper.js
index dda5acb..a4be865 100644
--- a/src/data/helper/sourceHelper.js
+++ b/src/data/helper/sourceHelper.js
@@ -19,7 +19,6 @@
 
 import {__DEV__} from '../../config';
 import {makeInner, getDataItemValue} from '../../util/model';
-import {getCoordSysDefineBySeries} from '../../model/referHelper';
 import {
     createHashMap,
     each,
@@ -44,6 +43,12 @@ import {
     SERIES_LAYOUT_BY_ROW
 } from './sourceType';
 
+// The result of `guessOrdinal`.
+export var BE_ORDINAL = {
+    Must: 1, // Encounter string but not '-' and not number-like.
+    Might: 2, // Encounter string but number-like.
+    Not: 3 // Other cases
+};
 
 var inner = makeInner();
 
@@ -178,14 +183,6 @@ export function prepareSource(seriesModel) {
         data, sourceFormat, seriesLayoutBy, sourceHeader, dimensionsDefine
     );
 
-    // Note: dataset option does not have `encode`.
-    var encodeDefine = seriesOption.encode;
-    if (!encodeDefine && datasetModel) {
-        encodeDefine = makeDefaultEncode(
-            seriesModel, datasetModel, data, sourceFormat, seriesLayoutBy, completeResult
-        );
-    }
-
     inner(seriesModel).source = new Source({
         data: data,
         fromDataset: fromDataset,
@@ -194,7 +191,8 @@ export function prepareSource(seriesModel) {
         dimensionsDefine: completeResult.dimensionsDefine,
         startIndex: completeResult.startIndex,
         dimensionsDetectCount: completeResult.dimensionsDetectCount,
-        encodeDefine: encodeDefine
+        // Note: dataset option does not have `encode`.
+        encodeDefine: seriesOption.encode
     });
 }
 
@@ -206,7 +204,6 @@ function completeBySourceData(data, sourceFormat, seriesLayoutBy, sourceHeader,
 
     var dimensionsDetectCount;
     var startIndex;
-    var findPotentialName;
 
     if (sourceFormat === SOURCE_FORMAT_ARRAY_ROWS) {
         // Rule: Most of the first line are string: it is header.
@@ -249,13 +246,11 @@ function completeBySourceData(data, sourceFormat, seriesLayoutBy, sourceHeader,
     else if (sourceFormat === SOURCE_FORMAT_OBJECT_ROWS) {
         if (!dimensionsDefine) {
             dimensionsDefine = objectRowsCollectDimensions(data);
-            findPotentialName = true;
         }
     }
     else if (sourceFormat === SOURCE_FORMAT_KEYED_COLUMNS) {
         if (!dimensionsDefine) {
             dimensionsDefine = [];
-            findPotentialName = true;
             each(data, function (colArr, key) {
                 dimensionsDefine.push(key);
             });
@@ -271,21 +266,10 @@ function completeBySourceData(data, sourceFormat, seriesLayoutBy, sourceHeader,
         }
     }
 
-    var potentialNameDimIndex;
-    if (findPotentialName) {
-        each(dimensionsDefine, function (dim, idx) {
-            if ((isObject(dim) ? dim.name : dim) === 'name') {
-                potentialNameDimIndex = idx;
-            }
-        });
-    }
-
     return {
         startIndex: startIndex,
         dimensionsDefine: normalizeDimensionsDefine(dimensionsDefine),
-        dimensionsDetectCount: dimensionsDetectCount,
-        potentialNameDimIndex: potentialNameDimIndex
-        // TODO: potentialIdDimIdx
+        dimensionsDetectCount: dimensionsDetectCount
     };
 }
 
@@ -359,101 +343,159 @@ function objectRowsCollectDimensions(data) {
     }
 }
 
-// ??? TODO merge to completedimensions, where also has
-// default encode making logic. And the default rule
-// should depends on series? consider 'map'.
-function makeDefaultEncode(
-    seriesModel, datasetModel, data, sourceFormat, seriesLayoutBy, completeResult
-) {
-    var coordSysDefine = getCoordSysDefineBySeries(seriesModel);
+/**
+ * [The strategy of the arrengment of data dimensions for dataset]:
+ * "value way": all axes are non-category axes. So series one by one take
+ *     several (the number is coordSysDims.length) dimensions from dataset.
+ *     The result of data arrengment of data dimensions like:
+ *     | ser0_x | ser0_y | ser1_x | ser1_y | ser2_x | ser2_y |
+ * "category way": at least one axis is category axis. So the the first data
+ *     dimension is always mapped to the first category axis and shared by
+ *     all of the series. The other data dimensions are taken by series like
+ *     "value way" does.
+ *     The result of data arrengment of data dimensions like:
+ *     | ser_shared_x | ser0_y | ser1_y | ser2_y |
+ *
+ * @param {Array.<Object|string>} coordDimensions [{name: <string>, type: <string>, dimsDef: <Array>}, ...]
+ * @param {module:model/Series} seriesModel
+ * @param {module:data/Source} source
+ * @return {Object} encode Never be `null/undefined`.
+ */
+export function makeSeriesEncodeForAxisCoordSys(coordDimensions, seriesModel, source) {
     var encode = {};
-    // var encodeTooltip = [];
-    // var encodeLabel = [];
+
+    var datasetModel = getDatasetModel(seriesModel);
+    // Currently only make default when using dataset, util more reqirements occur.
+    if (!datasetModel || !coordDimensions) {
+        return encode;
+    }
+
     var encodeItemName = [];
     var encodeSeriesName = [];
-    var seriesType = seriesModel.subType;
-
-    // ??? TODO refactor: provide by series itself.
-    // Consider the case: 'map' series is based on geo coordSys,
-    // 'graph', 'heatmap' can be based on cartesian. But can not
-    // give default rule simply here.
-    var nSeriesMap = createHashMap(['pie', 'map', 'funnel']);
-    var cSeriesMap = createHashMap([
-        'line', 'bar', 'pictorialBar', 'scatter', 'effectScatter', 'candlestick', 'boxplot'
-    ]);
-
-    // Usually in this case series will use the first data
-    // dimension as the "value" dimension, or other default
-    // processes respectively.
-    if (coordSysDefine && cSeriesMap.get(seriesType) != null) {
-        var ecModel = seriesModel.ecModel;
-        var datasetMap = inner(ecModel).datasetMap;
-        var key = datasetModel.uid + '_' + seriesLayoutBy;
-        var datasetRecord = datasetMap.get(key)
-            || datasetMap.set(key, {categoryWayDim: 1, valueWayDim: 0});
-
-        // TODO
-        // Auto detect first time axis and do arrangement.
-        each(coordSysDefine.coordSysDims, function (coordDim) {
-            // In value way.
-            if (coordSysDefine.firstCategoryDimIndex == null) {
-                var dataDim = datasetRecord.valueWayDim++;
-                encode[coordDim] = dataDim;
-
-                // ??? TODO give a better default series name rule?
-                // especially when encode x y specified.
-                // consider: when mutiple series share one dimension
-                // category axis, series name should better use
-                // the other dimsion name. On the other hand, use
-                // both dimensions name.
-
-                encodeSeriesName.push(dataDim);
-                // encodeTooltip.push(dataDim);
-                // encodeLabel.push(dataDim);
-            }
-            // In category way, category axis.
-            else if (coordSysDefine.categoryAxisMap.get(coordDim)) {
-                encode[coordDim] = 0;
-                encodeItemName.push(0);
-            }
-            // In category way, non-category axis.
-            else {
-                var dataDim = datasetRecord.categoryWayDim++;
-                encode[coordDim] = dataDim;
-                // encodeTooltip.push(dataDim);
-                // encodeLabel.push(dataDim);
-                encodeSeriesName.push(dataDim);
+
+    var ecModel = seriesModel.ecModel;
+    var datasetMap = inner(ecModel).datasetMap;
+    var key = datasetModel.uid + '_' + source.seriesLayoutBy;
+
+    var baseCategoryDimIndex;
+    var categoryWayValueDimStart;
+    coordDimensions = coordDimensions.slice();
+    each(coordDimensions, function (coordDimInfo, coordDimIdx) {
+        !isObject(coordDimInfo) && (coordDimensions[coordDimIdx] = {name: coordDimInfo});
+        if (coordDimInfo.type === 'ordinal' && baseCategoryDimIndex == null) {
+            baseCategoryDimIndex = coordDimIdx;
+            categoryWayValueDimStart = getDataDimCountOnCoordDim(coordDimensions[coordDimIdx]);
+        }
+        encode[coordDimInfo.name] = [];
+    });
+
+    var datasetRecord = datasetMap.get(key)
+        || datasetMap.set(key, {categoryWayDim: categoryWayValueDimStart, valueWayDim: 0});
+
+    // TODO
+    // Auto detect first time axis and do arrangement.
+    each(coordDimensions, function (coordDimInfo, coordDimIdx) {
+        var coordDimName = coordDimInfo.name;
+        var count = getDataDimCountOnCoordDim(coordDimInfo);
+
+        // In value way.
+        if (baseCategoryDimIndex == null) {
+            var start = datasetRecord.valueWayDim;
+            pushDim(encode[coordDimName], start, count);
+            pushDim(encodeSeriesName, start, count);
+            datasetRecord.valueWayDim += count;
+
+            // ??? TODO give a better default series name rule?
+            // especially when encode x y specified.
+            // consider: when mutiple series share one dimension
+            // category axis, series name should better use
+            // the other dimsion name. On the other hand, use
+            // both dimensions name.
+        }
+        // In category way, the first category axis.
+        else if (baseCategoryDimIndex === coordDimIdx) {
+            pushDim(encode[coordDimName], 0, count);
+            pushDim(encodeItemName, 0, count);
+        }
+        // In category way, the other axis.
+        else {
+            var start = datasetRecord.categoryWayDim;
+            pushDim(encode[coordDimName], start, count);
+            pushDim(encodeSeriesName, start, count);
+            datasetRecord.categoryWayDim += count;
+        }
+    });
+
+    function pushDim(dimIdxArr, idxFrom, idxCount) {
+        for (var i = 0; i < idxCount; i++) {
+            dimIdxArr.push(idxFrom + i);
+        }
+    }
+
+    function getDataDimCountOnCoordDim(coordDimInfo) {
+        var dimsDef = coordDimInfo.dimsDef;
+        return dimsDef ? dimsDef.length : 1;
+    }
+
+    encodeItemName.length && (encode.itemName = encodeItemName);
+    encodeSeriesName.length && (encode.seriesName = encodeSeriesName);
+
+    return encode;
+}
+
+/**
+ * Work for data like [{name: ..., value: ...}, ...].
+ *
+ * @param {module:model/Series} seriesModel
+ * @param {module:data/Source} source
+ * @return {Object} encode Never be `null/undefined`.
+ */
+export function makeSeriesEncodeForNameBased(seriesModel, source) {
+    var encode = {};
+
+    var datasetModel = getDatasetModel(seriesModel);
+    // Currently only make default when using dataset, util more reqirements occur.
+    if (!datasetModel) {
+        return encode;
+    }
+
+    var sourceFormat = source.sourceFormat;
+    var dimensionsDefine = source.dimensionsDefine;
+    var potentialNameDimIndex;
+    if (sourceFormat === SOURCE_FORMAT_OBJECT_ROWS || sourceFormat === SOURCE_FORMAT_KEYED_COLUMNS) {
+        each(dimensionsDefine, function (dim, idx) {
+            if ((isObject(dim) ? dim.name : dim) === 'name') {
+                potentialNameDimIndex = idx;
             }
         });
     }
+
+    var encodeItemName = [];
+    var encodeSeriesName = [];
+
     // Do not make a complex rule! Hard to code maintain and not necessary.
-    // ??? TODO refactor: provide by series itself.
-    // [{name: ..., value: ...}, ...] like:
-    else if (nSeriesMap.get(seriesType) != null) {
-        // Find the first not ordinal. (5 is an experience value)
-        var firstNotOrdinal;
-        for (var i = 0; i < 5 && firstNotOrdinal == null; i++) {
-            if (!doGuessOrdinal(
-                data, sourceFormat, seriesLayoutBy,
-                completeResult.dimensionsDefine, completeResult.startIndex, i
-            )) {
-                firstNotOrdinal = i;
-            }
-        }
-        if (firstNotOrdinal != null) {
-            encode.value = firstNotOrdinal;
-            var nameDimIndex = completeResult.potentialNameDimIndex
-                || Math.max(firstNotOrdinal - 1, 0);
-            // By default, label use itemName in charts.
-            // So we dont set encodeLabel here.
-            encodeSeriesName.push(nameDimIndex);
-            encodeItemName.push(nameDimIndex);
-            // encodeTooltip.push(firstNotOrdinal);
-        }
+    // Find the first not ordinal. (5 is an experience value)
+    var firstNotOrdinal;
+    var firstMaybeOrdinal;
+    for (var i = 0; i < 5 && (firstNotOrdinal == null || firstMaybeOrdinal == null); i++) {
+        doGuessOrdinal(
+            source.data, source.sourceFormat, source.seriesLayoutBy,
+            dimensionsDefine, source.startIndex, i
+        ) === BE_ORDINAL.Not
+            ? (firstNotOrdinal = i)
+            : (firstMaybeOrdinal = i);
+    }
+    if (firstNotOrdinal != null) {
+        encode.value = firstNotOrdinal;
+        var nameDimIndex = potentialNameDimIndex != null
+            ? potentialNameDimIndex
+            : firstMaybeOrdinal;
+        // By default, label use itemName in charts.
+        // So we dont set encodeLabel here.
+        encodeSeriesName.push(nameDimIndex);
+        encodeItemName.push(nameDimIndex);
     }
 
-    // encodeTooltip.length && (encode.tooltip = encodeTooltip);
-    // encodeLabel.length && (encode.label = encodeLabel);
     encodeItemName.length && (encode.itemName = encodeItemName);
     encodeSeriesName.length && (encode.seriesName = encodeSeriesName);
 
@@ -483,7 +525,7 @@ function getDatasetModel(seriesModel) {
  *
  * @param {module:echars/data/Source} source
  * @param {number} dimIndex
- * @return {boolean} Whether ordinal.
+ * @return {BE_ORDINAL} guess result.
  */
 export function guessOrdinal(source, dimIndex) {
     return doGuessOrdinal(
@@ -497,6 +539,7 @@ export function guessOrdinal(source, dimIndex) {
 }
 
 // dimIndex may be overflow source data.
+// return {BE_ORDINAL}
 function doGuessOrdinal(
     data, sourceFormat, seriesLayoutBy, dimensionsDefine, startIndex, dimIndex
 ) {
@@ -505,7 +548,7 @@ function doGuessOrdinal(
     var maxLoop = 5;
 
     if (isTypedArray(data)) {
-        return false;
+        return BE_ORDINAL.Not;
     }
 
     // When sourceType is 'objectRows' or 'keyedColumns', dimensionsDefine
@@ -536,7 +579,7 @@ function doGuessOrdinal(
     }
     else if (sourceFormat === SOURCE_FORMAT_OBJECT_ROWS) {
         if (!dimName) {
-            return;
+            return BE_ORDINAL.Not;
         }
         for (var i = 0; i < data.length && i < maxLoop; i++) {
             var item = data[i];
@@ -547,11 +590,11 @@ function doGuessOrdinal(
     }
     else if (sourceFormat === SOURCE_FORMAT_KEYED_COLUMNS) {
         if (!dimName) {
-            return;
+            return BE_ORDINAL.Not;
         }
         var sample = data[dimName];
         if (!sample || isTypedArray(sample)) {
-            return false;
+            return BE_ORDINAL.Not;
         }
         for (var i = 0; i < sample.length && i < maxLoop; i++) {
             if ((result = detectValue(sample[i])) != null) {
@@ -564,7 +607,7 @@ function doGuessOrdinal(
             var item = data[i];
             var val = getDataItemValue(item);
             if (!isArray(val)) {
-                return false;
+                return BE_ORDINAL.Not;
             }
             if ((result = detectValue(val[dimIndex])) != null) {
                 return result;
@@ -573,15 +616,16 @@ function doGuessOrdinal(
     }
 
     function detectValue(val) {
+        var beStr = isString(val);
         // Consider usage convenience, '1', '2' will be treated as "number".
         // `isFinit('')` get `true`.
         if (val != null && isFinite(val) && val !== '') {
-            return false;
+            return beStr ? BE_ORDINAL.Might : BE_ORDINAL.Not;
         }
-        else if (isString(val) && val !== '-') {
-            return true;
+        else if (beStr && val !== '-') {
+            return BE_ORDINAL.Must;
         }
     }
 
-    return false;
+    return BE_ORDINAL.Not;
 }
diff --git a/src/model/referHelper.js b/src/model/referHelper.js
index f97041a..ec9dc8f 100644
--- a/src/model/referHelper.js
+++ b/src/model/referHelper.js
@@ -30,7 +30,8 @@ import {__DEV__} from '../config';
 import {createHashMap, retrieve, each} from 'zrender/src/core/util';
 
 /**
- * @return {Object} For example:
+ * @class
+ * For example:
  * {
  *     coordSysName: 'cartesian2d',
  *     coordSysDims: ['x', 'y', ...],
@@ -42,19 +43,41 @@ import {createHashMap, retrieve, each} from 'zrender/src/core/util';
  *         x: xAxisModel,
  *         y: undefined
  *     }),
- *     // It also indicate that whether there is category axis.
+ *     // The index of the first category axis in `coordSysDims`.
+ *     // `null/undefined` means no category axis exists.
  *     firstCategoryDimIndex: 1,
  *     // To replace user specified encode.
  * }
  */
-export function getCoordSysDefineBySeries(seriesModel) {
+function CoordSysInfo(coordSysName) {
+    /**
+     * @type {string}
+     */
+    this.coordSysName = coordSysName;
+    /**
+     * @type {Array.<string>}
+     */
+    this.coordSysDims = [];
+    /**
+     * @type {module:zrender/core/util#HashMap}
+     */
+    this.axisMap = createHashMap();
+    /**
+     * @type {module:zrender/core/util#HashMap}
+     */
+    this.categoryAxisMap = createHashMap();
+    /**
+     * @type {number}
+     */
+    this.firstCategoryDimIndex = null;
+}
+
+/**
+ * @return {module:model/referHelper#CoordSysInfo}
+ */
+export function getCoordSysInfoBySeries(seriesModel) {
     var coordSysName = seriesModel.get('coordinateSystem');
-    var result = {
-        coordSysName: coordSysName,
-        coordSysDims: [],
-        axisMap: createHashMap(),
-        categoryAxisMap: createHashMap()
-    };
+    var result = new CoordSysInfo(coordSysName);
     var fetch = fetchers[coordSysName];
     if (fetch) {
         fetch(seriesModel, result, result.axisMap, result.categoryAxisMap);
@@ -95,7 +118,7 @@ var fetchers = {
         }
         if (isCategory(yAxisModel)) {
             categoryAxisMap.set('y', yAxisModel);
-            result.firstCategoryDimIndex = 1;
+            result.firstCategoryDimIndex == null & (result.firstCategoryDimIndex = 1);
         }
     },
 
@@ -141,7 +164,7 @@ var fetchers = {
         }
         if (isCategory(angleAxisModel)) {
             categoryAxisMap.set('angle', angleAxisModel);
-            result.firstCategoryDimIndex = 1;
+            result.firstCategoryDimIndex == null && (result.firstCategoryDimIndex = 1);
         }
     },
 
diff --git a/test/dataset-guess.html b/test/dataset-guess.html
new file mode 100644
index 0000000..b4bec00
--- /dev/null
+++ b/test/dataset-guess.html
@@ -0,0 +1,297 @@
+<!DOCTYPE html>
+<!--
+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.
+-->
+
+
+<html>
+    <head>
+        <meta charset="utf-8">
+        <meta name="viewport" content="width=device-width, initial-scale=1" />
+        <script src="lib/esl.js"></script>
+        <script src="lib/config.js"></script>
+        <script src="lib/jquery.min.js"></script>
+        <script src="lib/facePrint.js"></script>
+        <script src="lib/testHelper.js"></script>
+        <!-- <script src="ut/lib/canteen.js"></script> -->
+        <link rel="stylesheet" href="lib/reset.css" />
+    </head>
+    <body>
+        <style>
+        </style>
+
+
+
+        <div id="main0"></div>
+        <div id="main1"></div>
+        <div id="main2"></div>
+        <div id="main3"></div>
+        <div id="main4"></div>
+        <div id="main5"></div>
+        <div id="main6"></div>
+        <div id="main7"></div>
+        <div id="main8"></div>
+        <div id="main9"></div>
+        <div id="main10"></div>
+
+
+
+
+
+
+
+
+
+        <script>
+        require(['echarts'/*, 'map/js/china' */], function (echarts) {
+            var option;
+
+            option = {
+                legend: {},
+                tooltip: {},
+                dataset: {
+                    source: [
+                        ['分类', '平均消费金额'],
+                        ['a007', 100],
+                        ['008', 100],
+                        ['123', 100],
+                        ['333', 100],
+                        ['444', 100],
+                        ['Test', 100]
+                    ]
+                },
+                series: [
+                    {type: 'pie', radius: '50%'}
+                ]
+            };
+
+            var chart = testHelper.create(echarts, 'main0', {
+                title: [
+                    '6 equal sectors should be rendered with labels'
+                ],
+                option: option,
+                height: 200
+            });
+        });
+        </script>
+
+
+
+
+
+        <script>
+        require(['echarts'/*, 'map/js/china' */], function (echarts) {
+            var option;
+
+            option = {
+                legend: {},
+                tooltip: {},
+                dataset: {
+                    source: [
+                        ['分类', '平均消费金额'],
+                        // number like
+                        ['7', 100],
+                        ['008', 100],
+                        ['123', 100],
+                        ['333', 100],
+                        ['444', 100],
+                        ['Test', 100]
+                    ]
+                },
+                series: [
+                    {type: 'pie', radius: '50%'}
+                ]
+            };
+
+            var chart = testHelper.create(echarts, 'main1', {
+                title: [
+                    '6 equal sectors should be rendered with labels'
+                ],
+                option: option,
+                height: 200
+            });
+        });
+        </script>
+
+
+
+
+        <script>
+        require(['echarts'/*, 'map/js/china' */], function (echarts) {
+            var option;
+
+            option = {
+                legend: {},
+                tooltip: {},
+                dataset: {
+                    source: [
+                        ['分类', '平均消费金额'],
+                        // [value, label]
+                        [100, '7'],
+                        [90, '008'],
+                        [80, '123'],
+                        [70, '333'],
+                        [60, '444'],
+                        [50, 'Test']
+                    ]
+                },
+                series: [
+                    {type: 'funnel', radius: '50%'}
+                ]
+            };
+
+            var chart = testHelper.create(echarts, 'main2', {
+                title: [
+                    '6 bars (decrease) should be rendered with labels'
+                ],
+                option: option,
+                height: 200
+            });
+        });
+        </script>
+
+
+
+
+
+        <script>
+        require(['echarts'/*, 'map/js/china' */], function (echarts) {
+            var option;
+
+            option = {
+                legend: {},
+                tooltip: {},
+                dataset: {
+                    source: [
+                        ['分类', 'V100', 'V200', 'V300'],
+                        // number like
+                        ['7', 100, 200, 300],
+                        ['008', 100, 200, 300],
+                        ['123', 100, 200, 300],
+                        ['333', 100, 200, 300],
+                        ['444', 100, 200, 300],
+                        ['Test', 100, 200, 300]
+                    ]
+                },
+                xAxis: {type: 'category'},
+                yAxis: {},
+                series: [
+                    {type: 'bar'},
+                    {type: 'bar'}
+                ]
+            };
+
+            var chart = testHelper.create(echarts, 'main3', {
+                title: [
+                    'share category xAxis (number-like) and 100, 200 bars'
+                ],
+                option: option,
+                height: 200
+            });
+        });
+        </script>
+
+
+
+
+
+
+
+        <script>
+        require(['echarts'/*, 'map/js/china' */], function (echarts) {
+            var option;
+
+            option = {
+                legend: {},
+                tooltip: {},
+                dataset: {
+                    source: [
+                        ['分类', 'V100', 'V200', 'V300'],
+                        // number like
+                        ['7', 100, 200, 300],
+                        ['008', 100, 200, 300],
+                        ['123', 100, 200, 300],
+                        ['333', 100, 200, 300],
+                        ['444', 100, 200, 300],
+                        ['Test', 100, 200, 300]
+                    ]
+                },
+                xAxis: {},
+                yAxis: {},
+                series: [
+                    {type: 'scatter'},
+                    {type: 'scatter'}
+                ]
+            };
+
+            var chart = testHelper.create(echarts, 'main4', {
+                title: [
+                    'both x y value axis. Should be series0: "分类 V100", series1: "V200 V300" '
+                ],
+                option: option,
+                height: 200
+            });
+        });
+        </script>
+
+
+
+
+
+        <script>
+        require(['echarts'/*, 'map/js/china' */], function (echarts) {
+            var option;
+
+            option = {
+                legend: {},
+                tooltip: {},
+                dataset: {
+                    source: [
+                        ['分类', 'O', 'C', 'L', 'H', 'Column'],
+                        ['7', 190, 250, 50, 490, 500],
+                        ['008', 180, 240, 60, 480, 510],
+                        ['123', 170, 230, 70, 470, 520],
+                        ['333', 160, 220, 80, 460, 530],
+                        ['444', 150, 210, 90, 450, 540],
+                        ['Test', 140, 200, 100, 440, 550]
+                    ]
+                },
+                xAxis: {type: 'category'},
+                yAxis: {},
+                series: [
+                    {type: 'candlestick'},
+                    {type: 'line'},
+                ]
+            };
+
+            var chart = testHelper.create(echarts, 'main5', {
+                title: [
+                    'candlestick series should be "O C L H"',
+                    'line series should be "Column"'
+                ],
+                option: option,
+                height: 300
+            });
+        });
+        </script>
+
+
+
+    </body>
+</html>
+


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@echarts.apache.org
For additional commands, e-mail: commits-help@echarts.apache.org