You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@echarts.apache.org by sh...@apache.org on 2021/09/05 03:33:16 UTC

[echarts-examples] branch gh-pages updated: WIP: update examples to ts

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

shenyi pushed a commit to branch gh-pages
in repository https://gitbox.apache.org/repos/asf/echarts-examples.git


The following commit(s) were added to refs/heads/gh-pages by this push:
     new 6703ff3  WIP: update examples to ts
6703ff3 is described below

commit 6703ff3fcd8354c6149533f9a62040a3f4127a98
Author: pissang <bm...@gmail.com>
AuthorDate: Sun Sep 5 11:32:21 2021 +0800

    WIP: update examples to ts
---
 public/examples/ts/scatter-matrix.ts               |  62 +-
 public/examples/ts/scatter-nebula.ts               |  78 +++
 public/examples/ts/scatter-nutrients-matrix.ts     | 430 ++++++++++++
 public/examples/ts/scatter-nutrients.ts            | 179 +++++
 public/examples/ts/scatter-painter-choice.ts       |  63 ++
 public/examples/ts/scatter-polar-punchCard.ts      |  67 ++
 .../examples/ts/scatter-polynomial-regression.ts   |  87 +++
 public/examples/ts/scatter-punchCard.ts            |  72 ++
 public/examples/ts/scatter-simple.ts               |  42 ++
 public/examples/ts/scatter-single-axis.ts          |  62 ++
 public/examples/ts/scatter-stream-visual.ts        |  56 ++
 public/examples/ts/scatter-symbol-morph.ts         | 135 ++++
 public/examples/ts/scatter-weibo.ts                | 105 +++
 public/examples/ts/scatter-weight.ts               | 267 ++++++++
 public/examples/ts/sunburst-borderRadius.ts        |  66 ++
 public/examples/ts/sunburst-drink.ts               | 725 +++++++++++++++++++++
 public/examples/ts/sunburst-label-rotate.ts        |  98 +++
 public/examples/ts/sunburst-monochrome.ts          | 178 +++++
 public/examples/ts/sunburst-simple.ts              |  66 ++
 public/examples/ts/sunburst-visualMap.ts           |  95 +++
 public/examples/ts/themeRiver-basic.ts             | 100 +++
 public/examples/ts/themeRiver-lastfm.ts            |  82 +++
 public/examples/ts/tree-basic.ts                   |  60 ++
 public/examples/ts/tree-legend.ts                  | 261 ++++++++
 public/examples/ts/tree-orient-bottom-top.ts       |  61 ++
 public/examples/ts/tree-orient-right-left.ts       |  64 ++
 public/examples/ts/tree-polyline.ts                | 181 +++++
 public/examples/ts/tree-radial.ts                  |  43 ++
 public/examples/ts/tree-vertical.ts                |  56 ++
 public/examples/ts/treemap-disk.ts                 |  80 +++
 public/examples/ts/treemap-drill-down.ts           | 100 +++
 public/examples/ts/treemap-obama.ts                | 225 +++++++
 public/examples/ts/treemap-show-parent.ts          |  94 +++
 public/examples/ts/treemap-simple.ts               |  35 +
 public/examples/ts/treemap-sunburst-transition.ts  |  58 ++
 public/examples/ts/treemap-visual.ts               | 145 +++++
 public/examples/ts/watermark.ts                    | 220 +++++++
 public/examples/ts/wind-barb.ts                    | 269 ++++++++
 public/examples/types/example.d.ts                 |   2 +-
 src/editor/CodeMonaco.vue                          |   2 +-
 40 files changed, 5042 insertions(+), 29 deletions(-)

diff --git a/public/examples/ts/scatter-matrix.ts b/public/examples/ts/scatter-matrix.ts
index f49a383..572edb9 100644
--- a/public/examples/ts/scatter-matrix.ts
+++ b/public/examples/ts/scatter-matrix.ts
@@ -126,36 +126,39 @@ const GRID_HEIGHT = (100 - BASE_TOP - GAP) / CATEGORY_DIM_COUNT - GAP;
 const CATEGORY_DIM = 7;
 const SYMBOL_SIZE = 4;
 
