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 2020/08/18 07:06:05 UTC

[incubator-echarts] branch next updated: feature: enable media query and timeline declared without `baseOption` in echarts option.

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

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


The following commit(s) were added to refs/heads/next by this push:
     new 2deacbd  feature: enable media query and timeline declared without `baseOption` in echarts option.
2deacbd is described below

commit 2deacbd5203701ef836a15e99d8c059df7a4782b
Author: 100pah <su...@gmail.com>
AuthorDate: Tue Aug 18 15:03:16 2020 +0800

    feature: enable media query and timeline declared without `baseOption` in echarts option.
---
 package.json                                    |   1 +
 src/model/OptionManager.ts                      | 130 +++++--
 src/util/types.ts                               |   8 +-
 test/media-pie.html                             | 292 ++++++++--------
 test/ut/spec/model/timelineMediaOptions.test.js | 430 ++++++++++++++++++++++++
 test/ut/spec/model/timelineOptions.test.js      | 178 ----------
 6 files changed, 674 insertions(+), 365 deletions(-)

diff --git a/package.json b/package.json
index 186f1f0..fdfc853 100644
--- a/package.json
+++ b/package.json
@@ -28,6 +28,7 @@
     "test:visual": "node test/runTest/server.js",
     "test:visual:report": "node test/runTest/genReport.js",
     "test": "node build/build.js --prepublish && jest --config test/ut/jest.config.js",
+    "test:single": "jest --config test/ut/jest.config.js --coverage=false -t",
     "mktest": "node test/build/mktest.js",
     "mktest:help": "node test/build/mktest.js -h",
     "lint": "./node_modules/.bin/eslint src/**/*.ts extension-src/**/*.ts",
diff --git a/src/model/OptionManager.ts b/src/model/OptionManager.ts
index b92d5b4..850a29f 100644
--- a/src/model/OptionManager.ts
+++ b/src/model/OptionManager.ts
@@ -235,34 +235,105 @@ class OptionManager {
 
 }
 