-function retrieveScatterData(data, dimX, dimY) {
-    var result = [];
-    for (var i = 0; i < data.length; i++) {
-        var item = [data[i][dimX], data[i][dimY]];
+function retrieveScatterData(data: (number | string)[][], dimX: number, dimY: number) {
+    let result = [];
+    for (let i = 0; i < data.length; i++) {
+        let item = [data[i][dimX], data[i][dimY]];
         item[CATEGORY_DIM] = data[i][CATEGORY_DIM];
         result.push(item);
     }
     return result;
 }
 
-function generateGrids(option) {
-    var index = 0;
+function generateGrids() {
+    let index = 0;
 
-    for (var i = 0; i < CATEGORY_DIM_COUNT; i++) {
-        for (var j = 0; j < CATEGORY_DIM_COUNT; j++) {
+    const grid: echarts.GridComponentOption[] = [];
+    const xAxis: echarts.XAXisComponentOption[] = [];
+    const yAxis: echarts.YAXisComponentOption[] = [];
+    const series: echarts.SeriesOption[] = [];
+
+
+    for (let i = 0; i < CATEGORY_DIM_COUNT; i++) {
+        for (let j = 0; j < CATEGORY_DIM_COUNT; j++) {
             if (CATEGORY_DIM_COUNT - i + j >= CATEGORY_DIM_COUNT) {
                 continue;
             }
 
-            option.grid.push({
+            grid.push({
                 left: BASE_LEFT + i * (GRID_WIDTH + GAP) + '%',
                 top: BASE_TOP + j * (GRID_HEIGHT + GAP) + '%',
                 width: GRID_WIDTH + '%',
                 height: GRID_HEIGHT + '%'
             });
 
-            option.brush.xAxisIndex && option.brush.xAxisIndex.push(index);
-            option.brush.yAxisIndex && option.brush.yAxisIndex.push(index);
-
-            option.xAxis.push({
+            xAxis.push({
                 splitNumber: 3,
                 position: 'top',
                 axisLine: {
@@ -174,7 +177,7 @@ function generateGrids(option) {
                 scale: true
             });
 
-            option.yAxis.push({
+            yAxis.push({
                 splitNumber: 3,
                 position: 'right',
                 axisLine: {
@@ -193,7 +196,7 @@ function generateGrids(option) {
                 scale: true
             });
 
-            option.series.push({
+            series.push({
                 type: 'scatter',
                 symbolSize: SYMBOL_SIZE,
                 xAxisIndex: index,
@@ -201,20 +204,26 @@ function generateGrids(option) {
                 data: retrieveScatterData(rawData, i, j)
             });
 
-            option.visualMap.seriesIndex.push(option.series.length - 1);
-
             index++;
         }
     }
+
+    return {
+        grid,
+        xAxis,
+        yAxis,
+        series
+    };
 }
 
+const gridOption = generateGrids();
 
-var option = {
+option = {
     animation: false,
     brush: {
         brushLink: 'all',
-        xAxisIndex: [],
-        yAxisIndex: [],
+        xAxisIndex: gridOption.xAxis.map(function (_, idx) { return idx }),
+        yAxisIndex: gridOption.yAxis.map(function (_, idx) { return idx }),
         inBrush: {
             opacity: 1
         }
@@ -232,7 +241,7 @@ var option = {
         outOfRange: {
             color: '#ddd'
         },
-        seriesIndex: [0]
+        seriesIndex: gridOption.series.map(function (_, idx) { return idx })
     },
     tooltip: {
         trigger: 'item'
@@ -280,9 +289,9 @@ var option = {
             }
         }
     },
-    grid: [],
-    xAxis: [],
-    yAxis: [],
+    xAxis: gridOption.xAxis,
+    yAxis: gridOption.yAxis,
+    grid: gridOption.grid,
     series: [
         {
             name: 'parallel',
@@ -293,10 +302,9 @@ var option = {
                 opacity: 0.3
             },
             data: rawData
-        }
+        },
+        ...gridOption.series
     ]
 };
 
-generateGrids(option);
-
 export {}
\ No newline at end of file
diff --git a/public/examples/ts/scatter-nebula.ts b/public/examples/ts/scatter-nebula.ts
new file mode 100644
index 0000000..73a71c5
--- /dev/null
+++ b/public/examples/ts/scatter-nebula.ts
@@ -0,0 +1,78 @@
+/*
+title: Scatter Nebula
+category: scatter
+titleCN: 大规模星云散点图
+difficulty: 5
+*/
+
+
+const dataURL = ROOT_PATH + '/data/asset/data/fake-nebula.bin';
+const xhr = new XMLHttpRequest();
+xhr.open('GET', dataURL, true);
+xhr.responseType = 'arraybuffer';
+
+myChart.showLoading();
+
+xhr.onload = function (e) {
+    myChart.hideLoading();
+    var rawData = new Float32Array(this.response);
+
+    option = {
+        title: {
+            left: 'center',
+            text: echarts.format.addCommas(Math.round(rawData.length / 2)) + ' Points',
+            subtext: 'Fake data'
+        },
+        tooltip: {},
+        toolbox: {
+            right: 20,
+            feature: {
+                dataZoom: {}
+            }
+        },
+        grid: {
+            right: 70,
+            bottom: 70
+        },
+        xAxis: [{
+        }],
+        yAxis: [{
+        }],
+        dataZoom: [{
+            type: 'inside'
+        }, {
+            type: 'slider',
+            showDataShadow: false,
+            handleIcon: 'path://M10.7,11.9v-1.3H9.3v1.3c-4.9,0.3-8.8,4.4-8.8,9.4c0,5,3.9,9.1,8.8,9.4v1.3h1.3v-1.3c4.9-0.3,8.8-4.4,8.8-9.4C19.5,16.3,15.6,12.2,10.7,11.9z M13.3,24.4H6.7V23h6.6V24.4z M13.3,19.6H6.7v-1.4h6.6V19.6z',
+            handleSize: '80%'
+        }, {
+            type: 'inside',
+            orient: 'vertical'
+        }, {
+            type: 'slider',
+            orient: 'vertical',
+            showDataShadow: false,
+            handleIcon: 'path://M10.7,11.9v-1.3H9.3v1.3c-4.9,0.3-8.8,4.4-8.8,9.4c0,5,3.9,9.1,8.8,9.4v1.3h1.3v-1.3c4.9-0.3,8.8-4.4,8.8-9.4C19.5,16.3,15.6,12.2,10.7,11.9z M13.3,24.4H6.7V23h6.6V24.4z M13.3,19.6H6.7v-1.4h6.6V19.6z',
+            handleSize: '80%'
+        }],
+        animation: false,
+        series: [{
+            type: 'scatter',
+            data: rawData,
+            dimensions: ['x', 'y'],
+            symbolSize: 3,
+            itemStyle: {
+                opacity: 0.4
+            },
+            blendMode: 'source-over',
+            large: true,
+            largeThreshold: 500
+        }]
+    };
+
+    myChart.setOption(option);
+};
+
+xhr.send();
+
+export {}
\ No newline at end of file
diff --git a/public/examples/ts/scatter-nutrients-matrix.ts b/public/examples/ts/scatter-nutrients-matrix.ts
new file mode 100644
index 0000000..f7032ab
--- /dev/null
+++ b/public/examples/ts/scatter-nutrients-matrix.ts
@@ -0,0 +1,430 @@
+/*
+title: Scatter Nutrients Matrix
+category: scatter
+titleCN: 营养分布散点矩阵
+difficulty: 7
+*/
+
+const indices = {
+    name: 0,
+    group: 1,
+    id: 16
+};
+const schema = [
+    {name: 'name', index: 0},
+    {name: 'group', index: 1},
+    {name: 'protein', index: 2},
+    {name: 'calcium', index: 3},
+    {name: 'sodium', index: 4},
+    {name: 'fiber', index: 5},
+    {name: 'vitaminc', index: 6},
+    {name: 'potassium', index: 7},
+    {name: 'carbohydrate', index: 8},
+    {name: 'sugars', index: 9},
+    {name: 'fat', index: 10},
+    {name: 'water', index: 11},
+    {name: 'calories', index: 12},
+    {name: 'saturated', index: 13},
+    {name: 'monounsat', index: 14},
+    {name: 'polyunsat', index: 15},
+    {name: 'id', index: 16}
+];
+
+const axisColors: Record<string, string> = {
+    'xAxisLeft': '#2A8339',
+    'xAxisRight': '#367DA6',
+    'yAxisTop': '#A68B36',
+    'yAxisBottom': '#BD5692'
+};
+const colorBySchema: Record<string, string> = {};
+
+const fieldIndices = schema.reduce(function (obj, item) {
+    obj[item.name] = item.index;
+    return obj;
+}, {} as Record<string, number>);
+
+const groupCategories: string[] = [];
+const groupColors: string[] = [];
+let data: (number | string)[][];
+
+// zlevel 为 1 的层开启尾迹特效
+myChart.getZr().configLayer(1, {
+    motionBlur: true
+});
+
+
+function normalizeData(originData: (number | string)[][]) {
+    let groupMap: Record<string, number> = {};
+    originData.forEach(function (row) {
+        let groupName = row[indices.group];
+        if (!groupMap.hasOwnProperty(groupName)) {
+            groupMap[groupName] = 1;
+        }
+    });
+
+    originData.forEach(function (row) {
+        row.forEach(function (item, index) {
+            if (index !== indices.name
+                && index !== indices.group
+                && index !== indices.id
+            ) {
+                // Convert null to zero, as all of them under unit "g".
+                row[index] = parseFloat(item as string) || 0;
+            }
+        });
+    });
+
+    for (let groupName in groupMap) {
+        if (groupMap.hasOwnProperty(groupName)) {
+            groupCategories.push(groupName);
+        }
+    }
+    let hStep = Math.round(300 / (groupCategories.length - 1));
+    for (let i = 0; i < groupCategories.length; i++) {
+        groupColors.push(echarts.color.modifyHSL('#5A94DF', hStep * i));
+    }
+
+    return originData;
+}
+
+type AxisComponentOption = [
+    echarts.XAXisComponentOption,
+    echarts.YAXisComponentOption
+]
+function makeAxis<T extends 0 | 1>(
+    dimIndex: T,
+    id: string,
+    name: string,
+    nameLocation: AxisComponentOption[T]['nameLocation']
+): AxisComponentOption[T] {
+    const axisColor = axisColors[id.split('-')[dimIndex]];
+    colorBySchema[name] = axisColor;
+    return {
+        id: id,
+        name: name,
+        nameLocation: nameLocation,
+        nameGap: nameLocation === 'middle' ? 30 : 10,
+        gridId: id,
+        splitLine: {show: false},
+        axisLine: {
+            lineStyle: {
+                color: axisColor
+            }
+        },
+        axisLabel: {
+            color: axisColor
+        },
+        axisTick: {
+            lineStyle: {
+                color: axisColor
+            }
+        }
+    };
+}
+
+function makeSeriesData(xLeftOrRight: string, yTopOrBottom: string): (number | string)[][] {
+    return data.map(function (item, idx) {
+        const schemaX = app.config[xLeftOrRight] as string;
+        const schemaY = app.config[yTopOrBottom] as string;
+        return [
+            item[fieldIndices[schemaX]], // 0: xValue
+            item[fieldIndices[schemaY]], // 1: yValue
+            item[1],                     // 2: group
+            item[0],                     // 3: name
+            schemaX,                     // 4: schemaX
+            schemaY,                     // 5: schemaY
+            idx                          // 6
+        ];
+    });
+}
+
+function makeSeries(xLeftOrRight: string, yTopOrBottom: string): echarts.ScatterSeriesOption {
+    let id = xLeftOrRight + '-' + yTopOrBottom;
+    return {
+        zlevel: 1,
+        type: 'scatter',
+        name: 'nutrients',
+        xAxisId: id,
+        yAxisId: id,
+        symbolSize: 8,
+        emphasis: {
+            itemStyle: {
+                color: '#fff'
+            },
+        },
+        data: makeSeriesData(xLeftOrRight, yTopOrBottom)
+    };
+}
+
+function makeDataZoom(opt: any) {
+    return Object.assign({
+        type: 'slider',
+        filterMode: 'empty',
+        realtime: false
+    }, opt);
+}
+
+function tooltipFormatter(params: any): string {
+    type MapItem = Record<string, string>
+    // Remove duplicate by data name.
+    let mapByDataName: Record<string, MapItem> = {};
+    let mapOnDim: Record<string, Record<string, MapItem>> = {x: {}, y: {}, xy: {}};
+    params.forEach(function (item: any) {
+        let data = item.data;
+        let dataName = data[3];
+        let mapItem = mapByDataName[dataName] || (mapByDataName[dataName] = {});
+        mapItem[data[4]] = data[0];
+        mapItem[data[5]] = data[1];
+        mapOnDim[item.axisDim][dataName] = mapItem;
+    });
+    Object.keys(mapByDataName).forEach(function (dataName) {
+        if (mapOnDim.x[dataName] && mapOnDim.y[dataName]) {
+            mapOnDim.xy[dataName] = mapByDataName[dataName];
+            delete mapOnDim.x[dataName];
+            delete mapOnDim.y[dataName];
+        }
+    });
+    let resultHTML: string[] = [];
+    [['xy', 'CROSS'], ['x', 'V LINE'], ['y', 'H LINE']].forEach(function (dimDefine) {
+        let html: string[] = [];
+        Object.keys(mapOnDim[dimDefine[0]]).forEach(function (dataName) {
+            let mapItem = mapOnDim[dimDefine[0]][dataName];
+            let valuesHTML: string[] = [];
+            Object.keys(mapItem).forEach(function (dataName) {
+                valuesHTML.push(
+                    '<span style="color:' + colorBySchema[dataName] + '">'
+                        + dataName
+                    + '</span>: ' + mapItem[dataName]
+                );
+            });
+            html.push('<div style="margin: 10px 0">' + dataName + '<br/>' + valuesHTML.join('<br/>') + '</div>');
+        });
+        html.length && resultHTML.push(
+            '<div style="margin: 10px 0">'
+            + '<div style="font-size: 16px; color: #aaa">POINTS ON ' + dimDefine[1] + '</div>'
+            + html.join('')
+            + '</div>'
+        );
+    });
+    return resultHTML.join('');
+}
+
+function getOption(data: (string | number)[][]): echarts.EChartsOption {
+    let gridWidth = '35%';
+    let gridHeight = '35%';
+    let gridLeft = 80;
+    let gridRight = 50;
+    let gridTop = 50;
+    let gridBottom = 80;
+
+    return {
+        tooltip: {
+            trigger: 'none',
+            padding: [10, 20, 10, 20],
+            backgroundColor: 'rgba(0,0,0,0.7)',
+            transitionDuration: 0,
+            extraCssText: 'width: 300px; white-space: normal',
+            textStyle: {
+                color: '#fff',
+                fontSize: 12
+            },
+            position: function (pos, params, el, elRect, size) {
+                let obj: Record<string, number> = {};
+                obj[['left', 'right'][+(pos[0] < size.viewSize[0] / 2)]] = 60;
+                obj[['top', 'bottom'][+(pos[1] < size.viewSize[1] / 2)]] = 20;
+                return obj;
+            },
+            formatter: tooltipFormatter
+        },
+        axisPointer: {
+            show: true,
+            snap: true,
+            lineStyle: {
+                type: 'dashed'
+            },
+            label: {
+                show: true,
+                margin: 6,
+                backgroundColor: '#556',
+                color: '#fff'
+            },
+            link: [{
+                xAxisId: ['xAxisLeft-yAxisTop', 'xAxisLeft-yAxisBottom']
+            }, {
+                xAxisId: ['xAxisRight-yAxisTop', 'xAxisRight-yAxisBottom']
+            }, {
+                yAxisId: ['xAxisLeft-yAxisTop', 'xAxisRight-yAxisTop']
+            }, {
+                yAxisId: ['xAxisLeft-yAxisBottom', 'xAxisRight-yAxisBottom']
+            }]
+        },
+        xAxis: [
+            makeAxis(0, 'xAxisLeft-yAxisTop', 'carbohydrate', 'middle'),
+            makeAxis(0, 'xAxisLeft-yAxisBottom', 'carbohydrate', 'middle'),
+            makeAxis(0, 'xAxisRight-yAxisTop', 'potassium', 'middle'),
+            makeAxis(0, 'xAxisRight-yAxisBottom', 'potassium', 'middle')
+        ],
+        yAxis: [
+            makeAxis(1, 'xAxisLeft-yAxisTop', 'calcium', 'end'),
+            makeAxis(1, 'xAxisLeft-yAxisBottom', 'fiber', 'end'),
+            makeAxis(1, 'xAxisRight-yAxisTop', 'calcium', 'end'),
+            makeAxis(1, 'xAxisRight-yAxisBottom', 'fiber', 'end')
+        ],
+        grid: [{
+            id: 'xAxisLeft-yAxisTop',
+            left: gridLeft,
+            top: gridTop,
+            width: gridWidth,
+            height: gridHeight
+        }, {
+            id: 'xAxisLeft-yAxisBottom',
+            left: gridLeft,
+            bottom: gridBottom,
+            width: gridWidth,
+            height: gridHeight
+        }, {
+            id: 'xAxisRight-yAxisTop',
+            right: gridRight,
+            top: gridTop,
+            width: gridWidth,
+            height: gridHeight
+        }, {
+            id: 'xAxisRight-yAxisBottom',
+            right: gridRight,
+            bottom: gridBottom,
+            width: gridWidth,
+            height: gridHeight
+        }],
+        dataZoom: [
+            makeDataZoom({
+                width: gridWidth,
+                height: 20,
+                left: gridLeft,
+                bottom: 10,
+                xAxisIndex: [0, 1]
+            }),
+            makeDataZoom({
+                width: gridWidth,
+                height: 20,
+                right: gridRight,
+                bottom: 10,
+                xAxisIndex: [2, 3]
+            }),
+            makeDataZoom({
+                orient: 'vertical',
+                width: 20,
+                height: gridHeight,
+                left: 10,
+                top: gridTop,
+                yAxisIndex: [0, 2]
+            }),
+            makeDataZoom({
+                orient: 'vertical',
+                width: 20,
+                height: gridHeight,
+                left: 10,
+                bottom: gridBottom,
+                yAxisIndex: [1, 3]
+            })
+        ],
+        visualMap: [{
+            show: false,
+            type: 'piecewise',
+            categories: groupCategories,
+            dimension: 2,
+            inRange: {
+                color: groupColors //['#d94e5d','#eac736','#50a3ba']
+            },
+            outOfRange: {
+                color: ['#ccc'] //['#d94e5d','#eac736','#50a3ba']
+            },
+            top: 20,
+            textStyle: {
+                color: '#fff'
+            },
+            realtime: false
+        }],
+        series: [
+            makeSeries('xAxisLeft', 'yAxisTop'),
+            makeSeries('xAxisLeft', 'yAxisBottom'),
+            makeSeries('xAxisRight', 'yAxisTop'),
+            makeSeries('xAxisRight', 'yAxisBottom')
+        ],
+        animationThreshold: 5000,
+        progressiveThreshold: 5000,
+        animationEasingUpdate: 'cubicInOut',
+        animationDurationUpdate: 2000
+    };
+}
+
+const fieldNames = schema.map(function (item) {
+    return item.name;
+}).slice(2);
+
+app.config = {
+    xAxisLeft: 'carbohydrate',
+    yAxisTop: 'calcium',
+    xAxisRight: 'potassium',
+    yAxisBottom: 'fiber',
+    onChange: function () {
+        if (data) {
+            colorBySchema[app.config.xAxisLeft as string] = axisColors.xAxisLeft;
+            colorBySchema[app.config.xAxisRight as string] = axisColors.xAxisRight;
+            colorBySchema[app.config.yAxisTop as string] = axisColors.yAxisTop;
+            colorBySchema[app.config.yAxisBottom as string] = axisColors.yAxisBottom;
+
+            myChart.setOption({
+                xAxis: [{
+                    name: app.config.xAxisLeft
+                }, {
+                    name: app.config.xAxisLeft
+                }, {
+                    name: app.config.xAxisRight
+                }, {
+                    name: app.config.xAxisRight
+                }],
+                yAxis: [{
+                    name: app.config.yAxisTop
+                }, {
+                    name: app.config.yAxisBottom
+                }, {
+                    name: app.config.yAxisTop
+                }, {
+                    name: app.config.yAxisBottom
+                }],
+                series: [{
+                    data: makeSeriesData('xAxisLeft', 'yAxisTop')
+                }, {
+                    data: makeSeriesData('xAxisLeft', 'yAxisBottom')
+                }, {
+                    data: makeSeriesData('xAxisRight', 'yAxisTop')
+                }, {
+                    data: makeSeriesData('xAxisRight', 'yAxisBottom')
+                }]
+            });
+        }
+    }
+};
+
+app.configParameters = {
+    xAxisLeft: {
+        options: fieldNames
+    },
+    xAxisRight: {
+        options: fieldNames
+    },
+    yAxisTop: {
+        options: fieldNames
+    },
+    yAxisBottom: {
+        options: fieldNames
+    }
+};
+
+$.get(ROOT_PATH + '/data/asset/data/nutrients.json', function (originData) {
+    data = normalizeData(originData).slice(0, 1000);
+
+    myChart.setOption(option = getOption(data));
+});
+
+export {}
\ No newline at end of file
diff --git a/public/examples/ts/scatter-nutrients.ts b/public/examples/ts/scatter-nutrients.ts
new file mode 100644
index 0000000..651e0ba
--- /dev/null
+++ b/public/examples/ts/scatter-nutrients.ts
@@ -0,0 +1,179 @@
+/*
+title: Scatter Nutrients
+category: scatter
+titleCN: 营养分布散点图
+difficulty: 7
+*/
+
+const indices = {
+    name: 0,
+    group: 1,
+    id: 16
+};
+const schema = [
+    {name: 'name', index: 0},
+    {name: 'group', index: 1},
+    {name: 'protein', index: 2},
+    {name: 'calcium', index: 3},
+    {name: 'sodium', index: 4},
+    {name: 'fiber', index: 5},
+    {name: 'vitaminc', index: 6},
+    {name: 'potassium', index: 7},
+    {name: 'carbohydrate', index: 8},
+    {name: 'sugars', index: 9},
+    {name: 'fat', index: 10},
+    {name: 'water', index: 11},
+    {name: 'calories', index: 12},
+    {name: 'saturated', index: 13},
+    {name: 'monounsat', index: 14},
+    {name: 'polyunsat', index: 15},
+    {name: 'id', index: 16}
+];
+
+const fieldIndices = schema.reduce(function (obj, item) {
+    obj[item.name] = item.index;
+    return obj;
+}, {} as Record<string, number>);
+
+const groupCategories: string[] = [];
+const groupColors: string[] = [];
+let data: (number | string)[][];
+
+// zlevel 为 1 的层开启尾迹特效
+myChart.getZr().configLayer(1, {
+    motionBlur: true
+});
+
+ $.get(ROOT_PATH + '/data/asset/data/nutrients.json', function (originData) {
+    data = normalizeData(originData).slice(0, 1000);
+
+    myChart.setOption(option = getOption(data));
+});
+
+
+function normalizeData(originData: (number | string)[][]) {
+    let groupMap: Record<string, number> = {};
+    originData.forEach(function (row) {
+        let groupName = row[indices.group];
+        if (!groupMap.hasOwnProperty(groupName)) {
+            groupMap[groupName] = 1;
+        }
+    });
+
+    originData.forEach(function (row) {
+        row.forEach(function (item, index) {
+            if (index !== indices.name
+                && index !== indices.group
+                && index !== indices.id
+            ) {
+                // Convert null to zero, as all of them under unit "g".
+                row[index] = parseFloat(item as string) || 0;
+            }
+        });
+    });
+
+    for (let groupName in groupMap) {
+        if (groupMap.hasOwnProperty(groupName)) {
+            groupCategories.push(groupName);
+        }
+    }
+    let hStep = Math.round(300 / (groupCategories.length - 1));
+    for (let i = 0; i < groupCategories.length; i++) {
+        groupColors.push(echarts.color.modifyHSL('#5A94DF', hStep * i));
+    }
+
+    return originData;
+}
+
+function getOption(data: (string | number)[][]): echarts.EChartsOption {
+    return {
+        xAxis: {
+            name: 'protein',
+            splitLine: {show: false},
+        },
+        yAxis: {
+            name: 'calcium',
+            splitLine: {show: false},
+        },
+        visualMap: [{
+            show: false,
+            type: 'piecewise',
+            categories: groupCategories,
+            dimension: 2,
+            inRange: {
+                color: groupColors
+            },
+            outOfRange: {
+                color: ['#ccc']
+            },
+            top: 20,
+            textStyle: {
+                color: '#fff'
+            },
+            realtime: false
+        }, {
+            show: false,
+            dimension: 3,
+            max: 100,
+            inRange: {
+                colorLightness: [0.15, 0.6]
+            }
+        }],
+        series: [
+            {
+                zlevel: 1,
+                name: 'nutrients',
+                type: 'scatter',
+                data: data.map(function (item, idx) {
+                    return [item[2], item[3], item[1], idx];
+                }),
+                animationThreshold: 5000,
+                progressiveThreshold: 5000
+            }
+        ],
+        animationEasingUpdate: 'cubicInOut',
+        animationDurationUpdate: 2000
+    };
+}
+
+let fieldNames = schema.map(function (item) {
+    return item.name;
+}).slice(2);
+
+app.config = {
+    xAxis: 'protein',
+    yAxis: 'calcium',
+    onChange: function () {
+        if (data) {
+            myChart.setOption({
+                xAxis: {
+                    name: app.config.xAxis
+                },
+                yAxis: {
+                    name: app.config.yAxis
+                },
+                series: {
+                    data: data.map(function (item, idx) {
+                        return [
+                            item[fieldIndices[app.config.xAxis as number]],
+                            item[fieldIndices[app.config.yAxis as number]],
+                            item[1],
+                            idx
+                        ];
+                    })
+                }
+            });
+        }
+    }
+};
+
+app.configParameters = {
+    xAxis: {
+        options: fieldNames
+    },
+    yAxis: {
+        options: fieldNames
+    }
+};
+
+export {}
\ No newline at end of file
diff --git a/public/examples/ts/scatter-painter-choice.ts b/public/examples/ts/scatter-painter-choice.ts
new file mode 100644
index 0000000..760292e
--- /dev/null
+++ b/public/examples/ts/scatter-painter-choice.ts
@@ -0,0 +1,63 @@
+/*
+title: Master Painter Color Choices Throughout History
+category: scatter
+titleCN: Master Painter Color Choices Throughout History
+difficulty: 9
+*/
+
+myChart.showLoading();
+
+$.get(ROOT_PATH + '/data/asset/data/masterPainterColorChoice.json', function (json) {
+    myChart.hideLoading();
+
+    var data = json[0].x.map(function (x: number, idx: number) {
+        return [+x, +json[0].y[idx]];
+    });
+
+    myChart.setOption(option = {
+        title: {
+            text: 'Master Painter Color Choices Throughout History',
+            subtext: 'Data From Plot.ly',
+            left: 'right'
+        },
+        xAxis: {
+            type: 'value',
+            splitLine: {
+                show: false
+            },
+            scale: true,
+            splitNumber: 5,
+            max: 'dataMax',
+            axisLabel: {
+                formatter: function (val: number) {
+                    return val + 's';
+                }
+            }
+        },
+        yAxis: {
+            type: 'value',
+            min: 0,
+            max: 360,
+            interval: 60,
+            name: 'Hue',
+            splitLine: {
+                show: false
+            }
+        },
+        series: [{
+            name: 'scatter',
+            type: 'scatter',
+            symbolSize: function (val, param) {
+                return json[0].marker.size[param.dataIndex] / json[0].marker.sizeref;
+            },
+            itemStyle: {
+                color: function (param) {
+                    return json[0].marker.color[param.dataIndex];
+                }
+            },
+            data: data
+        }]
+    });
+});
+
+export {}
\ No newline at end of file
diff --git a/public/examples/ts/scatter-polar-punchCard.ts b/public/examples/ts/scatter-polar-punchCard.ts
new file mode 100644
index 0000000..7e7b769
--- /dev/null
+++ b/public/examples/ts/scatter-polar-punchCard.ts
@@ -0,0 +1,67 @@
+/*
+title: Punch Card of Github
+category: scatter
+titleCN: GitHub 打卡气泡图(极坐标)
+difficulty: 8
+*/
+
+
+const hours = ['12a', '1a', '2a', '3a', '4a', '5a', '6a',
+        '7a', '8a', '9a','10a','11a',
+        '12p', '1p', '2p', '3p', '4p', '5p',
+        '6p', '7p', '8p', '9p', '10p', '11p'];
+const days = ['Saturday', 'Friday', 'Thursday',
+        'Wednesday', 'Tuesday', 'Monday', 'Sunday'];
+
+const data = [[0,0,5],[0,1,1],[0,2,0],[0,3,0],[0,4,0],[0,5,0],[0,6,0],[0,7,0],[0,8,0],[0,9,0],[0,10,0],[0,11,2],[0,12,4],[0,13,1],[0,14,1],[0,15,3],[0,16,4],[0,17,6],[0,18,4],[0,19,4],[0,20,3],[0,21,3],[0,22,2],[0,23,5],[1,0,7],[1,1,0],[1,2,0],[1,3,0],[1,4,0],[1,5,0],[1,6,0],[1,7,0],[1,8,0],[1,9,0],[1,10,5],[1,11,2],[1,12,2],[1,13,6],[1,14,9],[1,15,11],[1,16,6],[1,17,7],[1,18,8],[1,19,12],[1,20,5],[1,21,5],[1,22,7],[1,23,2],[2,0,1],[2,1,1],[2,2,0],[2,3,0],[2,4,0],[2,5,0],[2,6,0],[2,7,0], [...]
+
+option = {
+    title: {
+        text: 'Punch Card of Github'
+    },
+    legend: {
+        data: ['Punch Card'],
+        left: 'right'
+    },
+    polar: {},
+    tooltip: {
+        formatter: function (params: any) {
+            return params.value[2] + ' commits in ' + hours[params.value[1]] + ' of ' + days[params.value[0]];
+        }
+    },
+    angleAxis: {
+        type: 'category',
+        data: hours,
+        boundaryGap: false,
+        splitLine: {
+            show: true
+        },
+        axisLine: {
+            show: false
+        }
+    },
+    radiusAxis: {
+        type: 'category',
+        data: days,
+        axisLine: {
+            show: false
+        },
+        axisLabel: {
+            rotate: 45
+        }
+    },
+    series: [{
+        name: 'Punch Card',
+        type: 'scatter',
+        coordinateSystem: 'polar',
+        symbolSize: function (val) {
+            return val[2] * 2;
+        },
+        data: data,
+        animationDelay: function (idx) {
+            return idx * 5;
+        }
+    }]
+};
+
+export {};
\ No newline at end of file
diff --git a/public/examples/ts/scatter-polynomial-regression.ts b/public/examples/ts/scatter-polynomial-regression.ts
new file mode 100644
index 0000000..7bef0a3
--- /dev/null
+++ b/public/examples/ts/scatter-polynomial-regression.ts
@@ -0,0 +1,87 @@
+/*
+title: Polynomial Regression
+category: scatter
+titleCN: 多项式回归(使用统计插件)
+difficulty: 2
+*/
+
+// See https://github.com/ecomfe/echarts-stat
+echarts.registerTransform(ecStat.transform.regression);
+
+const data = [
+    [96.24, 11.35],
+    [33.09, 85.11],
+    [57.60, 36.61],
+    [36.77, 27.26],
+    [20.10, 6.72],
+    [45.53, 36.37],
+    [110.07, 80.13],
+    [72.05, 20.88],
+    [39.82, 37.15],
+    [48.05, 70.50],
+    [0.85, 2.57],
+    [51.66, 63.70],
+    [61.07, 127.13],
+    [64.54, 33.59],
+    [35.50, 25.01],
+    [226.55, 664.02],
+    [188.60, 175.31],
+    [81.31, 108.68]
+];
+
+option = {
+    dataset: [{
+        source: data
+    }, {
+        transform: {
+            type: 'ecStat:regression',
+            config: { method: 'polynomial', order: 3 }
+        }
+    }],
+    title: {
+        text: '18 companies net profit and main business income (million)',
+        subtext: 'By ecStat.regression',
+        sublink: 'https://github.com/ecomfe/echarts-stat',
+        left: 'center',
+        top: 16
+    },
+    tooltip: {
+        trigger: 'axis',
+        axisPointer: {
+            type: 'cross'
+        }
+    },
+    xAxis: {
+        splitLine: {
+            lineStyle: {
+                type: 'dashed'
+            }
+        },
+        splitNumber: 20
+    },
+    yAxis: {
+        min: -40,
+        splitLine: {
+            lineStyle: {
+                type: 'dashed'
+            }
+        }
+    },
+    series: [{
+        name: 'scatter',
+        type: 'scatter'
+    }, {
+        name: 'line',
+        type: 'line',
+        smooth: true,
+        datasetIndex: 1,
+        symbolSize: 0.1,
+        symbol: 'circle',
+        label: { show: true, fontSize: 16 },
+        labelLayout: { dx: -20 },
+        encode: { label: 2, tooltip: 1 }
+    }]
+};
+
+
+export {}
\ No newline at end of file
diff --git a/public/examples/ts/scatter-punchCard.ts b/public/examples/ts/scatter-punchCard.ts
new file mode 100644
index 0000000..8b84a21
--- /dev/null
+++ b/public/examples/ts/scatter-punchCard.ts
@@ -0,0 +1,72 @@
+/*
+title: Punch Card of Github
+category: scatter
+titleCN: GitHub 打卡气泡图
+difficulty: 3
+*/
+
+
+const hours = ['12a', '1a', '2a', '3a', '4a', '5a', '6a',
+        '7a', '8a', '9a','10a','11a',
+        '12p', '1p', '2p', '3p', '4p', '5p',
+        '6p', '7p', '8p', '9p', '10p', '11p'];
+const days = ['Saturday', 'Friday', 'Thursday',
+        'Wednesday', 'Tuesday', 'Monday', 'Sunday'];
+
+const data = [[0,0,5],[0,1,1],[0,2,0],[0,3,0],[0,4,0],[0,5,0],[0,6,0],[0,7,0],[0,8,0],[0,9,0],[0,10,0],[0,11,2],[0,12,4],[0,13,1],[0,14,1],[0,15,3],[0,16,4],[0,17,6],[0,18,4],[0,19,4],[0,20,3],[0,21,3],[0,22,2],[0,23,5],[1,0,7],[1,1,0],[1,2,0],[1,3,0],[1,4,0],[1,5,0],[1,6,0],[1,7,0],[1,8,0],[1,9,0],[1,10,5],[1,11,2],[1,12,2],[1,13,6],[1,14,9],[1,15,11],[1,16,6],[1,17,7],[1,18,8],[1,19,12],[1,20,5],[1,21,5],[1,22,7],[1,23,2],[2,0,1],[2,1,1],[2,2,0],[2,3,0],[2,4,0],[2,5,0],[2,6,0],[2,7,0], [...]
+    .map(function (item) {
+        return [item[1], item[0], item[2]];
+    });
+
+option = {
+    title: {
+        text: 'Punch Card of Github'
+    },
+    legend: {
+        data: ['Punch Card'],
+        left: 'right'
+    },
+    tooltip: {
+        position: 'top',
+        formatter: function (params: any) {
+            return params.value[2] + ' commits in ' + hours[params.value[0]] + ' of ' + days[params.value[1]];
+        }
+    },
+    grid: {
+        left: 2,
+        bottom: 10,
+        right: 10,
+        containLabel: true
+    },
+    xAxis: {
+        type: 'category',
+        data: hours,
+        boundaryGap: false,
+        splitLine: {
+            show: true
+        },
+        axisLine: {
+            show: false
+        }
+    },
+    yAxis: {
+        type: 'category',
+        data: days,
+        axisLine: {
+            show: false
+        }
+    },
+    series: [{
+        name: 'Punch Card',
+        type: 'scatter',
+        symbolSize: function (val) {
+            return val[2] * 2;
+        },
+        data: data,
+        animationDelay: function (idx) {
+            return idx * 5;
+        }
+    }]
+};
+
+export {};
\ No newline at end of file
diff --git a/public/examples/ts/scatter-simple.ts b/public/examples/ts/scatter-simple.ts
new file mode 100644
index 0000000..d290c80
--- /dev/null
+++ b/public/examples/ts/scatter-simple.ts
@@ -0,0 +1,42 @@
+/*
+title: Basic Scatter Chart
+category: scatter
+titleCN: 基础散点图
+difficulty: 0
+*/
+
+option = {
+    xAxis: {},
+    yAxis: {},
+    series: [{
+        symbolSize: 20,
+        data: [
+            [10.0, 8.04],
+            [8.07, 6.95],
+            [13.0, 7.58],
+            [9.05, 8.81],
+            [11.0, 8.33],
+            [14.0, 7.66],
+            [13.4, 6.81],
+            [10.0, 6.33],
+            [14.0, 8.96],
+            [12.5, 6.82],
+            [9.15, 7.20],
+            [11.5, 7.20],
+            [3.03, 4.23],
+            [12.2, 7.83],
+            [2.02, 4.47],
+            [1.05, 3.33],
+            [4.05, 4.96],
+            [6.03, 7.24],
+            [12.0, 6.26],
+            [12.0, 8.84],
+            [7.08, 5.82],
+            [5.02, 5.68]
+        ],
+        type: 'scatter'
+    }]
+};
+
+
+export {}
\ No newline at end of file
diff --git a/public/examples/ts/scatter-single-axis.ts b/public/examples/ts/scatter-single-axis.ts
new file mode 100644
index 0000000..14df396
--- /dev/null
+++ b/public/examples/ts/scatter-single-axis.ts
@@ -0,0 +1,62 @@
+/*
+title: Scatter on Single Axis
+category: scatter
+titleCN: 单轴散点图
+difficulty: 3
+*/
+
+const hours = ['12a', '1a', '2a', '3a', '4a', '5a', '6a',
+        '7a', '8a', '9a','10a','11a',
+        '12p', '1p', '2p', '3p', '4p', '5p',
+        '6p', '7p', '8p', '9p', '10p', '11p'];
+const days = ['Saturday', 'Friday', 'Thursday',
+        'Wednesday', 'Tuesday', 'Monday', 'Sunday'];
+
+const data = [[0,0,5],[0,1,1],[0,2,0],[0,3,0],[0,4,0],[0,5,0],[0,6,0],[0,7,0],[0,8,0],[0,9,0],[0,10,0],[0,11,2],[0,12,4],[0,13,1],[0,14,1],[0,15,3],[0,16,4],[0,17,6],[0,18,4],[0,19,4],[0,20,3],[0,21,3],[0,22,2],[0,23,5],[1,0,7],[1,1,0],[1,2,0],[1,3,0],[1,4,0],[1,5,0],[1,6,0],[1,7,0],[1,8,0],[1,9,0],[1,10,5],[1,11,2],[1,12,2],[1,13,6],[1,14,9],[1,15,11],[1,16,6],[1,17,7],[1,18,8],[1,19,12],[1,20,5],[1,21,5],[1,22,7],[1,23,2],[2,0,1],[2,1,1],[2,2,0],[2,3,0],[2,4,0],[2,5,0],[2,6,0],[2,7,0], [...]
+
+const title: echarts.TitleComponentOption[] = [];
+const singleAxis: echarts.SingleAxisComponentOption[] = [];
+const series: echarts.ScatterSeriesOption[] = [];
+
+days.forEach(function (day, idx) {
+    title.push({
+        textBaseline: 'middle',
+        top: (idx + 0.5) * 100 / 7 + '%',
+        text: day
+    });
+    singleAxis.push({
+        left: 150,
+        type: 'category',
+        boundaryGap: false,
+        data: hours,
+        top: (idx * 100 / 7 + 5) + '%',
+        height: (100 / 7 - 10) + '%',
+        axisLabel: {
+            interval: 2
+        }
+    });
+    series.push({
+        singleAxisIndex: idx,
+        coordinateSystem: 'singleAxis',
+        type: 'scatter',
+        data: [],
+        symbolSize: function (dataItem) {
+            return dataItem[1] * 4;
+        }
+    });
+});
+
+data.forEach(function (dataItem) {
+    (series as any)[dataItem[0]].data.push([dataItem[1], dataItem[2]]);
+});
+
+option = {
+    tooltip: {
+        position: 'top'
+    },
+    title: title,
+    singleAxis: singleAxis,
+    series: series
+};
+
+export {};
\ No newline at end of file
diff --git a/public/examples/ts/scatter-stream-visual.ts b/public/examples/ts/scatter-stream-visual.ts
new file mode 100644
index 0000000..afb9a2a
--- /dev/null
+++ b/public/examples/ts/scatter-stream-visual.ts
@@ -0,0 +1,56 @@
+/*
+title: Visual interaction with stream
+category: scatter
+titleCN: 流式渲染和视觉映射操作
+difficulty: 5
+*/
+
+// Thanks to: 若怀冰
+// http://gallery.echartsjs.com/explore.html?u=bd-16906679
+// http://gallery.echartsjs.com/editor.html?c=xHJw-hVqjW
+
+$.getJSON(ROOT_PATH + '/data/asset/data/house-price-area2.json', function (data) {
+
+    var option = {
+        title: {
+            text: 'Dispersion of house price based on the area',
+            left: 'center',
+            top: 0
+        },
+        visualMap: {
+            min: 15202,
+            max: 159980,
+            dimension: 1,
+            orient: 'vertical',
+            right: 10,
+            top: 'center',
+            text: ['HIGH', 'LOW'],
+            calculable: true,
+            inRange: {
+                color: ['#f2c31a', '#24b7f2']
+            }
+        },
+        tooltip: {
+            trigger: 'item',
+            axisPointer: {
+                type: 'cross'
+            }
+        },
+        xAxis: [{
+            type: 'value'
+        }],
+        yAxis: [{
+            type: 'value'
+        }],
+        series: [{
+            name: 'price-area',
+            type: 'scatter',
+            symbolSize: 5,
+            data: data
+        }]
+    };
+
+    myChart.setOption(option);
+});
+
+export {}
\ No newline at end of file
diff --git a/public/examples/ts/scatter-symbol-morph.ts b/public/examples/ts/scatter-symbol-morph.ts
new file mode 100644
index 0000000..63e2a10
--- /dev/null
+++ b/public/examples/ts/scatter-symbol-morph.ts
@@ -0,0 +1,135 @@
+/*
+title: Symbol Shape Morph
+category: scatter
+titleCN: 散点图变形动画
+difficulty: 4
+videoStart: 1000
+videoEnd: 8000
+*/
+
+let xData = [];
+let yData = [];
+let data = [];
+for (let y = 0; y < 10; y++) {
+    yData.push(y);
+    for (let x = 0; x < 10; x++) {
+        data.push([
+            x, y, 10
+        ]);
+    }
+}
+for (let x = 0; x < 10; x++) {
+    xData.push(x);
+}
+
+const options: echarts.EChartsOption[] = [{
+    grid: {
+        left: 0,
+        right: 0,
+        top: 0,
+        bottom: 0
+    },
+    xAxis: {
+        show: false,
+        type: 'category',
+        data: xData
+    },
+    yAxis: {
+        show: false,
+        type: 'category',
+        data: yData
+    },
+    series: [
+        {
+            type: 'scatter',
+            data: data,
+            symbol: 'roundRect',
+            symbolKeepAspect: true,
+            universalTransition: true,
+            symbolSize: 50
+        }
+    ]
+},
+{
+    series: [{
+        type: 'scatter',
+        symbol: 'circle'
+    }]
+},
+
+
+{
+    // heart
+    series: [{
+        symbol: 'path://M23.6 2c-3.363 0-6.258 2.736-7.599 5.594-1.342-2.858-4.237-5.594-7.601-5.594-4.637 0-8.4 3.764-8.4 8.401 0 9.433 9.516 11.906 16.001 21.232 6.13-9.268 15.999-12.1 15.999-21.232 0-4.637-3.763-8.401-8.4-8.401z',
+    }]
+},
+
+{
+    // happy
+    series: [{
+        symbol: 'path://M16 0c-8.837 0-16 7.163-16 16s7.163 16 16 16 16-7.163 16-16-7.163-16-16-16zM22 8c1.105 0 2 1.343 2 3s-0.895 3-2 3-2-1.343-2-3 0.895-3 2-3zM10 8c1.105 0 2 1.343 2 3s-0.895 3-2 3-2-1.343-2-3 0.895-3 2-3zM16 28c-5.215 0-9.544-4.371-10-9.947 2.93 1.691 6.377 2.658 10 2.658s7.070-0.963 10-2.654c-0.455 5.576-4.785 9.942-10 9.942z',
+    }]
+},
+
+{
+    // evil
+    series: [{
+        symbol: 'path://M32 2c0-1.422-0.298-2.775-0.833-4-1.049 2.401-3.014 4.31-5.453 5.287-2.694-2.061-6.061-3.287-9.714-3.287s-7.021 1.226-9.714 3.287c-2.439-0.976-4.404-2.886-5.453-5.287-0.535 1.225-0.833 2.578-0.833 4 0 2.299 0.777 4.417 2.081 6.106-1.324 2.329-2.081 5.023-2.081 7.894 0 8.837 7.163 16 16 16s16-7.163 16-16c0-2.871-0.757-5.565-2.081-7.894 1.304-1.689 2.081-3.806 2.081-6.106zM18.003 11.891c0.064-1.483 1.413-2.467 2.55-3.036 1.086-0.543 2.16-0.814 2.205-0.826 0.536-0.13 [...]
+    }]
+},
+
+{
+    // hipster
+    series: [{
+        symbol: 'path://M16 0c-8.837 0-16 7.163-16 16s7.163 16 16 16 16-7.163 16-16-7.163-16-16-16zM22 8c1.105 0 2 0.895 2 2s-0.895 2-2 2-2-0.895-2-2 0.895-2 2-2zM10 8c1.105 0 2 0.895 2 2s-0.895 2-2 2-2-0.895-2-2 0.895-2 2-2zM16.994 21.23c-0.039-0.035-0.078-0.072-0.115-0.109-0.586-0.586-0.878-1.353-0.879-2.121-0 0.768-0.293 1.535-0.879 2.121-0.038 0.038-0.076 0.074-0.115 0.109-2.704 2.453-9.006-0.058-9.006-3.23 1.938 1.25 3.452 0.306 4.879-1.121 1.172-1.172 3.071-1.172 4.243 0 0.586 0.58 [...]
+    }]
+},
+
+{
+    // shocked
+    series: [{
+        symbol: 'path://M16 0c-8.837 0-16 7.163-16 16s7.163 16 16 16 16-7.163 16-16-7.163-16-16-16zM10 14c-1.105 0-2-1.343-2-3s0.895-3 2-3 2 1.343 2 3-0.895 3-2 3zM16 26c-2.209 0-4-1.791-4-4s1.791-4 4-4c2.209 0 4 1.791 4 4s-1.791 4-4 4zM22 14c-1.105 0-2-1.343-2-3s0.895-3 2-3 2 1.343 2 3-0.895 3-2 3z',
+    }]
+},
+
+{
+    // pie chart
+    series: [{
+        symbol: 'path://M14 18v-14c-7.732 0-14 6.268-14 14s6.268 14 14 14 14-6.268 14-14c0-2.251-0.532-4.378-1.476-6.262l-12.524 6.262zM28.524 7.738c-2.299-4.588-7.043-7.738-12.524-7.738v14l12.524-6.262z'
+    }]
+},
+
+{
+    // users
+    series: [{
+        symbol: 'path://M10.225 24.854c1.728-1.13 3.877-1.989 6.243-2.513-0.47-0.556-0.897-1.176-1.265-1.844-0.95-1.726-1.453-3.627-1.453-5.497 0-2.689 0-5.228 0.956-7.305 0.928-2.016 2.598-3.265 4.976-3.734-0.529-2.39-1.936-3.961-5.682-3.961-6 0-6 4.029-6 9 0 3.096 1.797 6.191 4 7.432v1.649c-6.784 0.555-12 3.888-12 7.918h8.719c0.454-0.403 0.956-0.787 1.506-1.146zM24 24.082v-1.649c2.203-1.241 4-4.337 4-7.432 0-4.971 0-9-6-9s-6 4.029-6 9c0 3.096 1.797 6.191 4 7.432v1.649c-6.784 0.555-12 3 [...]
+    }]
+},
+
+{
+    // mug
+    series: [{
+        symbol: 'path://M30 10h-6v-3c0-2.761-5.373-5-12-5s-12 2.239-12 5v20c0 2.761 5.373 5 12 5s12-2.239 12-5v-3h6c1.105 0 2-0.895 2-2v-10c0-1.105-0.895-2-2-2zM5.502 8.075c-1.156-0.381-1.857-0.789-2.232-1.075 0.375-0.286 1.075-0.694 2.232-1.075 1.811-0.597 4.118-0.925 6.498-0.925s4.688 0.329 6.498 0.925c1.156 0.381 1.857 0.789 2.232 1.075-0.375 0.286-1.076 0.694-2.232 1.075-1.811 0.597-4.118 0.925-6.498 0.925s-4.688-0.329-6.498-0.925zM28 20h-4v-6h4v6z'
+    }]
+},
+
+{
+    // plane
+    series: [{
+        symbol: 'path://M24 19.999l-5.713-5.713 13.713-10.286-4-4-17.141 6.858-5.397-5.397c-1.556-1.556-3.728-1.928-4.828-0.828s-0.727 3.273 0.828 4.828l5.396 5.396-6.858 17.143 4 4 10.287-13.715 5.713 5.713v7.999h4l2-6 6-2v-4l-7.999 0z'
+    }]
+}
+
+];
+
+
+let optionIndex = 0;
+option = options[optionIndex];
+
+setInterval(function () {
+    optionIndex = (optionIndex + 1) % options.length;
+    myChart.setOption(options[optionIndex]);
+}, 700);
+
+export {};
\ No newline at end of file
diff --git a/public/examples/ts/scatter-weibo.ts b/public/examples/ts/scatter-weibo.ts
new file mode 100644
index 0000000..dfdcf58
--- /dev/null
+++ b/public/examples/ts/scatter-weibo.ts
@@ -0,0 +1,105 @@
+/*
+title: Sign in of weibo
+category: scatter
+titleCN: 微博签到数据点亮中国
+*/
+
+myChart.showLoading();
+
+$.get(ROOT_PATH + '/data/asset/data/weibo.json', function (weiboData: number[][]) {
+    myChart.hideLoading();
+
+    const newWeiboData = weiboData.map(function (serieData, idx: number) {
+        let px = serieData[0] / 1000;
+        let py = serieData[1] / 1000;
+        let res: number[][] = [[px, py]];
+
+        for (let i = 2; i < serieData.length; i += 2) {
+            let dx = serieData[i] / 1000;
+            let dy = serieData[i + 1] / 1000;
+            let x = px + dx;
+            let y = py + dy;
+            res.push([+x.toFixed(2), +y.toFixed(2), 1]);
+
+            px = x;
+            py = y;
+        }
+        return res;
+    });
+    myChart.setOption(option = {
+        backgroundColor: '#404a59',
+        title: {
+            text: '微博签到数据点亮中国',
+            subtext: 'From ThinkGIS',
+            sublink: 'http://www.thinkgis.cn/public/sina',
+            left: 'center',
+            top: 'top',
+            textStyle: {
+                color: '#fff'
+            }
+        },
+        tooltip: {},
+        legend: {
+            left: 'left',
+            data: ['强', '中', '弱'],
+            textStyle: {
+                color: '#ccc'
+            }
+        },
+        geo: {
+            map: 'china',
+            roam: true,
+            emphasis: {
+                label: {
+                    show: false
+                },
+                itemStyle: {
+                    areaColor: '#2a333d'
+                }
+            },
+            itemStyle: {
+                areaColor: '#323c48',
+                borderColor: '#111'
+            }
+        },
+        series: [{
+            name: '弱',
+            type: 'scatter',
+            coordinateSystem: 'geo',
+            symbolSize: 1,
+            large: true,
+            itemStyle: {
+                shadowBlur: 2,
+                shadowColor: 'rgba(37, 140, 249, 0.8)',
+                color: 'rgba(37, 140, 249, 0.8)'
+            },
+            data: newWeiboData[0]
+        }, {
+            name: '中',
+            type: 'scatter',
+            coordinateSystem: 'geo',
+            symbolSize: 1,
+            large: true,
+            itemStyle: {
+                shadowBlur: 2,
+                shadowColor: 'rgba(14, 241, 242, 0.8)',
+                color: 'rgba(14, 241, 242, 0.8)'
+            },
+            data: newWeiboData[1]
+        }, {
+            name: '强',
+            type: 'scatter',
+            coordinateSystem: 'geo',
+            symbolSize: 1,
+            large: true,
+            itemStyle: {
+                shadowBlur: 2,
+                shadowColor: 'rgba(255, 255, 255, 0.8)',
+                color: 'rgba(255, 255, 255, 0.8)'
+            },
+            data: newWeiboData[2]
+        }]
+    });
+});
+
+export {}
\ No newline at end of file
diff --git a/public/examples/ts/scatter-weight.ts b/public/examples/ts/scatter-weight.ts
new file mode 100644
index 0000000..599a792
--- /dev/null
+++ b/public/examples/ts/scatter-weight.ts
@@ -0,0 +1,267 @@
+/*
+title: Distribution of Height and Weight
+category: scatter
+titleCN: 男性女性身高体重分布
+difficulty: 3
+*/
+
+option = {
+    title: {
+        text: 'Male and female height and weight distribution',
+        subtext: 'Data from: Heinz 2003'
+    },
+    grid: {
+        left: '3%',
+        right: '7%',
+        bottom: '7%',
+        containLabel: true
+    },
+    tooltip: {
+        // trigger: 'axis',
+        showDelay: 0,
+        formatter: function (params: any) {
+            if (params.value.length > 1) {
+                return params.seriesName + ' :<br/>'
+                + params.value[0] + 'cm '
+                + params.value[1] + 'kg ';
+            }
+            else {
+                return params.seriesName + ' :<br/>'
+                + params.name + ' : '
+                + params.value + 'kg ';
+            }
+        },
+        axisPointer: {
+            show: true,
+            type: 'cross',
+            lineStyle: {
+                type: 'dashed',
+                width: 1
+            }
+        }
+    },
+    toolbox: {
+        feature: {
+            dataZoom: {},
+            brush: {
+                type: ['rect', 'polygon', 'clear']
+            }
+        }
+    },
+    brush: {
+    },
+    legend: {
+        data: ['Female', 'Male'],
+        left: 'center',
+        bottom: 10
+    },
+    xAxis: [
+        {
+            type: 'value',
+            scale: true,
+            axisLabel: {
+                formatter: '{value} cm'
+            },
+            splitLine: {
+                show: false
+            }
+        }
+    ],
+    yAxis: [
+        {
+            type: 'value',
+            scale: true,
+            axisLabel: {
+                formatter: '{value} kg'
+            },
+            splitLine: {
+                show: false
+            }
+        }
+    ],
+    series: [
+        {
+            name: 'Female',
+            type: 'scatter',
+            emphasis: {
+                focus: 'series'
+            },
+            data: [[161.2, 51.6], [167.5, 59.0], [159.5, 49.2], [157.0, 63.0], [155.8, 53.6],
+                [170.0, 59.0], [159.1, 47.6], [166.0, 69.8], [176.2, 66.8], [160.2, 75.2],
+                [172.5, 55.2], [170.9, 54.2], [172.9, 62.5], [153.4, 42.0], [160.0, 50.0],
+                [147.2, 49.8], [168.2, 49.2], [175.0, 73.2], [157.0, 47.8], [167.6, 68.8],
+                [159.5, 50.6], [175.0, 82.5], [166.8, 57.2], [176.5, 87.8], [170.2, 72.8],
+                [174.0, 54.5], [173.0, 59.8], [179.9, 67.3], [170.5, 67.8], [160.0, 47.0],
+                [154.4, 46.2], [162.0, 55.0], [176.5, 83.0], [160.0, 54.4], [152.0, 45.8],
+                [162.1, 53.6], [170.0, 73.2], [160.2, 52.1], [161.3, 67.9], [166.4, 56.6],
+                [168.9, 62.3], [163.8, 58.5], [167.6, 54.5], [160.0, 50.2], [161.3, 60.3],
+                [167.6, 58.3], [165.1, 56.2], [160.0, 50.2], [170.0, 72.9], [157.5, 59.8],
+                [167.6, 61.0], [160.7, 69.1], [163.2, 55.9], [152.4, 46.5], [157.5, 54.3],
+                [168.3, 54.8], [180.3, 60.7], [165.5, 60.0], [165.0, 62.0], [164.5, 60.3],
+                [156.0, 52.7], [160.0, 74.3], [163.0, 62.0], [165.7, 73.1], [161.0, 80.0],
+                [162.0, 54.7], [166.0, 53.2], [174.0, 75.7], [172.7, 61.1], [167.6, 55.7],
+                [151.1, 48.7], [164.5, 52.3], [163.5, 50.0], [152.0, 59.3], [169.0, 62.5],
+                [164.0, 55.7], [161.2, 54.8], [155.0, 45.9], [170.0, 70.6], [176.2, 67.2],
+                [170.0, 69.4], [162.5, 58.2], [170.3, 64.8], [164.1, 71.6], [169.5, 52.8],
+                [163.2, 59.8], [154.5, 49.0], [159.8, 50.0], [173.2, 69.2], [170.0, 55.9],
+                [161.4, 63.4], [169.0, 58.2], [166.2, 58.6], [159.4, 45.7], [162.5, 52.2],
+                [159.0, 48.6], [162.8, 57.8], [159.0, 55.6], [179.8, 66.8], [162.9, 59.4],
+                [161.0, 53.6], [151.1, 73.2], [168.2, 53.4], [168.9, 69.0], [173.2, 58.4],
+                [171.8, 56.2], [178.0, 70.6], [164.3, 59.8], [163.0, 72.0], [168.5, 65.2],
+                [166.8, 56.6], [172.7, 105.2], [163.5, 51.8], [169.4, 63.4], [167.8, 59.0],
+                [159.5, 47.6], [167.6, 63.0], [161.2, 55.2], [160.0, 45.0], [163.2, 54.0],
+                [162.2, 50.2], [161.3, 60.2], [149.5, 44.8], [157.5, 58.8], [163.2, 56.4],
+                [172.7, 62.0], [155.0, 49.2], [156.5, 67.2], [164.0, 53.8], [160.9, 54.4],
+                [162.8, 58.0], [167.0, 59.8], [160.0, 54.8], [160.0, 43.2], [168.9, 60.5],
+                [158.2, 46.4], [156.0, 64.4], [160.0, 48.8], [167.1, 62.2], [158.0, 55.5],
+                [167.6, 57.8], [156.0, 54.6], [162.1, 59.2], [173.4, 52.7], [159.8, 53.2],
+                [170.5, 64.5], [159.2, 51.8], [157.5, 56.0], [161.3, 63.6], [162.6, 63.2],
+                [160.0, 59.5], [168.9, 56.8], [165.1, 64.1], [162.6, 50.0], [165.1, 72.3],
+                [166.4, 55.0], [160.0, 55.9], [152.4, 60.4], [170.2, 69.1], [162.6, 84.5],
+                [170.2, 55.9], [158.8, 55.5], [172.7, 69.5], [167.6, 76.4], [162.6, 61.4],
+                [167.6, 65.9], [156.2, 58.6], [175.2, 66.8], [172.1, 56.6], [162.6, 58.6],
+                [160.0, 55.9], [165.1, 59.1], [182.9, 81.8], [166.4, 70.7], [165.1, 56.8],
+                [177.8, 60.0], [165.1, 58.2], [175.3, 72.7], [154.9, 54.1], [158.8, 49.1],
+                [172.7, 75.9], [168.9, 55.0], [161.3, 57.3], [167.6, 55.0], [165.1, 65.5],
+                [175.3, 65.5], [157.5, 48.6], [163.8, 58.6], [167.6, 63.6], [165.1, 55.2],
+                [165.1, 62.7], [168.9, 56.6], [162.6, 53.9], [164.5, 63.2], [176.5, 73.6],
+                [168.9, 62.0], [175.3, 63.6], [159.4, 53.2], [160.0, 53.4], [170.2, 55.0],
+                [162.6, 70.5], [167.6, 54.5], [162.6, 54.5], [160.7, 55.9], [160.0, 59.0],
+                [157.5, 63.6], [162.6, 54.5], [152.4, 47.3], [170.2, 67.7], [165.1, 80.9],
+                [172.7, 70.5], [165.1, 60.9], [170.2, 63.6], [170.2, 54.5], [170.2, 59.1],
+                [161.3, 70.5], [167.6, 52.7], [167.6, 62.7], [165.1, 86.3], [162.6, 66.4],
+                [152.4, 67.3], [168.9, 63.0], [170.2, 73.6], [175.2, 62.3], [175.2, 57.7],
+                [160.0, 55.4], [165.1, 104.1], [174.0, 55.5], [170.2, 77.3], [160.0, 80.5],
+                [167.6, 64.5], [167.6, 72.3], [167.6, 61.4], [154.9, 58.2], [162.6, 81.8],
+                [175.3, 63.6], [171.4, 53.4], [157.5, 54.5], [165.1, 53.6], [160.0, 60.0],
+                [174.0, 73.6], [162.6, 61.4], [174.0, 55.5], [162.6, 63.6], [161.3, 60.9],
+                [156.2, 60.0], [149.9, 46.8], [169.5, 57.3], [160.0, 64.1], [175.3, 63.6],
+                [169.5, 67.3], [160.0, 75.5], [172.7, 68.2], [162.6, 61.4], [157.5, 76.8],
+                [176.5, 71.8], [164.4, 55.5], [160.7, 48.6], [174.0, 66.4], [163.8, 67.3]
+            ],
+            markArea: {
+                silent: true,
+                itemStyle: {
+                    color: 'transparent',
+                    borderWidth: 1,
+                    borderType: 'dashed'
+                },
+                data: [[{
+                    name: 'Female Data Range',
+                    xAxis: 'min',
+                    yAxis: 'min'
+                }, {
+                    xAxis: 'max',
+                    yAxis: 'max'
+                }]]
+            },
+            markPoint: {
+                data: [
+                    {type: 'max', name: 'Max'},
+                    {type: 'min', name: 'Min'}
+                ]
+            },
+            markLine: {
+                lineStyle: {
+                    type: 'solid'
+                },
+                data: [
+                    {type: 'average', name: 'AVG'},
+                    { xAxis: 160 }
+                ]
+            }
+        },
+        {
+            name: 'Male',
+            type: 'scatter',
+            emphasis: {
+                focus: 'series'
+            },
+            data: [[174.0, 65.6], [175.3, 71.8], [193.5, 80.7], [186.5, 72.6], [187.2, 78.8],
+                [181.5, 74.8], [184.0, 86.4], [184.5, 78.4], [175.0, 62.0], [184.0, 81.6],
+                [180.0, 76.6], [177.8, 83.6], [192.0, 90.0], [176.0, 74.6], [174.0, 71.0],
+                [184.0, 79.6], [192.7, 93.8], [171.5, 70.0], [173.0, 72.4], [176.0, 85.9],
+                [176.0, 78.8], [180.5, 77.8], [172.7, 66.2], [176.0, 86.4], [173.5, 81.8],
+                [178.0, 89.6], [180.3, 82.8], [180.3, 76.4], [164.5, 63.2], [173.0, 60.9],
+                [183.5, 74.8], [175.5, 70.0], [188.0, 72.4], [189.2, 84.1], [172.8, 69.1],
+                [170.0, 59.5], [182.0, 67.2], [170.0, 61.3], [177.8, 68.6], [184.2, 80.1],
+                [186.7, 87.8], [171.4, 84.7], [172.7, 73.4], [175.3, 72.1], [180.3, 82.6],
+                [182.9, 88.7], [188.0, 84.1], [177.2, 94.1], [172.1, 74.9], [167.0, 59.1],
+                [169.5, 75.6], [174.0, 86.2], [172.7, 75.3], [182.2, 87.1], [164.1, 55.2],
+                [163.0, 57.0], [171.5, 61.4], [184.2, 76.8], [174.0, 86.8], [174.0, 72.2],
+                [177.0, 71.6], [186.0, 84.8], [167.0, 68.2], [171.8, 66.1], [182.0, 72.0],
+                [167.0, 64.6], [177.8, 74.8], [164.5, 70.0], [192.0, 101.6], [175.5, 63.2],
+                [171.2, 79.1], [181.6, 78.9], [167.4, 67.7], [181.1, 66.0], [177.0, 68.2],
+                [174.5, 63.9], [177.5, 72.0], [170.5, 56.8], [182.4, 74.5], [197.1, 90.9],
+                [180.1, 93.0], [175.5, 80.9], [180.6, 72.7], [184.4, 68.0], [175.5, 70.9],
+                [180.6, 72.5], [177.0, 72.5], [177.1, 83.4], [181.6, 75.5], [176.5, 73.0],
+                [175.0, 70.2], [174.0, 73.4], [165.1, 70.5], [177.0, 68.9], [192.0, 102.3],
+                [176.5, 68.4], [169.4, 65.9], [182.1, 75.7], [179.8, 84.5], [175.3, 87.7],
+                [184.9, 86.4], [177.3, 73.2], [167.4, 53.9], [178.1, 72.0], [168.9, 55.5],
+                [157.2, 58.4], [180.3, 83.2], [170.2, 72.7], [177.8, 64.1], [172.7, 72.3],
+                [165.1, 65.0], [186.7, 86.4], [165.1, 65.0], [174.0, 88.6], [175.3, 84.1],
+                [185.4, 66.8], [177.8, 75.5], [180.3, 93.2], [180.3, 82.7], [177.8, 58.0],
+                [177.8, 79.5], [177.8, 78.6], [177.8, 71.8], [177.8, 116.4], [163.8, 72.2],
+                [188.0, 83.6], [198.1, 85.5], [175.3, 90.9], [166.4, 85.9], [190.5, 89.1],
+                [166.4, 75.0], [177.8, 77.7], [179.7, 86.4], [172.7, 90.9], [190.5, 73.6],
+                [185.4, 76.4], [168.9, 69.1], [167.6, 84.5], [175.3, 64.5], [170.2, 69.1],
+                [190.5, 108.6], [177.8, 86.4], [190.5, 80.9], [177.8, 87.7], [184.2, 94.5],
+                [176.5, 80.2], [177.8, 72.0], [180.3, 71.4], [171.4, 72.7], [172.7, 84.1],
+                [172.7, 76.8], [177.8, 63.6], [177.8, 80.9], [182.9, 80.9], [170.2, 85.5],
+                [167.6, 68.6], [175.3, 67.7], [165.1, 66.4], [185.4, 102.3], [181.6, 70.5],
+                [172.7, 95.9], [190.5, 84.1], [179.1, 87.3], [175.3, 71.8], [170.2, 65.9],
+                [193.0, 95.9], [171.4, 91.4], [177.8, 81.8], [177.8, 96.8], [167.6, 69.1],
+                [167.6, 82.7], [180.3, 75.5], [182.9, 79.5], [176.5, 73.6], [186.7, 91.8],
+                [188.0, 84.1], [188.0, 85.9], [177.8, 81.8], [174.0, 82.5], [177.8, 80.5],
+                [171.4, 70.0], [185.4, 81.8], [185.4, 84.1], [188.0, 90.5], [188.0, 91.4],
+                [182.9, 89.1], [176.5, 85.0], [175.3, 69.1], [175.3, 73.6], [188.0, 80.5],
+                [188.0, 82.7], [175.3, 86.4], [170.5, 67.7], [179.1, 92.7], [177.8, 93.6],
+                [175.3, 70.9], [182.9, 75.0], [170.8, 93.2], [188.0, 93.2], [180.3, 77.7],
+                [177.8, 61.4], [185.4, 94.1], [168.9, 75.0], [185.4, 83.6], [180.3, 85.5],
+                [174.0, 73.9], [167.6, 66.8], [182.9, 87.3], [160.0, 72.3], [180.3, 88.6],
+                [167.6, 75.5], [186.7, 101.4], [175.3, 91.1], [175.3, 67.3], [175.9, 77.7],
+                [175.3, 81.8], [179.1, 75.5], [181.6, 84.5], [177.8, 76.6], [182.9, 85.0],
+                [177.8, 102.5], [184.2, 77.3], [179.1, 71.8], [176.5, 87.9], [188.0, 94.3],
+                [174.0, 70.9], [167.6, 64.5], [170.2, 77.3], [167.6, 72.3], [188.0, 87.3],
+                [174.0, 80.0], [176.5, 82.3], [180.3, 73.6], [167.6, 74.1], [188.0, 85.9],
+                [180.3, 73.2], [167.6, 76.3], [183.0, 65.9], [183.0, 90.9], [179.1, 89.1],
+                [170.2, 62.3], [177.8, 82.7], [179.1, 79.1], [190.5, 98.2], [177.8, 84.1],
+                [180.3, 83.2], [180.3, 83.2]
+            ],
+            markArea: {
+                silent: true,
+                itemStyle: {
+                    color: 'transparent',
+                    borderWidth: 1,
+                    borderType: 'dashed'
+                },
+                data: [[{
+                    name: 'Male Data Range',
+                    xAxis: 'min',
+                    yAxis: 'min'
+                }, {
+                    xAxis: 'max',
+                    yAxis: 'max'
+                }]]
+            },
+            markPoint: {
+                data: [
+                    {type: 'max', name: 'Max'},
+                    {type: 'min', name: 'Min'}
+                ]
+            },
+            markLine: {
+                lineStyle: {
+                    type: 'solid'
+                },
+                data: [
+                    {type: 'average', name: 'Average'},
+                    { xAxis: 170 }
+                ]
+            }
+        }
+    ]
+};
+
+
+export {}
\ No newline at end of file
diff --git a/public/examples/ts/sunburst-borderRadius.ts b/public/examples/ts/sunburst-borderRadius.ts
new file mode 100644
index 0000000..dc42588
--- /dev/null
+++ b/public/examples/ts/sunburst-borderRadius.ts
@@ -0,0 +1,66 @@
+/*
+title: Sunburst with Rounded Corner
+category: sunburst
+titleCN: 圆角旭日图
+difficulty: 2
+*/
+
+var data = [{
+    name: 'Grandpa',
+    children: [{
+        name: 'Uncle Leo',
+        value: 15,
+        children: [{
+            name: 'Cousin Jack',
+            value: 2
+        }, {
+            name: 'Cousin Mary',
+            value: 5,
+            children: [{
+                name: 'Jackson',
+                value: 2
+            }]
+        }, {
+            name: 'Cousin Ben',
+            value: 4
+        }]
+    }, {
+        name: 'Father',
+        value: 10,
+        children: [{
+            name: 'Me',
+            value: 5
+        }, {
+            name: 'Brother Peter',
+            value: 1
+        }]
+    }]
+}, {
+    name: 'Nancy',
+    children: [{
+        name: 'Uncle Nike',
+        children: [{
+            name: 'Cousin Betty',
+            value: 1
+        }, {
+            name: 'Cousin Jenny',
+            value: 2
+        }]
+    }]
+}];
+
+option = {
+    series: {
+        type: 'sunburst',
+        data: data,
+        radius: [60, '90%'],
+        itemStyle: {
+            borderRadius: 7,
+            borderWidth: 2
+        },
+        label: {
+            show: false
+        }
+    }
+};
+export {}
\ No newline at end of file
diff --git a/public/examples/ts/sunburst-drink.ts b/public/examples/ts/sunburst-drink.ts
new file mode 100644
index 0000000..b2fc3f7
--- /dev/null
+++ b/public/examples/ts/sunburst-drink.ts
@@ -0,0 +1,725 @@
+/*
+title: Drink Flavors
+category: sunburst
+titleCN: Drink Flavors
+shotWidth: 1000
+difficulty: 5
+*/
+
+var data = [{
+    name: 'Flora',
+    itemStyle: {
+        color: '#da0d68'
+    },
+    children: [{
+        name: 'Black Tea',
+        value: 1,
+        itemStyle: {
+            color: '#975e6d'
+        }
+    }, {
+        name: 'Floral',
+        itemStyle: {
+            color: '#e0719c'
+        },
+        children: [{
+            name: 'Chamomile',
+            value: 1,
+            itemStyle: {
+                color: '#f99e1c'
+            }
+        }, {
+            name: 'Rose',
+            value: 1,
+            itemStyle: {
+                color: '#ef5a78'
+            }
+        }, {
+            name: 'Jasmine',
+            value: 1,
+            itemStyle: {
+                color: '#f7f1bd'
+            }
+        }]
+    }]
+}, {
+    name: 'Fruity',
+    itemStyle: {
+        color: '#da1d23'
+    },
+    children: [{
+        name: 'Berry',
+        itemStyle: {
+            color: '#dd4c51'
+        },
+        children: [{
+            name: 'Blackberry',
+            value: 1,
+            itemStyle: {
+                color: '#3e0317'
+            }
+        }, {
+            name: 'Raspberry',
+            value: 1,
+            itemStyle: {
+                color: '#e62969'
+            }
+        }, {
+            name: 'Blueberry',
+            value: 1,
+            itemStyle: {
+                color: '#6569b0'
+            }
+        }, {
+            name: 'Strawberry',
+            value: 1,
+            itemStyle: {
+                color: '#ef2d36'
+            }
+        }]
+    }, {
+        name: 'Dried Fruit',
+        itemStyle: {
+            color: '#c94a44'
+        },
+        children: [{
+            name: 'Raisin',
+            value: 1,
+            itemStyle: {
+                color: '#b53b54'
+            }
+        }, {
+            name: 'Prune',
+            value: 1,
+            itemStyle: {
+                color: '#a5446f'
+            }
+        }]
+    }, {
+        name: 'Other Fruit',
+        itemStyle: {
+            color: '#dd4c51'
+        },
+        children: [{
+            name: 'Coconut',
+            value: 1,
+            itemStyle: {
+                color: '#f2684b'
+            }
+        }, {
+            name: 'Cherry',
+            value: 1,
+            itemStyle: {
+                color: '#e73451'
+            }
+        }, {
+            name: 'Pomegranate',
+            value: 1,
+            itemStyle: {
+                color: '#e65656'
+            }
+        }, {
+            name: 'Pineapple',
+            value: 1,
+            itemStyle: {
+                color: '#f89a1c'
+            }
+        }, {
+            name: 'Grape',
+            value: 1,
+            itemStyle: {
+                color: '#aeb92c'
+            }
+        }, {
+            name: 'Apple',
+            value: 1,
+            itemStyle: {
+                color: '#4eb849'
+            }
+        }, {
+            name: 'Peach',
+            value: 1,
+            itemStyle: {
+                color: '#f68a5c'
+            }
+        }, {
+            name: 'Pear',
+            value: 1,
+            itemStyle: {
+                color: '#baa635'
+            }
+        }]
+    }, {
+        name: 'Citrus Fruit',
+        itemStyle: {
+            color: '#f7a128'
+        },
+        children: [{
+            name: 'Grapefruit',
+            value: 1,
+            itemStyle: {
+                color: '#f26355'
+            }
+        }, {
+            name: 'Orange',
+            value: 1,
+            itemStyle: {
+                color: '#e2631e'
+            }
+        }, {
+            name: 'Lemon',
+            value: 1,
+            itemStyle: {
+                color: '#fde404'
+            }
+        }, {
+            name: 'Lime',
+            value: 1,
+            itemStyle: {
+                color: '#7eb138'
+            }
+        }]
+    }]
+}, {
+    name: 'Sour/\nFermented',
+    itemStyle: {
+        color: '#ebb40f'
+    },
+    children: [{
+        name: 'Sour',
+        itemStyle: {
+            color: '#e1c315'
+        },
+        children: [{
+            name: 'Sour Aromatics',
+            value: 1,
+            itemStyle: {
+                color: '#9ea718'
+            }
+        }, {
+            name: 'Acetic Acid',
+            value: 1,
+            itemStyle: {
+                color: '#94a76f'
+            }
+        }, {
+            name: 'Butyric Acid',
+            value: 1,
+            itemStyle: {
+                color: '#d0b24f'
+            }
+        }, {
+            name: 'Isovaleric Acid',
+            value: 1,
+            itemStyle: {
+                color: '#8eb646'
+            }
+        }, {
+            name: 'Citric Acid',
+            value: 1,
+            itemStyle: {
+                color: '#faef07'
+            }
+        }, {
+            name: 'Malic Acid',
+            value: 1,
+            itemStyle: {
+                color: '#c1ba07'
+            }
+        }]
+    }, {
+        name: 'Alcohol/\nFremented',
+        itemStyle: {
+            color: '#b09733'
+        },
+        children: [{
+            name: 'Winey',
+            value: 1,
+            itemStyle: {
+                color: '#8f1c53'
+            }
+        }, {
+            name: 'Whiskey',
+            value: 1,
+            itemStyle: {
+                color: '#b34039'
+            }
+        }, {
+            name: 'Fremented',
+            value: 1,
+            itemStyle: {
+                color: '#ba9232'
+            }
+        }, {
+            name: 'Overripe',
+            value: 1,
+            itemStyle: {
+                color: '#8b6439'
+            }
+        }]
+    }]
+}, {
+    name: 'Green/\nVegetative',
+    itemStyle: {
+        color: '#187a2f'
+    },
+    children: [{
+        name: 'Olive Oil',
+        value: 1,
+        itemStyle: {
+            color: '#a2b029'
+        }
+    }, {
+        name: 'Raw',
+        value: 1,
+        itemStyle: {
+            color: '#718933'
+        }
+    }, {
+        name: 'Green/\nVegetative',
+        itemStyle: {
+            color: '#3aa255'
+        },
+        children: [{
+            name: 'Under-ripe',
+            value: 1,
+            itemStyle: {
+                color: '#a2bb2b'
+            }
+        }, {
+            name: 'Peapod',
+            value: 1,
+            itemStyle: {
+                color: '#62aa3c'
+            }
+        }, {
+            name: 'Fresh',
+            value: 1,
+            itemStyle: {
+                color: '#03a653'
+            }
+        }, {
+            name: 'Dark Green',
+            value: 1,
+            itemStyle: {
+                color: '#038549'
+            }
+        }, {
+            name: 'Vegetative',
+            value: 1,
+            itemStyle: {
+                color: '#28b44b'
+            }
+        }, {
+            name: 'Hay-like',
+            value: 1,
+            itemStyle: {
+                color: '#a3a830'
+            }
+        }, {
+            name: 'Herb-like',
+            value: 1,
+            itemStyle: {
+                color: '#7ac141'
+            }
+        }]
+    }, {
+        name: 'Beany',
+        value: 1,
+        itemStyle: {
+            color: '#5e9a80'
+        }
+    }]
+}, {
+    name: 'Other',
+    itemStyle: {
+        color: '#0aa3b5'
+    },
+    children: [{
+        name: 'Papery/Musty',
+        itemStyle: {
+            color: '#9db2b7'
+        },
+        children: [{
+            name: 'Stale',
+            value: 1,
+            itemStyle: {
+                color: '#8b8c90'
+            }
+        }, {
+            name: 'Cardboard',
+            value: 1,
+            itemStyle: {
+                color: '#beb276'
+            }
+        }, {
+            name: 'Papery',
+            value: 1,
+            itemStyle: {
+                color: '#fefef4'
+            }
+        }, {
+            name: 'Woody',
+            value: 1,
+            itemStyle: {
+                color: '#744e03'
+            }
+        }, {
+            name: 'Moldy/Damp',
+            value: 1,
+            itemStyle: {
+                color: '#a3a36f'
+            }
+        }, {
+            name: 'Musty/Dusty',
+            value: 1,
+            itemStyle: {
+                color: '#c9b583'
+            }
+        }, {
+            name: 'Musty/Earthy',
+            value: 1,
+            itemStyle: {
+                color: '#978847'
+            }
+        }, {
+            name: 'Animalic',
+            value: 1,
+            itemStyle: {
+                color: '#9d977f'
+            }
+        }, {
+            name: 'Meaty Brothy',
+            value: 1,
+            itemStyle: {
+                color: '#cc7b6a'
+            }
+        }, {
+            name: 'Phenolic',
+            value: 1,
+            itemStyle: {
+                color: '#db646a'
+            }
+        }]
+    }, {
+        name: 'Chemical',
+        itemStyle: {
+            color: '#76c0cb'
+        },
+        children: [{
+            name: 'Bitter',
+            value: 1,
+            itemStyle: {
+                color: '#80a89d'
+            }
+        }, {
+            name: 'Salty',
+            value: 1,
+            itemStyle: {
+                color: '#def2fd'
+            }
+        }, {
+            name: 'Medicinal',
+            value: 1,
+            itemStyle: {
+                color: '#7a9bae'
+            }
+        }, {
+            name: 'Petroleum',
+            value: 1,
+            itemStyle: {
+                color: '#039fb8'
+            }
+        }, {
+            name: 'Skunky',
+            value: 1,
+            itemStyle: {
+                color: '#5e777b'
+            }
+        }, {
+            name: 'Rubber',
+            value: 1,
+            itemStyle: {
+                color: '#120c0c'
+            }
+        }]
+    }]
+}, {
+    name: 'Roasted',
+    itemStyle: {
+        color: '#c94930'
+    },
+    children: [{
+        name: 'Pipe Tobacco',
+        value: 1,
+        itemStyle: {
+            color: '#caa465'
+        }
+    }, {
+        name: 'Tobacco',
+        value: 1,
+        itemStyle: {
+            color: '#dfbd7e'
+        }
+    }, {
+        name: 'Burnt',
+        itemStyle: {
+            color: '#be8663'
+        },
+        children: [{
+            name: 'Acrid',
+            value: 1,
+            itemStyle: {
+                color: '#b9a449'
+            }
+        }, {
+            name: 'Ashy',
+            value: 1,
+            itemStyle: {
+                color: '#899893'
+            }
+        }, {
+            name: 'Smoky',
+            value: 1,
+            itemStyle: {
+                color: '#a1743b'
+            }
+        }, {
+            name: 'Brown, Roast',
+            value: 1,
+            itemStyle: {
+                color: '#894810'
+            }
+        }]
+    }, {
+        name: 'Cereal',
+        itemStyle: {
+            color: '#ddaf61'
+        },
+        children: [{
+            name: 'Grain',
+            value: 1,
+            itemStyle: {
+                color: '#b7906f'
+            }
+        }, {
+            name: 'Malt',
+            value: 1,
+            itemStyle: {
+                color: '#eb9d5f'
+            }
+        }]
+    }]
+}, {
+    name: 'Spices',
+    itemStyle: {
+        color: '#ad213e'
+    },
+    children: [{
+        name: 'Pungent',
+        value: 1,
+        itemStyle: {
+            color: '#794752'
+        }
+    }, {
+        name: 'Pepper',
+        value: 1,
+        itemStyle: {
+            color: '#cc3d41'
+        }
+    }, {
+        name: 'Brown Spice',
+        itemStyle: {
+            color: '#b14d57'
+        },
+        children: [{
+            name: 'Anise',
+            value: 1,
+            itemStyle: {
+                color: '#c78936'
+            }
+        }, {
+            name: 'Nutmeg',
+            value: 1,
+            itemStyle: {
+                color: '#8c292c'
+            }
+        }, {
+            name: 'Cinnamon',
+            value: 1,
+            itemStyle: {
+                color: '#e5762e'
+            }
+        }, {
+            name: 'Clove',
+            value: 1,
+            itemStyle: {
+                color: '#a16c5a'
+            }
+        }]
+    }]
+}, {
+    name: 'Nutty/\nCocoa',
+    itemStyle: {
+        color: '#a87b64'
+    },
+    children: [{
+        name: 'Nutty',
+        itemStyle: {
+            color: '#c78869'
+        },
+        children: [ {
+            name: 'Peanuts',
+            value: 1,
+            itemStyle: {
+                color: '#d4ad12'
+            }
+        }, {
+            name: 'Hazelnut',
+            value: 1,
+            itemStyle: {
+                color: '#9d5433'
+            }
+        }, {
+            name: 'Almond',
+            value: 1,
+            itemStyle: {
+                color: '#c89f83'
+            }
+        }]
+    }, {
+        name: 'Cocoa',
+        itemStyle: {
+            color: '#bb764c'
+        },
+        children: [{
+            name: 'Chocolate',
+            value: 1,
+            itemStyle: {
+                color: '#692a19'
+            }
+        }, {
+            name: 'Dark Chocolate',
+            value: 1,
+            itemStyle: {
+                color: '#470604'
+            }
+        }]
+    }]
+}, {
+    name: 'Sweet',
+    itemStyle: {
+        color: '#e65832'
+    },
+    children: [{
+        name: 'Brown Sugar',
+        itemStyle: {
+            color: '#d45a59'
+        },
+        children: [{
+            name: 'Molasses',
+            value: 1,
+            itemStyle: {
+                color: '#310d0f'
+            }
+        }, {
+            name: 'Maple Syrup',
+            value: 1,
+            itemStyle: {
+                color: '#ae341f'
+            }
+        }, {
+            name: 'Caramelized',
+            value: 1,
+            itemStyle: {
+                color: '#d78823'
+            }
+        }, {
+            name: 'Honey',
+            value: 1,
+            itemStyle: {
+                color: '#da5c1f'
+            }
+        }]
+    }, {
+        name: 'Vanilla',
+        value: 1,
+        itemStyle: {
+            color: '#f89a80'
+        }
+    }, {
+        name: 'Vanillin',
+        value: 1,
+        itemStyle: {
+            color: '#f37674'
+        }
+    }, {
+        name: 'Overall Sweet',
+        value: 1,
+        itemStyle: {
+            color: '#e75b68'
+        }
+    }, {
+        name: 'Sweet Aromatics',
+        value: 1,
+        itemStyle: {
+            color: '#d0545f'
+        }
+    }]
+}];
+
+option = {
+    title: {
+        text: 'WORLD COFFEE RESEARCH SENSORY LEXICON',
+        subtext: 'Source: https://worldcoffeeresearch.org/work/sensory-lexicon/',
+        textStyle: {
+            fontSize: 14,
+            align: 'center'
+        },
+        subtextStyle: {
+            align: 'center'
+        },
+        sublink: 'https://worldcoffeeresearch.org/work/sensory-lexicon/'
+    },
+    series: {
+        type: 'sunburst',
+
+        data: data,
+        radius: [0, '95%'],
+        sort: null,
+
+        emphasis: {
+            focus: 'ancestor'
+        },
+
+        levels: [{}, {
+            r0: '15%',
+            r: '35%',
+            itemStyle: {
+                borderWidth: 2
+            },
+            label: {
+                rotate: 'tangential'
+            }
+        }, {
+            r0: '35%',
+            r: '70%',
+            label: {
+                align: 'right'
+            }
+        }, {
+            r0: '70%',
+            r: '72%',
+            label: {
+                position: 'outside',
+                padding: 3,
+                silent: false
+            },
+            itemStyle: {
+                borderWidth: 3
+            }
+        }]
+    }
+};
+
+export {}
\ No newline at end of file
diff --git a/public/examples/ts/sunburst-label-rotate.ts b/public/examples/ts/sunburst-label-rotate.ts
new file mode 100644
index 0000000..f6433dd
--- /dev/null
+++ b/public/examples/ts/sunburst-label-rotate.ts
@@ -0,0 +1,98 @@
+/*
+title: Sunburst Label Rotate
+category: sunburst
+titleCN: 旭日图标签旋转
+difficulty: 2
+*/
+
+option = {
+    silent: true,
+    series: [{
+        radius: ['15%', '80%'],
+        type: 'sunburst',
+        sort: undefined,
+        emphasis: {
+            focus: 'ancestor'
+        },
+        data: [{
+            value: 8,
+            children: [{
+                value: 4,
+                children: [{
+                    value: 2
+                }, {
+                    value: 1
+                }, {
+                    value: 1
+                }, {
+                    value: 0.5
+                }]
+            }, {
+                value: 2
+            }]
+        }, {
+            value: 4,
+            children: [{
+                children: [{
+                    value: 2
+                }]
+            }]
+        }, {
+            value: 4,
+            children: [{
+                children: [{
+                    value: 2
+                }]
+            }]
+        }, {
+            value: 3,
+            children: [{
+                children: [{
+                    value: 1
+                }]
+            }]
+        }],
+        label: {
+            color: '#000',
+            textBorderColor: '#fff',
+            textBorderWidth: 2,
+            formatter: function (param: any) {
+                var depth = param.treePathInfo.length;
+                if (depth === 2) {
+                    return 'radial';
+                }
+                else if (depth === 3) {
+                    return 'tangential';
+                }
+                else if (depth === 4) {
+                    return '0';
+                }
+                return ''
+            }
+        },
+        levels: [{}, {
+            itemStyle: {
+                color: '#CD4949'
+            },
+            label: {
+                rotate: 'radial'
+            }
+        }, {
+            itemStyle: {
+                color: '#F47251'
+            },
+            label: {
+                rotate: 'tangential'
+            }
+        }, {
+            itemStyle: {
+                color: '#FFC75F'
+            },
+            label: {
+                rotate: 0
+            }
+        }]
+    }]
+};
+
+export {}
\ No newline at end of file
diff --git a/public/examples/ts/sunburst-monochrome.ts b/public/examples/ts/sunburst-monochrome.ts
new file mode 100644
index 0000000..e472fcf
--- /dev/null
+++ b/public/examples/ts/sunburst-monochrome.ts
@@ -0,0 +1,178 @@
+/*
+title: Monochrome Sunburst
+category: sunburst
+titleCN: Monochrome Sunburst
+difficulty: 3
+*/
+
+const item1 = {
+    color: '#F54F4A'
+};
+const item2 = {
+    color: '#FF8C75'
+};
+const item3 = {
+    color: '#FFB499'
+};
+
+const data = [{
+    children: [{
+        value: 5,
+        children: [{
+            value: 1,
+            itemStyle: item1
+        }, {
+            value: 2,
+            children: [{
+                value: 1,
+                itemStyle: item2
+            }]
+        }, {
+            children: [{
+                value: 1
+            }]
+        }],
+        itemStyle: item1
+    }, {
+        value: 10,
+        children: [{
+            value: 6,
+            children: [{
+                value: 1,
+                itemStyle: item1
+            }, {
+                value: 1
+            }, {
+                value: 1,
+                itemStyle: item2
+            }, {
+                value: 1
+            }],
+            itemStyle: item3
+        }, {
+            value: 2,
+            children: [{
+                value: 1
+            }],
+            itemStyle: item3
+        }, {
+            children: [{
+                value: 1,
+                itemStyle: item2
+            }]
+        }],
+        itemStyle: item1
+    }],
+    itemStyle: item1
+}, {
+    value: 9,
+    children: [{
+        value: 4,
+        children: [{
+            value: 2,
+            itemStyle: item2
+        }, {
+            children: [{
+                value: 1,
+                itemStyle: item1
+            }]
+        }],
+        itemStyle: item1
+    }, {
+        children: [{
+            value: 3,
+            children: [{
+                value: 1
+            }, {
+                value: 1,
+                itemStyle: item2
+            }]
+        }],
+        itemStyle: item3
+    }],
+    itemStyle: item2
+}, {
+    value: 7,
+    children: [{
+        children: [{
+            value: 1,
+            itemStyle: item3
+        }, {
+            value: 3,
+            children: [{
+                value: 1,
+                itemStyle: item2
+            }, {
+                value: 1
+            }],
+            itemStyle: item2
+        }, {
+            value: 2,
+            children: [{
+                value: 1
+            }, {
+                value: 1,
+                itemStyle: item1
+            }],
+            itemStyle: item1
+        }],
+        itemStyle: item3
+    }],
+    itemStyle: item1
+}, {
+    children: [{
+        value: 6,
+        children: [{
+            value: 1,
+            itemStyle: item2
+        }, {
+            value: 2,
+            children: [{
+                value: 2,
+                itemStyle: item2
+            }],
+            itemStyle: item1
+        }, {
+            value: 1,
+            itemStyle: item3
+        }],
+        itemStyle: item3
+    }, {
+        value: 3,
+        children: [{
+            value: 1,
+        }, {
+            children: [{
+                value: 1,
+                itemStyle: item2
+            }]
+        }, {
+            value: 1
+        }],
+        itemStyle: item3
+    }],
+    itemStyle: item1
+}];
+
+option = {
+    series: {
+        radius: ['15%', '80%'],
+        type: 'sunburst',
+        sort: undefined,
+        emphasis: {
+            focus: 'ancestor'
+        },
+        data: data,
+        label: {
+            rotate: 'radial'
+        },
+        levels: [],
+        itemStyle: {
+            color: '#ddd',
+            borderWidth: 2
+        }
+    }
+};
+
+
+export {};
\ No newline at end of file
diff --git a/public/examples/ts/sunburst-simple.ts b/public/examples/ts/sunburst-simple.ts
new file mode 100644
index 0000000..086b281
--- /dev/null
+++ b/public/examples/ts/sunburst-simple.ts
@@ -0,0 +1,66 @@
+/*
+title: Basic Sunburst
+category: sunburst
+titleCN: 基础旭日图
+difficulty: 1
+*/
+
+var data = [{
+    name: 'Grandpa',
+    children: [{
+        name: 'Uncle Leo',
+        value: 15,
+        children: [{
+            name: 'Cousin Jack',
+            value: 2
+        }, {
+            name: 'Cousin Mary',
+            value: 5,
+            children: [{
+                name: 'Jackson',
+                value: 2
+            }]
+        }, {
+            name: 'Cousin Ben',
+            value: 4
+        }]
+    }, {
+        name: 'Father',
+        value: 10,
+        children: [{
+            name: 'Me',
+            value: 5
+        }, {
+            name: 'Brother Peter',
+            value: 1
+        }]
+    }]
+}, {
+    name: 'Nancy',
+    children: [{
+        name: 'Uncle Nike',
+        children: [{
+            name: 'Cousin Betty',
+            value: 1
+        }, {
+            name: 'Cousin Jenny',
+            value: 2
+        }]
+    }]
+}];
+
+option = {
+    series: {
+        type: 'sunburst',
+        // emphasis: {
+        //     focus: 'ancestor'
+        // },
+        data: data,
+        radius: [0, '90%'],
+        label: {
+            rotate: 'radial'
+        }
+    }
+};
+
+export {}
\ No newline at end of file
diff --git a/public/examples/ts/sunburst-visualMap.ts b/public/examples/ts/sunburst-visualMap.ts
new file mode 100644
index 0000000..30f26ad
--- /dev/null
+++ b/public/examples/ts/sunburst-visualMap.ts
@@ -0,0 +1,95 @@
+/*
+title: Sunburst VisualMap
+category: sunburst
+titleCN: 旭日图使用视觉编码
+difficulty: 4
+*/
+
+var data = [{
+    name: 'Grandpa',
+    children: [{
+        name: 'Uncle Leo',
+        value: 15,
+        children: [{
+            name: 'Cousin Jack',
+            value: 2
+        }, {
+            name: 'Cousin Mary',
+            value: 5,
+            children: [{
+                name: 'Jackson',
+                value: 2
+            }]
+        }, {
+            name: 'Cousin Ben',
+            value: 4
+        }]
+    }, {
+        name: 'Aunt Jane',
+        children: [{
+            name: 'Cousin Kate',
+            value: 4
+        }]
+    }, {
+        name: 'Father',
+        value: 10,
+        children: [{
+            name: 'Me',
+            value: 5,
+            itemStyle: {
+                color: 'red'
+            }
+        }, {
+            name: 'Brother Peter',
+            value: 1
+        }]
+    }]
+}, {
+    name: 'Mike',
+    children: [{
+        name: 'Uncle Dan',
+        children: [{
+            name: 'Cousin Lucy',
+            value: 3
+        }, {
+            name: 'Cousin Luck',
+            value: 4,
+            children: [{
+                name: 'Nephew',
+                value: 2
+            }]
+        }]
+    }]
+}, {
+    name: 'Nancy',
+    children: [{
+        name: 'Uncle Nike',
+        children: [{
+            name: 'Cousin Betty',
+            value: 1
+        }, {
+            name: 'Cousin Jenny',
+            value: 2
+        }]
+    }]
+}];
+
+option = {
+    visualMap: {
+        type: 'continuous',
+        min: 0,
+        max: 10,
+        inRange: {
+            color: ['#2F93C8', '#AEC48F', '#FFDB5C', '#F98862']
+        }
+    },
+    series: {
+        type: 'sunburst',
+        data: data,
+        radius: [0, '90%'],
+        label: {
+            rotate: 'radial'
+        }
+    }
+};
+export {}
\ No newline at end of file
diff --git a/public/examples/ts/themeRiver-basic.ts b/public/examples/ts/themeRiver-basic.ts
new file mode 100644
index 0000000..3ac8914
--- /dev/null
+++ b/public/examples/ts/themeRiver-basic.ts
@@ -0,0 +1,100 @@
+/*
+title: ThemeRiver
+category: themeRiver
+titleCN: 主题河流图
+*/
+
+
+option = {
+    tooltip: {
+        trigger: 'axis',
+        axisPointer: {
+            type: 'line',
+            lineStyle: {
+                color: 'rgba(0,0,0,0.2)',
+                width: 1,
+                type: 'solid'
+            }
+        }
+    },
+
+    legend: {
+        data: ['DQ', 'TY', 'SS', 'QG', 'SY', 'DD']
+    },
+
+    singleAxis: {
+        top: 50,
+        bottom: 50,
+        axisTick: {},
+        axisLabel: {},
+        type: 'time',
+        axisPointer: {
+            animation: true,
+            label: {
+                show: true
+            }
+        },
+        splitLine: {
+            show: true,
+            lineStyle: {
+                type: 'dashed',
+                opacity: 0.2
+            }
+        }
+    },
+
+    series: [
+        {
+            type: 'themeRiver',
+            emphasis: {
+                itemStyle: {
+                    shadowBlur: 20,
+                    shadowColor: 'rgba(0, 0, 0, 0.8)'
+                }
+            },
+            data: [['2015/11/08',10,'DQ'],['2015/11/09',15,'DQ'],['2015/11/10',35,'DQ'],
+            ['2015/11/11',38,'DQ'],['2015/11/12',22,'DQ'],['2015/11/13',16,'DQ'],
+            ['2015/11/14',7,'DQ'],['2015/11/15',2,'DQ'],['2015/11/16',17,'DQ'],
+            ['2015/11/17',33,'DQ'],['2015/11/18',40,'DQ'],['2015/11/19',32,'DQ'],
+            ['2015/11/20',26,'DQ'],['2015/11/21',35,'DQ'],['2015/11/22',40,'DQ'],
+            ['2015/11/23',32,'DQ'],['2015/11/24',26,'DQ'],['2015/11/25',22,'DQ'],
+            ['2015/11/26',16,'DQ'],['2015/11/27',22,'DQ'],['2015/11/28',10,'DQ'],
+            ['2015/11/08',35,'TY'],['2015/11/09',36,'TY'],['2015/11/10',37,'TY'],
+            ['2015/11/11',22,'TY'],['2015/11/12',24,'TY'],['2015/11/13',26,'TY'],
+            ['2015/11/14',34,'TY'],['2015/11/15',21,'TY'],['2015/11/16',18,'TY'],
+            ['2015/11/17',45,'TY'],['2015/11/18',32,'TY'],['2015/11/19',35,'TY'],
+            ['2015/11/20',30,'TY'],['2015/11/21',28,'TY'],['2015/11/22',27,'TY'],
+            ['2015/11/23',26,'TY'],['2015/11/24',15,'TY'],['2015/11/25',30,'TY'],
+            ['2015/11/26',35,'TY'],['2015/11/27',42,'TY'],['2015/11/28',42,'TY'],
+            ['2015/11/08',21,'SS'],['2015/11/09',25,'SS'],['2015/11/10',27,'SS'],
+            ['2015/11/11',23,'SS'],['2015/11/12',24,'SS'],['2015/11/13',21,'SS'],
+            ['2015/11/14',35,'SS'],['2015/11/15',39,'SS'],['2015/11/16',40,'SS'],
+            ['2015/11/17',36,'SS'],['2015/11/18',33,'SS'],['2015/11/19',43,'SS'],
+            ['2015/11/20',40,'SS'],['2015/11/21',34,'SS'],['2015/11/22',28,'SS'],
+            ['2015/11/23',26,'SS'],['2015/11/24',37,'SS'],['2015/11/25',41,'SS'],
+            ['2015/11/26',46,'SS'],['2015/11/27',47,'SS'],['2015/11/28',41,'SS'],
+            ['2015/11/08',10,'QG'],['2015/11/09',15,'QG'],['2015/11/10',35,'QG'],
+            ['2015/11/11',38,'QG'],['2015/11/12',22,'QG'],['2015/11/13',16,'QG'],
+            ['2015/11/14',7,'QG'],['2015/11/15',2,'QG'],['2015/11/16',17,'QG'],
+            ['2015/11/17',33,'QG'],['2015/11/18',40,'QG'],['2015/11/19',32,'QG'],
+            ['2015/11/20',26,'QG'],['2015/11/21',35,'QG'],['2015/11/22',40,'QG'],
+            ['2015/11/23',32,'QG'],['2015/11/24',26,'QG'],['2015/11/25',22,'QG'],
+            ['2015/11/26',16,'QG'],['2015/11/27',22,'QG'],['2015/11/28',10,'QG'],
+            ['2015/11/08',10,'SY'],['2015/11/09',15,'SY'],['2015/11/10',35,'SY'],
+            ['2015/11/11',38,'SY'],['2015/11/12',22,'SY'],['2015/11/13',16,'SY'],
+            ['2015/11/14',7,'SY'],['2015/11/15',2,'SY'],['2015/11/16',17,'SY'],
+            ['2015/11/17',33,'SY'],['2015/11/18',40,'SY'],['2015/11/19',32,'SY'],
+            ['2015/11/20',26,'SY'],['2015/11/21',35,'SY'],['2015/11/22',4,'SY'],
+            ['2015/11/23',32,'SY'],['2015/11/24',26,'SY'],['2015/11/25',22,'SY'],
+            ['2015/11/26',16,'SY'],['2015/11/27',22,'SY'],['2015/11/28',10,'SY'],
+            ['2015/11/08',10,'DD'],['2015/11/09',15,'DD'],['2015/11/10',35,'DD'],
+            ['2015/11/11',38,'DD'],['2015/11/12',22,'DD'],['2015/11/13',16,'DD'],
+            ['2015/11/14',7,'DD'],['2015/11/15',2,'DD'],['2015/11/16',17,'DD'],
+            ['2015/11/17',33,'DD'],['2015/11/18',4,'DD'],['2015/11/19',32,'DD'],
+            ['2015/11/20',26,'DD'],['2015/11/21',35,'DD'],['2015/11/22',40,'DD'],
+            ['2015/11/23',32,'DD'],['2015/11/24',26,'DD'],['2015/11/25',22,'DD'],
+            ['2015/11/26',16,'DD'],['2015/11/27',22,'DD'],['2015/11/28',10,'DD']]
+        }
+    ]
+};
+export {}
\ No newline at end of file
diff --git a/public/examples/ts/themeRiver-lastfm.ts b/public/examples/ts/themeRiver-lastfm.ts
new file mode 100644
index 0000000..df06508
--- /dev/null
+++ b/public/examples/ts/themeRiver-lastfm.ts
@@ -0,0 +1,82 @@
+/*
+title: ThemeRiver Lastfm
+category: themeRiver
+titleCN: ThemeRiver Lastfm
+*/
+
+
+// From https://github.com/jsundram/streamgraph.js/blob/master/examples/data/lastfm.js
+let rawData = [
+    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+    [0, 49, 67, 16, 0, 19, 19, 0, 0, 1, 10, 5, 6, 1, 1, 0, 25, 0, 0, 0],
+    [0, 6, 3, 34, 0, 16, 1, 0, 0, 1, 6, 0, 1, 56, 0, 2, 0, 2, 0, 0],
+    [0, 8, 13, 15, 0, 12, 23, 0, 0, 1, 0, 1, 0, 0, 6, 0, 0, 1, 0, 1],
+    [0, 9, 28, 0, 91, 6, 1, 0, 0, 0, 7, 18, 0, 9, 16, 0, 1, 0, 0, 0],
+    [0, 3, 42, 36, 21, 0, 1, 0, 0, 0, 0, 16, 30, 1, 4, 62, 55, 1, 0, 0],
+    [0, 7, 13, 12, 64, 5, 0, 0, 0, 8, 17, 3, 72, 1, 1, 53, 1, 0, 0, 0],
+    [1, 14, 13, 7, 8, 8, 7, 0, 1, 1, 14, 6, 44, 8, 7, 17, 21, 1, 0, 0],
+    [0, 6, 14, 2, 14, 1, 0, 0, 0, 0, 2, 2, 7, 15, 6, 3, 0, 0, 0, 0],
+    [0, 9, 11, 3, 0, 8, 0, 0, 14, 2, 0, 1, 1, 1, 7, 13, 2, 1, 0, 0],
+    [0, 7, 5, 10, 8, 21, 0, 0, 130, 1, 2, 18, 6, 1, 5, 1, 4, 1, 0, 7],
+    [0, 2, 15, 1, 5, 5, 0, 0, 6, 0, 0, 0, 4, 1, 3, 1, 17, 0, 0, 9],
+    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+    [6, 27, 26, 1, 0, 11, 1, 0, 0, 0, 1, 1, 2, 0, 0, 9, 1, 0, 0, 0],
+    [31, 81, 11, 6, 11, 0, 0, 0, 0, 0, 0, 0, 3, 2, 0, 3, 14, 0, 0, 12],
+    [19, 53, 6, 20, 0, 4, 37, 0, 30, 86, 43, 7, 5, 7, 17, 19, 2, 0, 0, 5],
+    [0, 22, 14, 6, 10, 24, 18, 0, 13, 21, 5, 2, 13, 35, 7, 1, 8, 0, 0, 1],
+    [0, 56, 5, 0, 0, 0, 0, 0, 7, 24, 0, 17, 7, 0, 0, 3, 0, 0, 0, 8],
+    [18, 29, 3, 6, 11, 0, 15, 0, 12, 42, 37, 0, 3, 3, 13, 8, 0, 0, 0, 1],
+    [32, 39, 37, 3, 33, 21, 6, 0, 4, 17, 0, 11, 8, 2, 3, 0, 23, 0, 0, 17],
+    [72, 15, 28, 0, 0, 0, 0, 0, 1, 3, 0, 35, 0, 9, 17, 1, 9, 1, 0, 8],
+    [11, 15, 4, 2, 0, 18, 10, 0, 20, 3, 0, 0, 2, 0, 0, 2, 2, 30, 0, 0],
+    [14, 29, 19, 3, 2, 17, 13, 0, 7, 12, 2, 0, 6, 0, 0, 1, 1, 34, 0, 1],
+    [1, 1, 7, 6, 1, 1, 15, 1, 1, 2, 1, 3, 1, 1, 9, 1, 1, 25, 1, 72]
+];
+
+let labels = [
+    'The Sea and Cake',
+    'Andrew Bird',
+    'Laura Veirs',
+    'Brian Eno',
+    'Christopher Willits',
+    'Wilco',
+    'Edgar Meyer',
+    'B\xc3\xa9la Fleck',
+    'Fleet Foxes',
+    'Kings of Convenience',
+    'Brett Dennen',
+    'Psapp',
+    'The Bad Plus',
+    'Feist',
+    'Battles',
+    'Avishai Cohen',
+    'Rachael Yamagata',
+    'Norah Jones',
+    'B\xc3\xa9la Fleck and the Flecktones',
+    'Joshua Redman'
+];
+
+let data: [number, number, string][] = [];
+for (let i = 0; i < rawData.length; i++) {
+    for (let j = 0; j < rawData[i].length; j++) {
+        let label = labels[i];
+        data.push([
+            j, rawData[i][j], label
+        ]);
+    }
+}
+
+option = {
+    singleAxis: {
+        max: 'dataMax'
+    },
+    series: [{
+        type: 'themeRiver',
+        data: data,
+        label: {
+            show: false
+        }
+    }]
+};
+
+export {}
\ No newline at end of file
diff --git a/public/examples/ts/tree-basic.ts b/public/examples/ts/tree-basic.ts
new file mode 100644
index 0000000..c5a91b4
--- /dev/null
+++ b/public/examples/ts/tree-basic.ts
@@ -0,0 +1,60 @@
+/*
+title: From Left to Right Tree
+category: tree
+titleCN: 从左到右树状图
+*/
+
+myChart.showLoading();
+$.get(ROOT_PATH + '/data/asset/data/flare.json', function (data) {
+    myChart.hideLoading();
+
+    data.children.forEach(function (datum, index) {
+        index % 2 === 0 && (datum.collapsed = true);
+    });
+
+    myChart.setOption(option = {
+        tooltip: {
+            trigger: 'item',
+            triggerOn: 'mousemove'
+        },
+        series: [
+            {
+                type: 'tree',
+
+                data: [data],
+
+                top: '1%',
+                left: '7%',
+                bottom: '1%',
+                right: '20%',
+
+                symbolSize: 7,
+
+                label: {
+                    position: 'left',
+                    verticalAlign: 'middle',
+                    align: 'right',
+                    fontSize: 9
+                },
+
+                leaves: {
+                    label: {
+                        position: 'right',
+                        verticalAlign: 'middle',
+                        align: 'left'
+                    }
+                },
+
+                emphasis: {
+                    focus: 'descendant'
+                },
+
+                expandAndCollapse: true,
+                animationDuration: 550,
+                animationDurationUpdate: 750
+            }
+        ]
+    });
+});
+
+export {};
\ No newline at end of file
diff --git a/public/examples/ts/tree-legend.ts b/public/examples/ts/tree-legend.ts
new file mode 100644
index 0000000..a07b869
--- /dev/null
+++ b/public/examples/ts/tree-legend.ts
@@ -0,0 +1,261 @@
+/*
+title: Multiple Trees
+category: tree
+titleCN: 多棵树
+*/
+
+myChart.showLoading();
+
+const data = {
+    "name": "flare",
+    "children": [
+        {
+            "name": "data",
+            "children": [
+                {
+                     "name": "converters",
+                     "children": [
+                      {"name": "Converters", "value": 721},
+                      {"name": "DelimitedTextConverter", "value": 4294}
+                     ]
+                },
+                {
+                    "name": "DataUtil",
+                    "value": 3322
+                }
+            ]
+        },
+        {
+            "name": "display",
+            "children": [
+                {"name": "DirtySprite", "value": 8833},
+                {"name": "LineSprite", "value": 1732},
+                {"name": "RectSprite", "value": 3623}
+           ]
+        },
+        {
+            "name": "flex",
+            "children": [
+                {"name": "FlareVis", "value": 4116}
+            ]
+        },
+        {
+           "name": "query",
+           "children": [
+            {"name": "AggregateExpression", "value": 1616},
+            {"name": "And", "value": 1027},
+            {"name": "Arithmetic", "value": 3891},
+            {"name": "Average", "value": 891},
+            {"name": "BinaryExpression", "value": 2893},
+            {"name": "Comparison", "value": 5103},
+            {"name": "CompositeExpression", "value": 3677},
+            {"name": "Count", "value": 781},
+            {"name": "DateUtil", "value": 4141},
+            {"name": "Distinct", "value": 933},
+            {"name": "Expression", "value": 5130},
+            {"name": "ExpressionIterator", "value": 3617},
+            {"name": "Fn", "value": 3240},
+            {"name": "If", "value": 2732},
+            {"name": "IsA", "value": 2039},
+            {"name": "Literal", "value": 1214},
+            {"name": "Match", "value": 3748},
+            {"name": "Maximum", "value": 843},
+            {
+             "name": "methods",
+             "children": [
+              {"name": "add", "value": 593},
+              {"name": "and", "value": 330},
+              {"name": "average", "value": 287},
+              {"name": "count", "value": 277},
+              {"name": "distinct", "value": 292},
+              {"name": "div", "value": 595},
+              {"name": "eq", "value": 594},
+              {"name": "fn", "value": 460},
+              {"name": "gt", "value": 603},
+              {"name": "gte", "value": 625},
+              {"name": "iff", "value": 748},
+              {"name": "isa", "value": 461},
+              {"name": "lt", "value": 597},
+              {"name": "lte", "value": 619},
+              {"name": "max", "value": 283},
+              {"name": "min", "value": 283},
+              {"name": "mod", "value": 591},
+              {"name": "mul", "value": 603},
+              {"name": "neq", "value": 599},
+              {"name": "not", "value": 386},
+              {"name": "or", "value": 323},
+              {"name": "orderby", "value": 307},
+              {"name": "range", "value": 772},
+              {"name": "select", "value": 296},
+              {"name": "stddev", "value": 363},
+              {"name": "sub", "value": 600},
+              {"name": "sum", "value": 280},
+              {"name": "update", "value": 307},
+              {"name": "variance", "value": 335},
+              {"name": "where", "value": 299},
+              {"name": "xor", "value": 354},
+              {"name": "_", "value": 264}
+             ]
+            },
+            {"name": "Minimum", "value": 843},
+            {"name": "Not", "value": 1554},
+            {"name": "Or", "value": 970},
+            {"name": "Query", "value": 13896},
+            {"name": "Range", "value": 1594},
+            {"name": "StringUtil", "value": 4130},
+            {"name": "Sum", "value": 791},
+            {"name": "Variable", "value": 1124},
+            {"name": "Variance", "value": 1876},
+            {"name": "Xor", "value": 1101}
+           ]
+          },
+        {
+           "name": "scale",
+           "children": [
+            {"name": "IScaleMap", "value": 2105},
+            {"name": "LinearScale", "value": 1316},
+            {"name": "LogScale", "value": 3151},
+            {"name": "OrdinalScale", "value": 3770},
+            {"name": "QuantileScale", "value": 2435},
+            {"name": "QuantitativeScale", "value": 4839},
+            {"name": "RootScale", "value": 1756},
+            {"name": "Scale", "value": 4268},
+            {"name": "ScaleType", "value": 1821},
+            {"name": "TimeScale", "value": 5833}
+           ]
+        }
+    ]
+};
+
+var data2 = {
+    "name": "flare",
+    "children": [
+        {
+            "name": "flex",
+            "children": [
+                {"name": "FlareVis", "value": 4116}
+            ]
+        },
+        {
+            "name": "scale",
+            "children": [
+                {"name": "IScaleMap", "value": 2105},
+                {"name": "LinearScale", "value": 1316},
+                {"name": "LogScale", "value": 3151},
+                {"name": "OrdinalScale", "value": 3770},
+                {"name": "QuantileScale", "value": 2435},
+                {"name": "QuantitativeScale", "value": 4839},
+                {"name": "RootScale", "value": 1756},
+                {"name": "Scale", "value": 4268},
+                {"name": "ScaleType", "value": 1821},
+                {"name": "TimeScale", "value": 5833}
+           ]
+        },
+        {
+            "name": "display",
+            "children": [
+                {"name": "DirtySprite", "value": 8833}
+           ]
+        }
+    ]
+};
+
+myChart.hideLoading();
+
+myChart.setOption(option = {
+    tooltip: {
+        trigger: 'item',
+        triggerOn: 'mousemove'
+    },
+    legend: {
+        top: '2%',
+        left: '3%',
+        orient: 'vertical',
+        data: [{
+            name: 'tree1',
+            icon: 'rectangle'
+        },
+        {
+            name: 'tree2',
+            icon: 'rectangle'
+        }],
+        borderColor: '#c23531'
+    },
+    series:[
+        {
+            type: 'tree',
+
+            name: 'tree1',
+
+            data: [data],
+
+            top: '5%',
+            left: '7%',
+            bottom: '2%',
+            right: '60%',
+
+            symbolSize: 7,
+
+            label: {
+                position: 'left',
+                verticalAlign: 'middle',
+                align: 'right'
+            },
+
+            leaves: {
+                label: {
+                    position: 'right',
+                    verticalAlign: 'middle',
+                    align: 'left'
+                }
+            },
+
+            emphasis: {
+                focus: 'descendant'
+            },
+
+            expandAndCollapse: true,
+
+            animationDuration: 550,
+            animationDurationUpdate: 750
+
+        },
+        {
+            type: 'tree',
+            name: 'tree2',
+            data: [data2],
+
+            top: '20%',
+            left: '60%',
+            bottom: '22%',
+            right: '18%',
+
+            symbolSize: 7,
+
+            label: {
+                position: 'left',
+                verticalAlign: 'middle',
+                align: 'right'
+            },
+
+            leaves: {
+                label: {
+                    position: 'right',
+                    verticalAlign: 'middle',
+                    align: 'left'
+                }
+            },
+
+            expandAndCollapse: true,
+
+            emphasis: {
+                focus: 'descendant'
+            },
+
+            animationDuration: 550,
+            animationDurationUpdate: 750
+        }
+    ]
+});
+
+export {};
\ No newline at end of file
diff --git a/public/examples/ts/tree-orient-bottom-top.ts b/public/examples/ts/tree-orient-bottom-top.ts
new file mode 100644
index 0000000..c29d795
--- /dev/null
+++ b/public/examples/ts/tree-orient-bottom-top.ts
@@ -0,0 +1,61 @@
+/*
+title: From Bottom to Top Tree
+category: tree
+titleCN: 从下到上树状图
+*/
+
+myChart.showLoading();
+$.get(ROOT_PATH + '/data/asset/data/flare.json', function (data) {
+    myChart.hideLoading();
+
+    myChart.setOption(option = {
+
+        tooltip: {
+            trigger: 'item',
+            triggerOn: 'mousemove'
+        },
+
+        series:[
+            {
+                type: 'tree',
+
+                data: [data],
+
+                left: '2%',
+                right: '2%',
+                top: '20%',
+                bottom: '8%',
+
+                symbol: 'emptyCircle',
+
+                orient: 'BT',
+
+                expandAndCollapse: true,
+
+                label: {
+                    position: 'bottom',
+                    rotate: 90,
+                    verticalAlign: 'middle',
+                    align: 'right'
+                },
+
+                leaves: {
+                    label: {
+                        position: 'top',
+                        rotate: 90,
+                        verticalAlign: 'middle',
+                        align: 'left'
+                    }
+                },
+
+                emphasis: {
+                    focus: 'descendant'
+                },
+
+                animationDurationUpdate: 750
+            }
+        ]
+    });
+});
+
+export {}
\ No newline at end of file
diff --git a/public/examples/ts/tree-orient-right-left.ts b/public/examples/ts/tree-orient-right-left.ts
new file mode 100644
index 0000000..918a116
--- /dev/null
+++ b/public/examples/ts/tree-orient-right-left.ts
@@ -0,0 +1,64 @@
+/*
+title: From Right to Left Tree
+category: tree
+titleCN: 从右到左树状图
+*/
+
+
+myChart.showLoading();
+$.get(ROOT_PATH + '/data/asset/data/flare.json', function (data) {
+    myChart.hideLoading();
+
+    data.children.forEach(function (datum, index) {
+        index % 2 === 0 && (datum.collapsed = true);
+    });
+
+    myChart.setOption(option = {
+
+        tooltip: {
+            trigger: 'item',
+            triggerOn: 'mousemove'
+        },
+
+        series:[
+            {
+                type: 'tree',
+
+                data: [data],
+
+                top: '1%',
+                left: '15%',
+                bottom: '1%',
+                right: '7%',
+
+                symbolSize: 7,
+
+                orient: 'RL',
+
+                label: {
+                    position: 'right',
+                    verticalAlign: 'middle',
+                    align: 'left'
+                },
+
+                leaves: {
+                    label: {
+                        position: 'left',
+                        verticalAlign: 'middle',
+                        align: 'right'
+                    }
+                },
+
+                emphasis: {
+                    focus: 'descendant'
+                },
+
+                expandAndCollapse: true,
+                animationDuration: 550,
+                animationDurationUpdate: 750
+            }
+        ]
+    });
+});
+
+export {}
\ No newline at end of file
diff --git a/public/examples/ts/tree-polyline.ts b/public/examples/ts/tree-polyline.ts
new file mode 100644
index 0000000..cac82c6
--- /dev/null
+++ b/public/examples/ts/tree-polyline.ts
@@ -0,0 +1,181 @@
+/*
+title: Tree with Polyline Edge
+category: tree
+titleCN: 折线树图
+*/
+
+const data = {
+    "name": "flare",
+    "children": [
+        {
+            "name": "data",
+            "children": [
+                {
+                    "name": "converters",
+                    "children": [
+                        {"name": "Converters", "value": 721},
+                        {"name": "DelimitedTextConverter", "value": 4294}
+                    ]
+                },
+                {
+                    "name": "DataUtil",
+                    "value": 3322
+                }
+            ]
+        },
+        {
+            "name": "display",
+            "children": [
+                {"name": "DirtySprite", "value": 8833},
+                {"name": "LineSprite", "value": 1732},
+                {"name": "RectSprite", "value": 3623}
+            ]
+        },
+        {
+            "name": "flex",
+            "children": [
+                {"name": "FlareVis", "value": 4116}
+            ]
+        },
+        {
+            "name": "query",
+            "children": [
+                {"name": "AggregateExpression", "value": 1616},
+                {"name": "And", "value": 1027},
+                {"name": "Arithmetic", "value": 3891},
+                {"name": "Average", "value": 891},
+                {"name": "BinaryExpression", "value": 2893},
+                {"name": "Comparison", "value": 5103},
+                {"name": "CompositeExpression", "value": 3677},
+                {"name": "Count", "value": 781},
+                {"name": "DateUtil", "value": 4141},
+                {"name": "Distinct", "value": 933},
+                {"name": "Expression", "value": 5130},
+                {"name": "ExpressionIterator", "value": 3617},
+                {"name": "Fn", "value": 3240},
+                {"name": "If", "value": 2732},
+                {"name": "IsA", "value": 2039},
+                {"name": "Literal", "value": 1214},
+                {"name": "Match", "value": 3748},
+                {"name": "Maximum", "value": 843},
+                {
+                    "name": "methods",
+                    "children": [
+                        {"name": "add", "value": 593},
+                        {"name": "and", "value": 330},
+                        {"name": "average", "value": 287},
+                        {"name": "count", "value": 277},
+                        {"name": "distinct", "value": 292},
+                        {"name": "div", "value": 595},
+                        {"name": "eq", "value": 594},
+                        {"name": "fn", "value": 460},
+                        {"name": "gt", "value": 603},
+                        {"name": "gte", "value": 625},
+                        {"name": "iff", "value": 748},
+                        {"name": "isa", "value": 461},
+                        {"name": "lt", "value": 597},
+                        {"name": "lte", "value": 619},
+                        {"name": "max", "value": 283},
+                        {"name": "min", "value": 283},
+                        {"name": "mod", "value": 591},
+                        {"name": "mul", "value": 603},
+                        {"name": "neq", "value": 599},
+                        {"name": "not", "value": 386},
+                        {"name": "or", "value": 323},
+                        {"name": "orderby", "value": 307},
+                        {"name": "range", "value": 772},
+                        {"name": "select", "value": 296},
+                        {"name": "stddev", "value": 363},
+                        {"name": "sub", "value": 600},
+                        {"name": "sum", "value": 280},
+                        {"name": "update", "value": 307},
+                        {"name": "variance", "value": 335},
+                        {"name": "where", "value": 299},
+                        {"name": "xor", "value": 354},
+                        {"name": "x_x", "value": 264}
+                    ]
+                },
+                {"name": "Minimum", "value": 843},
+                {"name": "Not", "value": 1554},
+                {"name": "Or", "value": 970},
+                {"name": "Query", "value": 13896},
+                {"name": "Range", "value": 1594},
+                {"name": "StringUtil", "value": 4130},
+                {"name": "Sum", "value": 791},
+                {"name": "Variable", "value": 1124},
+                {"name": "Variance", "value": 1876},
+                {"name": "Xor", "value": 1101}
+            ]
+        },
+        {
+            "name": "scale",
+            "children": [
+                {"name": "IScaleMap", "value": 2105},
+                {"name": "LinearScale", "value": 1316},
+                {"name": "LogScale", "value": 3151},
+                {"name": "OrdinalScale", "value": 3770},
+                {"name": "QuantileScale", "value": 2435},
+                {"name": "QuantitativeScale", "value": 4839},
+                {"name": "RootScale", "value": 1756},
+                {"name": "Scale", "value": 4268},
+                {"name": "ScaleType", "value": 1821},
+                {"name": "TimeScale", "value": 5833}
+            ]
+        }
+    ]
+};
+
+option = {
+    tooltip: {
+        trigger: 'item',
+        triggerOn: 'mousemove'
+    },
+    series:[
+        {
+            type: 'tree',
+            id: 0,
+            name: 'tree1',
+            data: [data],
+
+            top: '10%',
+            left: '8%',
+            bottom: '22%',
+            right: '20%',
+
+            symbolSize: 7,
+
+            edgeShape: 'polyline',
+            edgeForkPosition: '63%',
+            initialTreeDepth: 3,
+
+            lineStyle: {
+                width: 2
+            },
+
+            label: {
+                backgroundColor: '#fff',
+                position: 'left',
+                verticalAlign: 'middle',
+                align: 'right'
+            },
+
+            leaves: {
+                label: {
+                    position: 'right',
+                    verticalAlign: 'middle',
+                    align: 'left'
+                }
+            },
+
+            emphasis: {
+                focus: 'descendant'
+            },
+
+            expandAndCollapse: true,
+            animationDuration: 550,
+            animationDurationUpdate: 750
+        }
+    ]
+};
+
+export {}
\ No newline at end of file
diff --git a/public/examples/ts/tree-radial.ts b/public/examples/ts/tree-radial.ts
new file mode 100644
index 0000000..f6daff2
--- /dev/null
+++ b/public/examples/ts/tree-radial.ts
@@ -0,0 +1,43 @@
+/*
+title: Radial Tree
+category: tree
+titleCN: 径向树状图
+*/
+
+myChart.showLoading();
+$.get(ROOT_PATH + '/data/asset/data/flare.json', function (data) {
+    myChart.hideLoading();
+
+    myChart.setOption(option = {
+        tooltip: {
+            trigger: 'item',
+            triggerOn: 'mousemove'
+        },
+        series: [
+            {
+                type: 'tree',
+
+                data: [data],
+
+                top: '18%',
+                bottom: '14%',
+
+                layout: 'radial',
+
+                symbol: 'emptyCircle',
+
+                symbolSize: 7,
+
+                initialTreeDepth: 3,
+
+                animationDurationUpdate: 750,
+
+                emphasis: {
+                    focus: 'descendant'
+                }
+            }
+        ]
+    });
+});
+
+export {};
\ No newline at end of file
diff --git a/public/examples/ts/tree-vertical.ts b/public/examples/ts/tree-vertical.ts
new file mode 100644
index 0000000..c5527a9
--- /dev/null
+++ b/public/examples/ts/tree-vertical.ts
@@ -0,0 +1,56 @@
+/*
+title: From Top to Bottom Tree
+category: tree
+titleCN: 从上到下树状图
+*/
+
+myChart.showLoading();
+$.get(ROOT_PATH + '/data/asset/data/flare.json', function (data) {
+    myChart.hideLoading();
+
+    myChart.setOption(option = {
+        tooltip: {
+            trigger: 'item',
+            triggerOn: 'mousemove'
+        },
+        series:[
+            {
+                type: 'tree',
+
+                data: [data],
+
+                left: '2%',
+                right: '2%',
+                top: '8%',
+                bottom: '20%',
+
+                symbol: 'emptyCircle',
+
+                orient: 'vertical',
+
+                expandAndCollapse: true,
+
+                label: {
+                    position: 'top',
+                    rotate: -90,
+                    verticalAlign: 'middle',
+                    align: 'right',
+                    fontSize: 9
+                },
+
+                leaves: {
+                    label: {
+                        position: 'bottom',
+                        rotate: -90,
+                        verticalAlign: 'middle',
+                        align: 'left'
+                    }
+                },
+
+                animationDurationUpdate: 750
+            }
+        ]
+    });
+});
+
+export {};
\ No newline at end of file
diff --git a/public/examples/ts/treemap-disk.ts b/public/examples/ts/treemap-disk.ts
new file mode 100644
index 0000000..0778051
--- /dev/null
+++ b/public/examples/ts/treemap-disk.ts
@@ -0,0 +1,80 @@
+/*
+title: Disk Usage
+category: treemap
+titleCN: 磁盘占用
+*/
+
+myChart.showLoading();
+
+$.get(ROOT_PATH + '/data/asset/data/disk.tree.json', function (diskData) {
+    myChart.hideLoading();
+
+    const formatUtil = echarts.format;
+
+    function getLevelOption() {
+        return [
+            {
+                itemStyle: {
+                    borderWidth: 0,
+                    gapWidth: 5
+                }
+            },
+            {
+                itemStyle: {
+                    gapWidth: 1
+                }
+            },
+            {
+                colorSaturation: [0.35, 0.5],
+                itemStyle: {
+                    gapWidth: 1,
+                    borderColorSaturation: 0.6
+                }
+            }
+        ];
+    }
+
+    myChart.setOption(option = {
+
+        title: {
+            text: 'Disk Usage',
+            left: 'center'
+        },
+
+        tooltip: {
+            formatter: function (info: any) {
+                var value = info.value;
+                var treePathInfo = info.treePathInfo;
+                var treePath = [];
+
+                for (var i = 1; i < treePathInfo.length; i++) {
+                    treePath.push(treePathInfo[i].name);
+                }
+
+                return [
+                    '<div class="tooltip-title">' + formatUtil.encodeHTML(treePath.join('/')) + '</div>',
+                    'Disk Usage: ' + formatUtil.addCommas(value) + ' KB',
+                ].join('');
+            }
+        },
+
+        series: [
+            {
+                name: 'Disk Usage',
+                type: 'treemap',
+                visibleMin: 300,
+                label: {
+                    show: true,
+                    formatter: '{b}'
+                },
+                itemStyle: {
+                    borderColor: '#fff'
+                },
+                levels: getLevelOption(),
+                data: diskData
+            }
+        ]
+    });
+});
+
+export {}
\ No newline at end of file
diff --git a/public/examples/ts/treemap-drill-down.ts b/public/examples/ts/treemap-drill-down.ts
new file mode 100644
index 0000000..434bdbd
--- /dev/null
+++ b/public/examples/ts/treemap-drill-down.ts
@@ -0,0 +1,100 @@
+/*
+title: ECharts Option Query
+category: treemap
+titleCN: ECharts 配置项查询分布
+*/
+
+type RawNode = {
+    [key: string]: RawNode
+} & {
+    $count: number
+}
+
+interface TreeNode {
+    name: string
+    value: number
+    children?: TreeNode[]
+}
+
+const uploadedDataURL = ROOT_PATH + '/data/asset/data/ec-option-doc-statistics-201604.json';
+
+myChart.showLoading();
+
+$.getJSON(uploadedDataURL, function (rawData) {
+
+    myChart.hideLoading();
+
+    function convert(source: RawNode, target: TreeNode, basePath: string) {
+        for (let key in source) {
+            let path = basePath ? (basePath + '.' + key) : key;
+            if (!key.match(/^\$/)) {
+                target.children = target.children || [];
+                const child = {
+                    name: path
+                } as TreeNode;
+                target.children.push(child);
+                convert(source[key], child, path);
+            }
+        }
+
+        if (!target.children) {
+            target.value = source.$count || 1;
+        }
+        else {
+            target.children.push({
+                name: basePath,
+                value: source.$count
+            });
+        }
+    }
+
+    const data = {
+        children: [] as TreeNode[]
+    } as TreeNode;
+
+    convert(rawData, data, '');
+
+    myChart.setOption(option = {
+        title: {
+            text: 'ECharts Options',
+            subtext: '2016/04',
+            left: 'leafDepth'
+        },
+        tooltip: {},
+        series: [{
+            name: 'option',
+            type: 'treemap',
+            visibleMin: 300,
+            data: data.children,
+            leafDepth: 2,
+            levels: [
+                {
+                    itemStyle: {
+                        borderColor: '#555',
+                        borderWidth: 4,
+                        gapWidth: 4
+                    }
+                },
+                {
+                    colorSaturation: [0.3, 0.6],
+                    itemStyle: {
+                        borderColorSaturation: 0.7,
+                        gapWidth: 2,
+                        borderWidth: 2
+                    }
+                },
+                {
+                    colorSaturation: [0.3, 0.5],
+                    itemStyle: {
+                        borderColorSaturation: 0.6,
+                        gapWidth: 1
+                    }
+                },
+                {
+                    colorSaturation: [0.3, 0.5]
+                }
+            ]
+        }]
+    });
+});
+export {}
\ No newline at end of file
diff --git a/public/examples/ts/treemap-obama.ts b/public/examples/ts/treemap-obama.ts
new file mode 100644
index 0000000..2a3d702
--- /dev/null
+++ b/public/examples/ts/treemap-obama.ts
@@ -0,0 +1,225 @@
+/*
+title: How $3.7 Trillion is Spent
+category: treemap
+titleCN: How $3.7 Trillion is Spent
+*/
+
+type Mode = number;
+interface TreeNode {
+    name: string
+    id: string
+    value: number[]
+
+    children?: TreeNode[]
+}
+
+myChart.showLoading();
+
+const household_america_2012 = 113616229;
+$.get(ROOT_PATH + '/data/asset/data/obama_budget_proposal_2012.json', function (obama_budget_2012) {
+    myChart.hideLoading();
+
+    function buildData(mode: Mode, originList: TreeNode[]) {
+        let out: TreeNode[] = [];
+
+        for (let i = 0; i < originList.length; i++) {
+            let node = originList[i];
+            let newNode = cloneNodeInfo(node);
+
+            if (!newNode) {
+                continue;
+            }
+            out[i] = newNode;
+            let value = newNode.value;
+
+            // Calculate amount per household.
+            value[3] = value[0] / household_america_2012;
+
+            // if mode === 0 and mode === 2 do nothing
+            if (mode === 1) {
+                // Set 'Change from 2010' to value[0].
+                let tmp = value[1];
+                value[1] = value[0];
+                value[0] = tmp;
+            }
+
+            if (node.children) {
+                newNode.children = buildData(mode, node.children);
+            }
+        }
+
+        return out;
+    }
+
+    function cloneNodeInfo(node?: TreeNode) {
+        if (!node) {
+            return;
+        }
+
+        const newNode = {} as TreeNode;
+        newNode.name = node.name;
+        newNode.id = node.id;
+        newNode.value = (node.value || []).slice();
+        return newNode;
+    }
+
+    function getLevelOption(mode: Mode): echarts.TreemapSeriesOption['levels'] {
+        return [
+            {
+                color: mode === 2
+                    ? [
+                        '#c23531', '#314656', '#61a0a8', '#dd8668',
+                        '#91c7ae', '#6e7074', '#61a0a8', '#bda29a',
+                        '#44525d', '#c4ccd3'
+                    ]
+                    : undefined,
+                colorMappingBy: 'id',
+                itemStyle: {
+                    borderWidth: 3,
+                    gapWidth: 3
+                }
+            },
+            {
+                colorAlpha: mode === 2
+                    ? [0.5, 1] : undefined,
+                itemStyle: {
+                    gapWidth: 1
+                }
+            }
+        ];
+    }
+
+    function isValidNumber(num: number) {
+        return num != null && isFinite(num);
+    }
+
+    function getTooltipFormatter(mode: Mode) {
+        let amountIndex = mode === 1 ? 1 : 0;
+        let amountIndex2011 = mode === 1 ? 0 : 1;
+
+        return function (info: any) {
+            let value = info.value;
+
+            let amount = value[amountIndex];
+            amount = isValidNumber(amount)
+                ? echarts.format.addCommas(amount * 1000) + '$'
+                : '-';
+
+            let amount2011 = value[amountIndex2011];
+            amount2011 = isValidNumber(amount2011)
+                ? echarts.format.addCommas(amount2011 * 1000) + '$'
+                : '-';
+
+            let perHousehold = value[3];
+            perHousehold = isValidNumber(perHousehold)
+                ? echarts.format.addCommas((+perHousehold.toFixed(4)) * 1000) + '$'
+                : '-';
+
+            let change = value[2];
+            change = isValidNumber(change)
+                ? change.toFixed(2) + '%'
+                : '-';
+
+            return [
+                '<div class="tooltip-title">' + echarts.format.encodeHTML(info.name) + '</div>',
+                '2012 Amount: &nbsp;&nbsp;' + amount + '<br>',
+                'Per Household: &nbsp;&nbsp;' + perHousehold + '<br>',
+                '2011 Amount: &nbsp;&nbsp;' + amount2011 + '<br>',
+                'Change From 2011: &nbsp;&nbsp;' + change
+            ].join('');
+        };
+    }
+
+    function createSeriesCommon(mode: Mode): echarts.TreemapSeriesOption {
+        return {
+            type: 'treemap',
+            tooltip: {
+                formatter: getTooltipFormatter(mode)
+            },
+            label: {
+                position: 'insideTopLeft',
+                formatter: function (params: any) {
+                    let arr = [
+                        '{name|' + params.name + '}',
+                        '{hr|}',
+                        '{budget|$ ' + echarts.format.addCommas(params.value[0]) + '} {label|budget}'
+                    ];
+
+                    mode !== 1 && arr.push(
+                        '{household|$ ' + echarts.format.addCommas((+params.value[3].toFixed(4)) * 1000) + '} {label|per household}'
+                    );
+
+                    return arr.join('\n');
+                },
+                rich: {
+                    budget: {
+                        fontSize: 22,
+                        lineHeight: 30,
+                        color: 'yellow'
+                    },
+                    household: {
+                        fontSize: 14,
+                        color: '#fff'
+                    },
+                    label: {
+                        fontSize: 9,
+                        backgroundColor: 'rgba(0,0,0,0.3)',
+                        color: '#fff',
+                        borderRadius: 2,
+                        padding: [2, 4],
+                        lineHeight: 25,
+                        align: 'right'
+                    },
+                    name: {
+                        fontSize: 12,
+                        color: '#fff'
+                    },
+                    hr: {
+                        width: '100%',
+                        borderColor: 'rgba(255,255,255,0.2)',
+                        borderWidth: 0.5,
+                        height: 0,
+                        lineHeight: 10
+                    }
+                }
+            },
+            itemStyle: {
+                borderColor: 'black'
+            },
+            levels: getLevelOption(0)
+        };
+    }
+
+    let modes = ['2012Budget', '2011Budget', 'Growth'];
+
+    myChart.setOption(option = {
+        title: {
+            top: 5,
+            left: 'center',
+            text: 'How $3.7 Trillion is Spent',
+            subtext: 'Obama’s 2012 Budget Proposal'
+        },
+
+        legend: {
+            data: modes,
+            selectedMode: 'single',
+            top: 55,
+            itemGap: 5,
+            borderRadius: 5
+        },
+
+        tooltip: {},
+
+        series: modes.map(function (mode, idx) {
+            let seriesOpt = createSeriesCommon(idx);
+            seriesOpt.name = mode;
+            seriesOpt.top = 80;
+            seriesOpt.visualDimension = idx === 2 ? 2 : undefined;
+            seriesOpt.data = buildData(idx, obama_budget_2012);
+            seriesOpt.levels = getLevelOption(idx);
+            return seriesOpt;
+        })
+    });
+});
+
+export {}
\ No newline at end of file
diff --git a/public/examples/ts/treemap-show-parent.ts b/public/examples/ts/treemap-show-parent.ts
new file mode 100644
index 0000000..c8e216a
--- /dev/null
+++ b/public/examples/ts/treemap-show-parent.ts
@@ -0,0 +1,94 @@
+/*
+title: Show Parent Labels
+category: treemap
+titleCN: 显示父层级标签
+*/
+
+myChart.showLoading();
+
+$.get(ROOT_PATH + '/data/asset/data/disk.tree.json', function (diskData) {
+    myChart.hideLoading();
+
+    function getLevelOption() {
+        return [
+            {
+                itemStyle: {
+                    borderColor: '#777',
+                    borderWidth: 0,
+                    gapWidth: 1
+                },
+                upperLabel: {
+                    show: false
+                }
+            },
+            {
+                itemStyle: {
+                    borderColor: '#555',
+                    borderWidth: 5,
+                    gapWidth: 1
+                },
+                emphasis: {
+                    itemStyle: {
+                        borderColor: '#ddd'
+                    }
+                }
+            },
+            {
+                colorSaturation: [0.35, 0.5],
+                itemStyle: {
+                    borderWidth: 5,
+                    gapWidth: 1,
+                    borderColorSaturation: 0.6
+                }
+            }
+        ];
+    }
+
+    myChart.setOption(option = {
+
+        title: {
+            text: 'Disk Usage',
+            left: 'center'
+        },
+
+        tooltip: {
+            formatter: function (info: any) {
+                var value = info.value;
+                var treePathInfo = info.treePathInfo;
+                var treePath = [];
+
+                for (var i = 1; i < treePathInfo.length; i++) {
+                    treePath.push(treePathInfo[i].name);
+                }
+
+                return [
+                    '<div class="tooltip-title">' + echarts.format.encodeHTML(treePath.join('/')) + '</div>',
+                    'Disk Usage: ' + echarts.format.addCommas(value) + ' KB',
+                ].join('');
+            }
+        },
+
+        series: [
+            {
+                name: 'Disk Usage',
+                type: 'treemap',
+                visibleMin: 300,
+                label: {
+                    show: true,
+                    formatter: '{b}'
+                },
+                upperLabel: {
+                    show: true,
+                    height: 30
+                },
+                itemStyle: {
+                    borderColor: '#fff'
+                },
+                levels: getLevelOption(),
+                data: diskData
+            }
+        ]
+    });
+});
+
+export {}
\ No newline at end of file
diff --git a/public/examples/ts/treemap-simple.ts b/public/examples/ts/treemap-simple.ts
new file mode 100644
index 0000000..6dd09f0
--- /dev/null
+++ b/public/examples/ts/treemap-simple.ts
@@ -0,0 +1,35 @@
+/*
+title: Basic Treemap
+category: treemap
+titleCN: 基础矩形树图
+*/
+
+option = {
+    series: [{
+        type: 'treemap',
+        data: [{
+            name: 'nodeA',            // First tree
+            value: 10,
+            children: [{
+                name: 'nodeAa',       // First leaf of first tree
+                value: 4
+            }, {
+                name: 'nodeAb',       // Second leaf of first tree
+                value: 6
+            }]
+        }, {
+            name: 'nodeB',            // Second tree
+            value: 20,
+            children: [{
+                name: 'nodeBa',       // Son of first tree
+                value: 20,
+                children: [{
+                    name: 'nodeBa1',  // Granson of first tree
+                    value: 20
+                }]
+            }]
+        }]
+    }]
+};
+
+export {}
\ No newline at end of file
diff --git a/public/examples/ts/treemap-sunburst-transition.ts b/public/examples/ts/treemap-sunburst-transition.ts
new file mode 100644
index 0000000..c1a8f33
--- /dev/null
+++ b/public/examples/ts/treemap-sunburst-transition.ts
@@ -0,0 +1,58 @@
+/*
+title: Transition between Treemap and Sunburst
+category: treemap
+titleCN: 矩形树图和旭日图的动画过渡
+difficulty: 4
+videoStart: 3000
+videoEnd: 9000
+*/
+
+$.getJSON(ROOT_PATH + '/data/asset/data/echarts-package-size.json', function (data) {
+    const treemapOption: echarts.EChartsOption = {
+        series: [{
+            type: 'treemap',
+            id: 'echarts-package-size',
+            animationDurationUpdate: 1000,
+            roam: false,
+            nodeClick: undefined,
+            data: data.children,
+            universalTransition: true,
+            label: {
+                show: true
+            },
+            breadcrumb: {
+                show: false
+            }
+        }]
+    };
+
+    const sunburstOption: echarts.EChartsOption = {
+        series: [{
+            type: 'sunburst',
+            id: 'echarts-package-size',
+            radius: ['20%', '90%'],
+            animationDurationUpdate: 1000,
+            nodeClick: undefined,
+            data: data.children,
+            universalTransition: true,
+            itemStyle: {
+                borderWidth: 1,
+                borderColor: 'rgba(255,255,255,.5)'
+            },
+            label: {
+                show: false
+            }
+        }]
+    };
+
+    let currentOption = treemapOption;
+
+    myChart.setOption(currentOption);
+
+    setInterval(function () {
+        currentOption = currentOption === treemapOption ? sunburstOption : treemapOption;
+        myChart.setOption(currentOption);
+    }, 3000);
+});
+
+export {}
\ No newline at end of file
diff --git a/public/examples/ts/treemap-visual.ts b/public/examples/ts/treemap-visual.ts
new file mode 100644
index 0000000..182e965
--- /dev/null
+++ b/public/examples/ts/treemap-visual.ts
@@ -0,0 +1,145 @@
+/*
+title: Gradient Mapping
+category: treemap
+titleCN: 映射为渐变色
+*/
+
+interface TreeNode {
+    name: string
+    id: string
+    value: number[]
+
+    children?: TreeNode[]
+}
+
+myChart.showLoading();
+
+const household_america_2012 = 113616229;
+$.get(ROOT_PATH + '/data/asset/data/obama_budget_proposal_2012.json', function (obama_budget_2012) {
+    myChart.hideLoading();
+
+    const visualMin = -100;
+    const visualMax = 100;
+    const visualMinBound = -40;
+    const visualMaxBound = 40;
+
+    convertData(obama_budget_2012);
+
+    function convertData(originList: TreeNode[]) {
+        let min = Infinity;
+        let max = -Infinity;
+
+        for (let i = 0; i < originList.length; i++) {
+            let node = originList[i];
+            if (node) {
+                let value = node.value;
+                value[2] != null && value[2] < min && (min = value[2]);
+                value[2] != null && value[2] > max && (max = value[2]);
+            }
+        }
+
+        for (let i = 0; i < originList.length; i++) {
+            let node = originList[i];
+            if (node) {
+                let value = node.value;
+
+                // Scale value for visual effect
+                if (value[2] != null && value[2] > 0) {
+                    value[3] = echarts.number.linearMap(
+                        value[2], [0, max], [visualMaxBound, visualMax], true
+                    );
+                }
+                else if (value[2] != null && value[2] < 0) {
+                    value[3] = echarts.number.linearMap(
+                        value[2], [min, 0], [visualMin, visualMinBound], true
+                    );
+                }
+                else {
+                    value[3] = 0;
+                }
+
+                if (!isFinite(value[3])) {
+                    value[3] = 0;
+                }
+
+                if (node.children) {
+                    convertData(node.children);
+                }
+            }
+        }
+    }
+
+
+    function isValidNumber(num: number) {
+        return num != null && isFinite(num);
+    }
+
+    myChart.setOption(option = {
+        title: {
+            left: 'center',
+            text: 'Gradient Mapping',
+            subtext: 'Growth > 0: green; Growth < 0: red; Growth = 0: grey'
+        },
+        tooltip: {
+            formatter: function (info: any) {
+                let value = info.value;
+
+                let amount = value[0];
+                amount = isValidNumber(amount)
+                    ? echarts.format.addCommas(amount * 1000) + '$'
+                    : '-';
+
+                let amount2011 = value[1];
+                amount2011 = isValidNumber(amount2011)
+                    ? echarts.format.addCommas(amount2011 * 1000) + '$'
+                    : '-';
+
+                let change = value[2];
+                change = isValidNumber(change)
+                    ? change.toFixed(2) + '%'
+                    : '-';
+
+                return [
+                    '<div class="tooltip-title">' + echarts.format.encodeHTML(info.name) + '</div>',
+                    '2012 Amount: &nbsp;&nbsp;' + amount + '<br>',
+                    '2011 Amount: &nbsp;&nbsp;' + amount2011 + '<br>',
+                    'Change From 2011: &nbsp;&nbsp;' + change
+                ].join('');
+            }
+        },
+        series: [{
+            name: 'ALL',
+            top: 80,
+            type: 'treemap',
+            label: {
+                show: true,
+                formatter: "{b}",
+                ellipsis: true
+            },
+            itemStyle: {
+                borderColor: 'black'
+            },
+            visualMin: visualMin,
+            visualMax: visualMax,
+            visualDimension: 3,
+            levels: [
+                {
+                    itemStyle: {
+                        borderWidth: 3,
+                        borderColor: '#333',
+                        gapWidth: 3
+                    }
+                },
+                {
+                    color: ['#942e38', '#aaa', '#269f3c'],
+                    colorMappingBy: 'value',
+                    itemStyle: {
+                        gapWidth: 1
+                    }
+                }
+            ],
+            data: obama_budget_2012
+        }]
+    });
+});
+export {}
\ No newline at end of file
diff --git a/public/examples/ts/watermark.ts b/public/examples/ts/watermark.ts
new file mode 100644
index 0000000..3cd1e37
--- /dev/null
+++ b/public/examples/ts/watermark.ts
@@ -0,0 +1,220 @@
+/*
+title: Watermark - ECharts Download
+category: bar
+titleCN: 水印 - ECharts 下载统计
+difficulty: 6
+*/
+
+const builderJson = {
+  "all": 10887,
+  "charts": {
+    "map": 3237,
+    "lines": 2164,
+    "bar": 7561,
+    "line": 7778,
+    "pie": 7355,
+    "scatter": 2405,
+    "candlestick": 1842,
+    "radar": 2090,
+    "heatmap": 1762,
+    "treemap": 1593,
+    "graph": 2060,
+    "boxplot": 1537,
+    "parallel": 1908,
+    "gauge": 2107,
+    "funnel": 1692,
+    "sankey": 1568
+  } as Record<string, number>,
+  "components": {
+    "geo": 2788,
+    "title": 9575,
+    "legend": 9400,
+    "tooltip": 9466,
+    "grid": 9266,
+    "markPoint": 3419,
+    "markLine": 2984,
+    "timeline": 2739,
+    "dataZoom": 2744,
+    "visualMap": 2466,
+    "toolbox": 3034,
+    "polar": 1945
+  } as Record<string, number>,
+  "ie": 9743
+};
+
+const downloadJson: Record<string, number> = {
+  "echarts.min.js": 17365,
+  "echarts.simple.min.js": 4079,
+  "echarts.common.min.js": 6929,
+  "echarts.js": 14890
+};
+
+const themeJson: Record<string, number> = {
+  "dark.js": 1594,
+  "infographic.js": 925,
+  "shine.js": 1608,
+  "roma.js": 721,
+  "macarons.js": 2179,
+  "vintage.js": 1982
+};
+
+const waterMarkText = 'ECHARTS';
+
+const canvas = document.createElement('canvas');
+const ctx = canvas.getContext('2d')!;
+canvas.width = canvas.height = 100;
+ctx.textAlign = 'center';
+ctx.textBaseline = 'middle';
+ctx.globalAlpha = 0.08;
+ctx.font = '20px Microsoft Yahei';
+ctx.translate(50, 50);
+ctx.rotate(-Math.PI / 4);
+ctx.fillText(waterMarkText, 0, 0);
+
+option = {
+    backgroundColor: {
+        type: 'pattern',
+        image: canvas,
+        repeat: 'repeat'
+    },
+    tooltip: {},
+    title: [{
+        text: '在线构建',
+        subtext: '总计 ' + builderJson.all,
+        left: '25%',
+        textAlign: 'center'
+    }, {
+        text: '各版本下载',
+        subtext: '总计 ' + Object.keys(downloadJson).reduce(function (all, key) {
+            return all + downloadJson[key];
+        }, 0),
+        left: '75%',
+        textAlign: 'center'
+    }, {
+        text: '主题下载',
+        subtext: '总计 ' + Object.keys(themeJson).reduce(function (all, key) {
+            return all + themeJson[key];
+        }, 0),
+        left: '75%',
+        top: '50%',
+        textAlign: 'center'
+    }],
+    grid: [{
+        top: 50,
+        width: '50%',
+        bottom: '45%',
+        left: 10,
+        containLabel: true
+    }, {
+        top: '55%',
+        width: '50%',
+        bottom: 0,
+        left: 10,
+        containLabel: true
+    }],
+    xAxis: [{
+        type: 'value',
+        max: builderJson.all,
+        splitLine: {
+            show: false
+        }
+    }, {
+        type: 'value',
+        max: builderJson.all,
+        gridIndex: 1,
+        splitLine: {
+            show: false
+        }
+    }],
+    yAxis: [{
+        type: 'category',
+        data: Object.keys(builderJson.charts),
+        axisLabel: {
+            interval: 0,
+            rotate: 30
+        },
+        splitLine: {
+            show: false
+        }
+    }, {
+        gridIndex: 1,
+        type: 'category',
+        data: Object.keys(builderJson.components),
+        axisLabel: {
+            interval: 0,
+            rotate: 30
+        },
+        splitLine: {
+            show: false
+        }
+    }],
+    series: [{
+        type: 'bar',
+        stack: 'chart',
+        z: 3,
+        label: {
+            position: 'right',
+            show: true
+        },
+        data: Object.keys(builderJson.charts).map(function (key) {
+            return builderJson.charts[key];
+        })
+    }, {
+        type: 'bar',
+        stack: 'chart',
+        silent: true,
+        itemStyle: {
+            color: '#eee'
+        },
+        data: Object.keys(builderJson.charts).map(function (key) {
+            return builderJson.all - builderJson.charts[key];
+        })
+    }, {
+        type: 'bar',
+        stack: 'component',
+        xAxisIndex: 1,
+        yAxisIndex: 1,
+        z: 3,
+        label: {
+            position: 'right',
+            show: true
+        },
+        data: Object.keys(builderJson.components).map(function (key) {
+            return builderJson.components[key];
+        })
+    }, {
+        type: 'bar',
+        stack: 'component',
+        silent: true,
+        xAxisIndex: 1,
+        yAxisIndex: 1,
+        itemStyle: {
+            color: '#eee'
+        },
+        data: Object.keys(builderJson.components).map(function (key) {
+            return builderJson.all - builderJson.components[key];
+        })
+    }, {
+        type: 'pie',
+        radius: [0, '30%'],
+        center: ['75%', '25%'],
+        data: Object.keys(downloadJson).map(function (key) {
+            return {
+                name: key.replace('.js', ''),
+                value: downloadJson[key]
+            };
+        })
+    }, {
+        type: 'pie',
+        radius: [0, '30%'],
+        center: ['75%', '75%'],
+        data: Object.keys(themeJson).map(function (key) {
+            return {
+                name: key.replace('.js', ''),
+                value: themeJson[key]
+            };
+        })
+    }]
+};
+
+export []
\ No newline at end of file
diff --git a/public/examples/ts/wind-barb.ts b/public/examples/ts/wind-barb.ts
new file mode 100644
index 0000000..2ec7deb
--- /dev/null
+++ b/public/examples/ts/wind-barb.ts
@@ -0,0 +1,269 @@
+/*
+title: Wind Barb
+category: 'custom, dataZoom'
+titleCN: 风向图
+difficulty: 5
+*/
+
+
+$.getJSON(ROOT_PATH + '/data/asset/data/wind-barb-hobart.json', function (rawData) {
+
+    const weatherIcons: Record<string, string> = {
+        'Showers': ROOT_PATH + '/data/asset/img/weather/showers_128.png',
+        'Sunny': ROOT_PATH + '/data/asset/img/weather/sunny_128.png',
+        'Cloudy': ROOT_PATH + '/data/asset/img/weather/cloudy_128.png'
+    };
+
+    const directionMap: Record<string, number> = {};
+    ['W', 'WSW', 'SW', 'SSW', 'S', 'SSE', 'SE', 'ESE', 'E', 'ENE', 'NE', 'NNE', 'N', 'NNW', 'NW', 'WNW'].forEach(
+        function (name, index) {
+            directionMap[name] = Math.PI / 8 * index;
+        }
+    );
+
+    const data = rawData.data.map(function (entry: any) {
+        return [entry.time, entry.windSpeed, entry.R, entry.waveHeight];
+    });
+    const weatherData = rawData.forecast.map(function (entry: any) {
+        return [entry.localDate, 0, weatherIcons[entry.skyIcon], entry.minTemp, entry.maxTemp];
+    });
+
+    const dims = {
+        time: 0,
+        windSpeed: 1,
+        R: 2,
+        waveHeight: 3,
+        weatherIcon: 2,
+        minTemp: 3,
+        maxTemp: 4
+    };
+    const arrowSize = 18;
+    const weatherIconSize = 45;
+
+    const renderArrow: echarts.CustomSeriesOption['renderItem'] = function (param, api) {
+        const point = api.coord([
+            api.value(dims.time),
+            api.value(dims.windSpeed)
+        ]);
+
+        return {
+            type: 'path',
+            shape: {
+                pathData: 'M31 16l-15-15v9h-26v12h26v9z',
+                x: -arrowSize / 2,
+                y: -arrowSize / 2,
+                width: arrowSize,
+                height: arrowSize
+            },
+            rotation: directionMap[api.value(dims.R)],
+            position: point,
+            style: api.style({
+                stroke: '#555',
+                lineWidth: 1
+            })
+        };
+    }
+
+    const renderWeather: echarts.CustomSeriesOption['renderItem'] = function (param, api) {
+        const point = api.coord([
+            api.value(dims.time) as number + 3600 * 24 * 1000 / 2,
+            0
+        ]);
+
+        return {
+            type: 'group',
+            children: [{
+                type: 'image',
+                style: {
+                    image: api.value(dims.weatherIcon),
+                    x: -weatherIconSize / 2,
+                    y: -weatherIconSize / 2,
+                    width: weatherIconSize,
+                    height: weatherIconSize
+                },
+                position: [point[0], 110]
+            }, {
+                type: 'text',
+                style: {
+                    text: api.value(dims.minTemp) + ' - ' + api.value(dims.maxTemp) + '°',
+                    textFont: api.font({fontSize: 14}),
+                    textAlign: 'center',
+                    textVerticalAlign: 'bottom'
+                },
+                position: [point[0], 80]
+            }]
+        };
+    }
+
+    option = {
+        title: {
+            text: '天气 风向 风速 海浪 预报',
+            subtext: '示例数据源于 www.seabreeze.com.au',
+            left: 'center'
+        },
+        tooltip: {
+            trigger: 'axis',
+            formatter: function (params: any) {
+                return [
+                    echarts.format.formatTime('yyyy-MM-dd', params[0].value[dims.time])
+                    + ' ' + echarts.format.formatTime('hh:mm', params[0].value[dims.time]),
+                    '风速:' + params[0].value[dims.windSpeed],
+                    '风向:' + params[0].value[dims.R],
+                    '浪高:' + params[0].value[dims.waveHeight]
+                ].join('<br>');
+            }
+        },
+        grid: {
+            top: 160,
+            bottom: 125
+        },
+        xAxis: {
+            type: 'time',
+            maxInterval: 3600 * 1000 * 24,
+            splitLine: {
+                lineStyle: {
+                    color: '#ddd'
+                }
+            }
+        },
+        yAxis: [{
+            name: '风速(节)',
+            nameLocation: 'middle',
+            nameGap: 35,
+            axisLine: {
+                lineStyle: {
+                    color: '#666'
+                }
+            },
+            splitLine: {
+                lineStyle: {
+                    color: '#ddd'
+                }
+            }
+        }, {
+            name: '浪高(米)',
+            nameLocation: 'middle',
+            nameGap: 35,
+            max: 6,
+            axisLine: {
+                lineStyle: {
+                    color: '#015DD5'
+                }
+            },
+            splitLine: {show: false}
+        }, {
+            axisLine: {show: false},
+            axisTick: {show: false},
+            axisLabel: {show: false},
+            splitLine: {show: false}
+        }],
+        visualMap: {
+            type: 'piecewise',
+            // show: false,
+            orient: 'horizontal',
+            left: 'center',
+            bottom: 10,
+            pieces: [{
+                gte: 17,
+                color: '#18BF12',
+                label: '大风(>=17节)'
+            }, {
+                gte: 11,
+                lt: 17,
+                color: '#f4e9a3',
+                label: '中风(11  ~ 17 节)'
+            }, {
+                lt: 11,
+                color: '#D33C3E',
+                label: '微风(小于 11 节)'
+            }],
+            seriesIndex: 1,
+            dimension: 1
+        },
+        dataZoom: [{
+            type: 'inside',
+            xAxisIndex: 0,
+            minSpan: 5
+        }, {
+            type: 'slider',
+            xAxisIndex: 0,
+            minSpan: 5,
+            bottom: 50
+        }],
+        series: [{
+            type: 'line',
+            yAxisIndex: 1,
+            showSymbol: false,
+            emphasis: {
+                scale: false
+            },
+            symbolSize: 10,
+            areaStyle: {
+                color: {
+                    type: 'linear',
+                    x: 0,
+                    y: 0,
+                    x2: 0,
+                    y2: 1,
+                    global: false,
+                    colorStops: [{
+                        offset: 0, color: 'rgba(88,160,253,1)'
+                    }, {
+                        offset: 0.5, color: 'rgba(88,160,253,0.7)'
+                    }, {
+                        offset: 1, color: 'rgba(88,160,253,0)'
+                    }]
+                }
+            },
+            lineStyle: {
+                color: 'rgba(88,160,253,1)'
+            },
+            itemStyle: {
+                color: 'rgba(88,160,253,1)'
+            },
+            encode: {
+                x: dims.time,
+                y: dims.waveHeight
+            },
+            data: data,
+            z: 2
+        }, {
+            type: 'custom',
+            renderItem: renderArrow,
+            encode: {
+                x: dims.time,
+                y: dims.windSpeed
+            },
+            data: data,
+            z: 10
+        }, {
+            type: 'line',
+            symbol: 'none',
+            encode: {
+                x: dims.time,
+                y: dims.windSpeed
+            },
+            lineStyle: {
+                color: '#aaa',
+                type: 'dotted'
+            },
+            data: data,
+            z: 1
+        }, {
+            type: 'custom',
+            renderItem: renderWeather,
+            data: weatherData,
+            tooltip: {
+                trigger: 'item',
+                formatter: function (param: any) {
+                    return param.value[dims.time] + ': '
+                        + param.value[dims.minTemp] + ' - ' + param.value[dims.maxTemp] + '°';
+                }
+            },
+            yAxisIndex: 2,
+            z: 11
+        }]
+    };
+
+    myChart.setOption(option);
+});
diff --git a/public/examples/types/example.d.ts b/public/examples/types/example.d.ts
index 8f68932..c0239dd 100644
--- a/public/examples/types/example.d.ts
+++ b/public/examples/types/example.d.ts
@@ -6,7 +6,7 @@ declare global {
     const app: {
         configParameters: {
             [key: string]: {
-                options: Record<string, string>
+                options: Record<string, string> | string[]
             } | {
                 min?: number
                 max?: number
diff --git a/src/editor/CodeMonaco.vue b/src/editor/CodeMonaco.vue
index f2f62c7..128c900 100644
--- a/src/editor/CodeMonaco.vue
+++ b/src/editor/CodeMonaco.vue
@@ -55,7 +55,7 @@ declare global {
     const app: {
         configParameters: {
             [key: string]: {
-                options: Record<string, string>
+                options: Record<string, string> | string[]
             } | {
                 min?: number
                 max?: number

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