+/**
+ * [RAW_OPTION_PATTERNS]
+ * (Note: "series: []" represents all other props in `ECUnitOption`)
+ *
+ * (1) No prop "baseOption" declared:
+ * Root option is used as "baseOption" (except prop "options" and "media").
+ * ```js
+ * option = {
+ *     series: [],
+ *     timeline: {},
+ *     options: [],
+ * };
+ * option = {
+ *     series: [],
+ *     media: {},
+ * };
+ * option = {
+ *     series: [],
+ *     timeline: {},
+ *     options: [],
+ *     media: {},
+ * }
+ * ```
+ *
+ * (2) Prop "baseOption" declared:
+ * If "baseOption" declared, `ECUnitOption` props can only be declared
+ * inside "baseOption" except prop "timeline" (compat ec2).
+ * ```js
+ * option = {
+ *     baseOption: {
+ *         timeline: {},
+ *         series: [],
+ *     },
+ *     options: []
+ * };
+ * option = {
+ *     baseOption: {
+ *         series: [],
+ *     },
+ *     media: []
+ * };
+ * option = {
+ *     baseOption: {
+ *         timeline: {},
+ *         series: [],
+ *     },
+ *     options: []
+ *     media: []
+ * };
+ * option = {
+ *     // ec3 compat ec2: allow (only) `timeline` declared
+ *     // outside baseOption. Keep this setting for compat.
+ *     timeline: {},
+ *     baseOption: {
+ *         series: [],
+ *     },
+ *     options: [],
+ *     media: []
+ * };
+ * ```
+ */
 function parseRawOption(
+    // `rawOption` May be modified
     rawOption: ECOption,
     optionPreprocessorFuncs: OptionPreprocessor[],
     isNew: boolean
 ): ParsedRawOption {
-    let timelineOptions: ECUnitOption[] = [];
     const mediaList: MediaUnit[] = [];
     let mediaDefault: MediaUnit;
     let baseOption: ECUnitOption;
 
-    // Compatible with ec2.
-    const timelineOpt = rawOption.timeline;
+    const declaredBaseOption = rawOption.baseOption;
+    // Compatible with ec2, [RAW_OPTION_PATTERNS] above.
+    const timelineOnRoot = rawOption.timeline;
+    const timelineOptionsOnRoot = rawOption.options;
+    const mediaOnRoot = rawOption.media;
+    const hasMedia = !!rawOption.media;
+    const hasTimeline = !!(
+        timelineOptionsOnRoot || timelineOnRoot || (declaredBaseOption && declaredBaseOption.timeline)
+    );
 
-    if (rawOption.baseOption) {
-        baseOption = rawOption.baseOption;
+    if (declaredBaseOption) {
+        baseOption = declaredBaseOption;
+        // For merge option.
+        if (!baseOption.timeline) {
+            baseOption.timeline = timelineOnRoot;
+        }
     }
-
-    // For timeline
-    if (timelineOpt || rawOption.options) {
-        baseOption = baseOption || {} as ECUnitOption;
-        timelineOptions = (rawOption.options || []).slice();
+    // For convenience, enable to use the root option as the `baseOption`:
+    // `{ ...normalOptionProps, media: [{ ... }, { ... }] }`
+    else {
+        if (hasTimeline || hasMedia) {
+            rawOption.options = rawOption.media = null;
+        }
+        baseOption = rawOption;
     }
 
-    // For media query
-    if (rawOption.media) {
-        baseOption = baseOption || {} as ECUnitOption;
-        const media = rawOption.media;
-        each(media, function (singleMedia) {
+    if (hasMedia) {
+        each(mediaOnRoot, function (singleMedia) {
             if (singleMedia && singleMedia.option) {
                 if (singleMedia.query) {
                     mediaList.push(singleMedia);
@@ -275,32 +346,19 @@ function parseRawOption(
         });
     }
 
-    // For normal option
-    if (!baseOption) {
-        baseOption = rawOption as ECUnitOption;
-    }
+    doPreprocess(baseOption);
+    each(timelineOptionsOnRoot, option => doPreprocess(option));
+    each(mediaList, media => doPreprocess(media.option));
 
-    // Set timelineOpt to baseOption in ec3,
-    // which is convenient for merge option.
-    if (!baseOption.timeline) {
-        baseOption.timeline = timelineOpt;
+    function doPreprocess(option: ECUnitOption) {
+        each(optionPreprocessorFuncs, function (preProcess) {
+            preProcess(option, isNew);
+        });
     }
 
-    // Preprocess.
-    each([baseOption].concat(timelineOptions)
-        .concat(map(mediaList, function (media) {
-            return media.option;
-        })),
-        function (option) {
-            each(optionPreprocessorFuncs, function (preProcess) {
-                preProcess(option, isNew);
-            });
-        }
-    );
-
     return {
         baseOption: baseOption,
-        timelineOptions: timelineOptions,
+        timelineOptions: timelineOptionsOnRoot || [],
         mediaDefault: mediaDefault,
         mediaList: mediaList
     };
diff --git a/src/util/types.ts b/src/util/types.ts
index 814b115..52b4906 100644
--- a/src/util/types.ts
+++ b/src/util/types.ts
@@ -471,10 +471,10 @@ export type ECUnitOption = {
  * ```
  */
 export interface ECOption extends ECUnitOption {
-    baseOption?: ECUnitOption,
-    timeline?: ComponentOption,
-    options?: ECUnitOption[],
-    media?: MediaUnit[],
+    baseOption?: ECUnitOption;
+    timeline?: ComponentOption | ComponentOption[];
+    options?: ECUnitOption[];
+    media?: MediaUnit[];
 };
 
 // series.data or dataset.source
diff --git a/test/media-pie.html b/test/media-pie.html
index 3276a8a..7c74a70 100644
--- a/test/media-pie.html
+++ b/test/media-pie.html
@@ -72,171 +72,169 @@ under the License.
 
 
 
-    option = {
-        baseOption: {
-            title : {
-                text: '南丁格尔玫瑰图',
-                subtext: '纯属虚构',
-                x:'center'
-            },
-            tooltip : {
-                trigger: 'item',
-                formatter: "{a} <br/>{b} : {c} ({d}%)"
-            },
-            legend: {
-                data:['rose1','rose2','rose3','rose4','rose5','rose6','rose7','rose8']
-            },
-            toolbox: {
-                show : true,
-                feature : {
-                    mark : {show: true},
-                    dataView : {show: true, readOnly: false},
-                    magicType : {
-                        show: true,
-                        type: ['pie', 'funnel']
+                option = {
+                    title : {
+                        text: '南丁格尔玫瑰图',
+                        subtext: '纯属虚构',
+                        x:'center'
                     },
-                    restore : {show: true},
-                    saveAsImage : {show: true}
-                }
-            },
-            calculable : true,
-            series : [
-                {
-                    name:'半径模式',
-                    type:'pie',
-                    roseType : 'radius',
-                    label: {
-                        normal: {
-                            show: false
-                        },
-                        emphasis: {
-                            show: true
-                        }
-                    },
-                    lableLine: {
-                        normal: {
-                            show: false
-                        },
-                        emphasis: {
-                            show: true
-                        }
+                    tooltip : {
+                        trigger: 'item',
+                        formatter: "{a} <br/>{b} : {c} ({d}%)"
                     },
-                    data:[
-                        {value:10, name:'rose1'},
-                        {value:5, name:'rose2'},
-                        {value:15, name:'rose3'},
-                        {value:25, name:'rose4'},
-                        {value:20, name:'rose5'},
-                        {value:35, name:'rose6'},
-                        {value:30, name:'rose7'},
-                        {value:40, name:'rose8'}
-                    ]
-                },
-                {
-                    name:'面积模式',
-                    type:'pie',
-                    roseType : 'area',
-                    data:[
-                        {value:10, name:'rose1'},
-                        {value:5, name:'rose2'},
-                        {value:15, name:'rose3'},
-                        {value:25, name:'rose4'},
-                        {value:20, name:'rose5'},
-                        {value:35, name:'rose6'},
-                        {value:30, name:'rose7'},
-                        {value:40, name:'rose8'}
-                    ]
-                }
-            ]
-        },
-        media: [
-            {
-                option: {
                     legend: {
-                        right: 'center',
-                        bottom: 0,
-                        orient: 'horizontal'
+                        data:['rose1','rose2','rose3','rose4','rose5','rose6','rose7','rose8']
                     },
-                    series: [
-                        {
-                            radius: [20, 110],
-                            center: ['25%', 200]
-                        },
-                        {
-                            radius: [30, 110],
-                            center: ['75%', 200]
+                    toolbox: {
+                        show : true,
+                        feature : {
+                            mark : {show: true},
+                            dataView : {show: true, readOnly: false},
+                            magicType : {
+                                show: true,
+                                type: ['pie', 'funnel']
+                            },
+                            restore : {show: true},
+                            saveAsImage : {show: true}
                         }
-                    ]
-                }
-            },
-            {
-                query: {
-                    minAspectRatio: 1
-                },
-                option: {
-                    legend: {
-                        right: 'center',
-                        bottom: 0,
-                        orient: 'horizontal'
                     },
-                    series: [
+                    calculable : true,
+                    series : [
                         {
-                            radius: [20, 110],
-                            center: ['25%', 200]
+                            name:'半径模式',
+                            type:'pie',
+                            roseType : 'radius',
+                            label: {
+                                normal: {
+                                    show: false
+                                },
+                                emphasis: {
+                                    show: true
+                                }
+                            },
+                            lableLine: {
+                                normal: {
+                                    show: false
+                                },
+                                emphasis: {
+                                    show: true
+                                }
+                            },
+                            data:[
+                                {value:10, name:'rose1'},
+                                {value:5, name:'rose2'},
+                                {value:15, name:'rose3'},
+                                {value:25, name:'rose4'},
+                                {value:20, name:'rose5'},
+                                {value:35, name:'rose6'},
+                                {value:30, name:'rose7'},
+                                {value:40, name:'rose8'}
+                            ]
                         },
                         {
-                            radius: [30, 110],
-                            center: ['75%', 200]
+                            name:'面积模式',
+                            type:'pie',
+                            roseType : 'area',
+                            data:[
+                                {value:10, name:'rose1'},
+                                {value:5, name:'rose2'},
+                                {value:15, name:'rose3'},
+                                {value:25, name:'rose4'},
+                                {value:20, name:'rose5'},
+                                {value:35, name:'rose6'},
+                                {value:30, name:'rose7'},
+                                {value:40, name:'rose8'}
+                            ]
                         }
-                    ]
-                }
-            },
-            {
-                query: {
-                    maxAspectRatio: 1
-                },
-                option: {
-                    legend: {
-                        right: 'center',
-                        bottom: 0,
-                        orient: 'horizontal'
-                    },
-                    series: [
+                    ],
+                    media: [
                         {
-                            radius: [20, 110],
-                            center: [200, '30%']
+                            option: {
+                                legend: {
+                                    right: 'center',
+                                    bottom: 0,
+                                    orient: 'horizontal'
+                                },
+                                series: [
+                                    {
+                                        radius: [20, 110],
+                                        center: ['25%', 200]
+                                    },
+                                    {
+                                        radius: [30, 110],
+                                        center: ['75%', 200]
+                                    }
+                                ]
+                            }
                         },
                         {
-                            radius: [30, 110],
-                            center: [200, '70%']
-                        }
-                    ]
-                }
-            },
-            {
-                query: {
-                    maxWidth: 500
-                },
-                option: {
-                    legend: {
-                        right: 10,
-                        top: '15%',
-                        orient: 'vertical'
-                    },
-                    series: [
+                            query: {
+                                minAspectRatio: 1
+                            },
+                            option: {
+                                legend: {
+                                    right: 'center',
+                                    bottom: 0,
+                                    orient: 'horizontal'
+                                },
+                                series: [
+                                    {
+                                        radius: [20, 110],
+                                        center: ['25%', 200]
+                                    },
+                                    {
+                                        radius: [30, 110],
+                                        center: ['75%', 200]
+                                    }
+                                ]
+                            }
+                        },
                         {
-                            radius: [20, 110],
-                            center: [200, '30%']
+                            query: {
+                                maxAspectRatio: 1
+                            },
+                            option: {
+                                legend: {
+                                    right: 'center',
+                                    bottom: 0,
+                                    orient: 'horizontal'
+                                },
+                                series: [
+                                    {
+                                        radius: [20, 110],
+                                        center: [200, '30%']
+                                    },
+                                    {
+                                        radius: [30, 110],
+                                        center: [200, '70%']
+                                    }
+                                ]
+                            }
                         },
                         {
-                            radius: [30, 110],
-                            center: [200, '75%']
+                            query: {
+                                maxWidth: 500
+                            },
+                            option: {
+                                legend: {
+                                    right: 10,
+                                    top: '15%',
+                                    orient: 'vertical'
+                                },
+                                series: [
+                                    {
+                                        radius: [20, 110],
+                                        center: [200, '30%']
+                                    },
+                                    {
+                                        radius: [30, 110],
+                                        center: [200, '75%']
+                                    }
+                                ]
+                            }
                         }
                     ]
-                }
-            }
-        ]
-    };
+                };
 
 
 
diff --git a/test/ut/spec/model/timelineMediaOptions.test.js b/test/ut/spec/model/timelineMediaOptions.test.js
new file mode 100755
index 0000000..07db6bf
--- /dev/null
+++ b/test/ut/spec/model/timelineMediaOptions.test.js
@@ -0,0 +1,430 @@
+
+/*
+* 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.
+*/
+const utHelper = require('../../core/utHelper');
+
+describe('timelineMediaOptions', function () {
+
+    function getData0(chart, seriesIndex) {
+        return getSeries(chart, seriesIndex).getData().get('y', 0);
+    }
+    function getSeries(chart, seriesIndex) {
+        return chart.getModel().getComponent('series', seriesIndex);
+    }
+    function getLegendOption(chart) {
+        return chart.getModel().getComponent('legend', 0).option;
+    }
+    function getTimelineComponent(chart) {
+        return chart.getModel().getComponent('timeline', 0);
+    }
+
+    var chart;
+    beforeEach(function () {
+        chart = utHelper.createChart(10, 10);
+    });
+
+    afterEach(function () {
+        chart.dispose();
+    });
+
+
+
+
+    describe('parse_timeline_media_option', function () {
+
+        it('parse_media_has_baseOption_has_default', function () {
+            var option = {
+                baseOption: {
+                    xAxis: { data: ['a'] },
+                    yAxis: {},
+                    legend: { left: 10 },
+                    series: { name: 'a', type: 'line', data: [11] }
+                },
+                legend: { left: 999, right: 123 }, // Illegal, should be ignored
+                media: [{
+                    query: { maxWidth: 670, minWidth: 550 },
+                    option: {
+                        legend: { left: 50 }
+                    }
+                }, {
+                    option: {
+                        legend: { left: 100 }
+                    }
+                }]
+            };
+            chart.setOption(option);
+            expect(getLegendOption(chart).left).toEqual(100);
+            expect(getLegendOption(chart).right).not.toEqual(123);
+
+            chart.resize({ width: 600 });
+            expect(getLegendOption(chart).left).toEqual(50);
+        });
+
+        it('parse_media_no_baseOption_has_default', function () {
+            var option = {
+                xAxis: { data: ['a'] },
+                yAxis: {},
+                legend: { left: 10 },
+                series: { name: 'a', type: 'line', data: [11] },
+                media: [{
+                    query: { maxWidth: 670, minWidth: 550 },
+                    option: {
+                        legend: { left: 50 }
+                    }
+                }, {
+                    option: {
+                        legend: { left: 100 }
+                    }
+                }]
+            };
+            chart.setOption(option);
+            expect(getLegendOption(chart).left).toEqual(100);
+
+            chart.resize({ width: 600 });
+            expect(getLegendOption(chart).left).toEqual(50);
+        });
+
+        it('parse_media_no_baseOption_no_default', function () {
+            var option = {
+                xAxis: { data: ['a'] },
+                yAxis: {},
+                legend: { left: 10 },
+                series: { name: 'a', type: 'line', data: [11] },
+                media: [{
+                    query: { maxWidth: 670, minWidth: 550 },
+                    option: {
+                        legend: { left: 50 }
+                    }
+                }]
+            };
+            chart.setOption(option);
+            expect(getLegendOption(chart).left).toEqual(10);
+
+            chart.resize({ width: 600 });
+            expect(getLegendOption(chart).left).toEqual(50);
+        });
+
+        it('parse_timeline_media_has_baseOption', function () {
+            var option = {
+                baseOption: {
+                    timeline: { axisType: 'category' },
+                    xAxis: { data: ['a'] },
+                    yAxis: {},
+                    legend: { left: 10 },
+                    series: { name: 'a', type: 'line', data: [11] }
+                },
+                legend: { left: 999, right: 123 }, // Illegal, should be ignored
+                media: [{
+                    query: { maxWidth: 670, minWidth: 550 },
+                    option: {
+                        legend: { left: 50 }
+                    }
+                }, {
+                    option: {
+                        legend: { left: 100 }
+                    }
+                }],
+                options: [
+                    { series: { type: 'line', data: [88] } },
+                    { series: { type: 'line', data: [99] } }
+                ]
+            };
+            chart.setOption(option);
+            expect(getLegendOption(chart).left).toEqual(100);
+            expect(getData0(chart, 0)).toEqual(88);
+            expect(getLegendOption(chart).right).not.toEqual(123);
+            expect(getTimelineComponent(chart) != null).toEqual(true);
+
+            chart.resize({ width: 600 });
+            expect(getData0(chart, 0)).toEqual(88);
+            expect(getLegendOption(chart).left).toEqual(50);
+
+            chart.setOption({ timeline: { currentIndex: 1 } });
+            expect(getData0(chart, 0)).toEqual(99);
+            expect(getLegendOption(chart).left).toEqual(50);
+        });
+
+        it('parse_timeline_media_no_baseOption', function () {
+            var option = {
+                timeline: { axisType: 'category' },
+                xAxis: { data: ['a'] },
+                yAxis: {},
+                legend: { left: 10 },
+                series: { name: 'a', type: 'line', data: [11] },
+                media: [{
+                    query: { maxWidth: 670, minWidth: 550 },
+                    option: {
+                        legend: { left: 50 }
+                    }
+                }, {
+                    option: {
+                        legend: { left: 100 }
+                    }
+                }],
+                options: [
+                    { series: { type: 'line', data: [88] } },
+                    { series: { type: 'line', data: [99] } }
+                ]
+            };
+            chart.setOption(option);
+            expect(getLegendOption(chart).left).toEqual(100);
+            expect(getData0(chart, 0)).toEqual(88);
+            expect(getTimelineComponent(chart) != null).toEqual(true);
+
+            chart.resize({ width: 600 });
+            expect(getData0(chart, 0)).toEqual(88);
+            expect(getLegendOption(chart).left).toEqual(50);
+
+            chart.setOption({ timeline: { currentIndex: 1 } });
+            expect(getData0(chart, 0)).toEqual(99);
+            expect(getLegendOption(chart).left).toEqual(50);
+        });
+
+        it('parse_timeline_has_baseOption', function () {
+            var option = {
+                baseOption: {
+                    timeline: { axisType: 'category' },
+                    xAxis: { data: ['a'] },
+                    yAxis: {},
+                    legend: { },
+                    series: { name: 'a', type: 'line', data: [11] }
+                },
+                legend: { right: 123 }, // Illegal, should be ignored
+                options: [
+                    { series: { type: 'line', data: [88] } },
+                    { series: { type: 'line', data: [99] } }
+                ]
+            };
+            chart.setOption(option);
+            expect(getData0(chart, 0)).toEqual(88);
+            expect(getLegendOption(chart).right).not.toEqual(123);
+            expect(getTimelineComponent(chart) != null).toEqual(true);
+
+            chart.setOption({ timeline: { currentIndex: 1 } });
+            expect(getData0(chart, 0)).toEqual(99);
+        });
+
+        it('parse_timeline_has_baseOption_compat', function () {
+            var option = {
+                timeline: { axisType: 'category' },
+                baseOption: {
+                    xAxis: { data: ['a'] },
+                    yAxis: {},
+                    legend: { },
+                    series: { name: 'a', type: 'line', data: [11] }
+                },
+                legend: { right: 123 }, // Illegal, should be ignored
+                options: [
+                    { series: { type: 'line', data: [88] } },
+                    { series: { type: 'line', data: [99] } }
+                ]
+            };
+            chart.setOption(option);
+            expect(getData0(chart, 0)).toEqual(88);
+            expect(getLegendOption(chart).right).not.toEqual(123);
+            expect(getTimelineComponent(chart) != null).toEqual(true);
+
+            chart.setOption({ timeline: { currentIndex: 1 } });
+            expect(getData0(chart, 0)).toEqual(99);
+        });
+
+        it('parse_timeline_has_baseOption_compat', function () {
+            var option = {
+                timeline: { axisType: 'category' },
+                baseOption: {
+                    xAxis: { data: ['a'] },
+                    yAxis: {},
+                    legend: {},
+                    series: { name: 'a', type: 'line', data: [11] }
+                },
+                legend: { right: 123 }, // Illegal, should be ignored
+                options: [
+                    { series: { type: 'line', data: [88] } },
+                    { series: { type: 'line', data: [99] } }
+                ]
+            };
+            chart.setOption(option);
+            expect(getData0(chart, 0)).toEqual(88);
+            expect(getLegendOption(chart).right).not.toEqual(123);
+            expect(getTimelineComponent(chart) != null).toEqual(true);
+
+            chart.setOption({ timeline: { currentIndex: 1 } });
+            expect(getData0(chart, 0)).toEqual(99);
+        });
+
+        it('parse_timeline_no_baseOption', function () {
+            var option = {
+                timeline: { axisType: 'category' },
+                xAxis: { data: ['a'] },
+                yAxis: {},
+                legend: {},
+                series: { name: 'a', type: 'line', data: [11] },
+                options: [
+                    { series: { type: 'line', data: [88] } },
+                    { series: { type: 'line', data: [99] } }
+                ]
+            };
+            chart.setOption(option);
+            expect(getData0(chart, 0)).toEqual(88);
+            expect(getLegendOption(chart).right).not.toEqual(123);
+            expect(getTimelineComponent(chart) != null).toEqual(true);
+
+            chart.setOption({ timeline: { currentIndex: 1 } });
+            expect(getData0(chart, 0)).toEqual(99);
+        });
+
+
+    });
+
+
+
+
+
+    describe('timeline_onceMore', function () {
+
+        it('timeline_setOptionOnceMore_baseOption', function () {
+            var option = {
+                baseOption: {
+                    timeline: {
+                        axisType: 'category',
+                        autoPlay: false,
+                        playInterval: 1000
+                    },
+                    xAxis: {data: ['a']},
+                    yAxis: {}
+                },
+                options: [{
+                    series: [
+                        { type: 'line', data: [11] },
+                        { type: 'line', data: [22] }
+                    ]
+                }, {
+                    series: [
+                        { type: 'line', data: [111] },
+                        { type: 'line', data: [222] }
+                    ]
+                }]
+            };
+            chart.setOption(option);
+
+            expect(getData0(chart, 0)).toEqual(11);
+            expect(getData0(chart, 1)).toEqual(22);
+
+            chart.setOption({
+                xAxis: {data: ['b']}
+            });
+
+            expect(getData0(chart, 0)).toEqual(11);
+            expect(getData0(chart, 1)).toEqual(22);
+
+            chart.setOption({
+                xAxis: {data: ['c']},
+                timeline: {
+                    currentIndex: 1
+                }
+            });
+
+            expect(getData0(chart, 0)).toEqual(111);
+            expect(getData0(chart, 1)).toEqual(222);
+        });
+
+
+
+        it('timeline_setOptionOnceMore_substitudeTimelineOptions', function () {
+            var option = {
+                baseOption: {
+                    timeline: {
+                        axisType: 'category',
+                        autoPlay: false,
+                        playInterval: 1000,
+                        currentIndex: 2
+                    },
+                    xAxis: {data: ['a']},
+                    yAxis: {}
+                },
+                options: [{
+                    series: [
+                        { type: 'line', data: [11] },
+                        { type: 'line', data: [22] }
+                    ]
+                }, {
+                    series: [
+                        { type: 'line', data: [111] },
+                        { type: 'line', data: [222] }
+                    ]
+                }, {
+                    series: [
+                        { type: 'line', data: [1111] },
+                        { type: 'line', data: [2222] }
+                    ]
+                }]
+            };
+            chart.setOption(option);
+
+            var ecModel = chart.getModel();
+            expect(getData0(chart, 0)).toEqual(1111);
+            expect(getData0(chart, 1)).toEqual(2222);
+
+            chart.setOption({
+                baseOption: {
+                    backgroundColor: '#987654',
+                    xAxis: {data: ['b']}
+                },
+                options: [{
+                    series: [
+                        { type: 'line', data: [55] },
+                        { type: 'line', data: [66] }
+                    ]
+                }, {
+                    series: [
+                        { type: 'line', data: [555] },
+                        { type: 'line', data: [666] }
+                    ]
+                }]
+            });
+
+            var ecModel = chart.getModel();
+            var option = ecModel.getOption();
+            expect(option.backgroundColor).toEqual('#987654');
+            expect(getData0(chart, 0)).toEqual(1111);
+            expect(getData0(chart, 1)).toEqual(2222);
+
+            chart.setOption({
+                timeline: {
+                    currentIndex: 0
+                }
+            });
+
+            expect(getData0(chart, 0)).toEqual(55);
+            expect(getData0(chart, 1)).toEqual(66);
+
+            chart.setOption({
+                timeline: {
+                    currentIndex: 2
+                }
+            });
+
+            // no 1111 2222 any more, replaced totally by new timeline.
+            expect(getData0(chart, 0)).toEqual(55);
+            expect(getData0(chart, 1)).toEqual(66);
+        });
+    });
+
+
+});
diff --git a/test/ut/spec/model/timelineOptions.test.js b/test/ut/spec/model/timelineOptions.test.js
deleted file mode 100755
index b85afab..0000000
--- a/test/ut/spec/model/timelineOptions.test.js
+++ /dev/null
@@ -1,178 +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.
-*/
-const utHelper = require('../../core/utHelper');
-
-describe('timelineOptions', function () {
-    function getData0(chart, seriesIndex) {
-        return getSeries(chart, seriesIndex).getData().get('y', 0);
-    }
-
-    function getSeries(chart, seriesIndex) {
-        return chart.getModel().getComponent('series', seriesIndex);
-    }
-
-    var chart;
-    beforeEach(function () {
-        chart = utHelper.createChart();
-    });
-
-    afterEach(function () {
-        chart.dispose();
-    });
-
-    it('timeline_setOptionOnceMore_baseOption', function () {
-        var option = {
-            baseOption: {
-                timeline: {
-                    axisType: 'category',
-                    autoPlay: false,
-                    playInterval: 1000
-                },
-                xAxis: {data: ['a']},
-                yAxis: {}
-            },
-            options: [
-                {
-                    series: [
-                        {type: 'line', data: [11]},
-                        {type: 'line', data: [22]}
-                    ]
-                },
-                {
-                    series: [
-                        {type: 'line', data: [111]},
-                        {type: 'line', data: [222]}
-                    ]
-                }
-            ]
-        };
-        chart.setOption(option);
-
-        expect(getData0(chart, 0)).toEqual(11);
-        expect(getData0(chart, 1)).toEqual(22);
-
-        chart.setOption({
-            xAxis: {data: ['b']}
-        });
-
-        expect(getData0(chart, 0)).toEqual(11);
-        expect(getData0(chart, 1)).toEqual(22);
-
-        chart.setOption({
-            xAxis: {data: ['c']},
-            timeline: {
-                currentIndex: 1
-            }
-        });
-
-        expect(getData0(chart, 0)).toEqual(111);
-        expect(getData0(chart, 1)).toEqual(222);
-    });
-
-
-
-    it('timeline_setOptionOnceMore_substitudeTimelineOptions', function () {
-        var option = {
-            baseOption: {
-                timeline: {
-                    axisType: 'category',
-                    autoPlay: false,
-                    playInterval: 1000,
-                    currentIndex: 2
-                },
-                xAxis: {data: ['a']},
-                yAxis: {}
-            },
-            options: [
-                {
-                    series: [
-                        {type: 'line', data: [11]},
-                        {type: 'line', data: [22]}
-                    ]
-                },
-                {
-                    series: [
-                        {type: 'line', data: [111]},
-                        {type: 'line', data: [222]}
-                    ]
-                },
-                {
-                    series: [
-                        {type: 'line', data: [1111]},
-                        {type: 'line', data: [2222]}
-                    ]
-                }
-            ]
-        };
-        chart.setOption(option);
-
-        var ecModel = chart.getModel();
-        expect(getData0(chart, 0)).toEqual(1111);
-        expect(getData0(chart, 1)).toEqual(2222);
-
-        chart.setOption({
-            baseOption: {
-                backgroundColor: '#987654',
-                xAxis: {data: ['b']}
-            },
-            options: [
-                {
-                    series: [
-                        {type: 'line', data: [55]},
-                        {type: 'line', data: [66]}
-                    ]
-                },
-                {
-                    series: [
-                        {type: 'line', data: [555]},
-                        {type: 'line', data: [666]}
-                    ]
-                }
-            ]
-        });
-
-        var ecModel = chart.getModel();
-        var option = ecModel.getOption();
-        expect(option.backgroundColor).toEqual('#987654');
-        expect(getData0(chart, 0)).toEqual(1111);
-        expect(getData0(chart, 1)).toEqual(2222);
-
-        chart.setOption({
-            timeline: {
-                currentIndex: 0
-            }
-        });
-
-        expect(getData0(chart, 0)).toEqual(55);
-        expect(getData0(chart, 1)).toEqual(66);
-
-        chart.setOption({
-            timeline: {
-                currentIndex: 2
-            }
-        });
-
-        // no 1111 2222 any more, replaced totally by new timeline.
-        expect(getData0(chart, 0)).toEqual(55);
-        expect(getData0(chart, 1)).toEqual(66);
-
-    });
-
-});


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